This commit was manufactured by cvs2svn to create branch 'uc'.
[gnokii.git] / xgnokii / xgnokii_lowlevel.c
1 /*
2
3   X G N O K I I
4
5   A Linux/Unix GUI for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8
9 */
10
11 #include <unistd.h>
12 #include <pthread.h>
13 #include <string.h>
14 #include <glib.h>
15 #include "gsm-api.h"
16 #include "xgnokii_lowlevel.h"
17 #include "xgnokii.h"
18 #include "xgnokii_common.h"
19
20 pthread_t monitor_th;
21 PhoneMonitor phoneMonitor;
22 pthread_mutex_t memoryMutex;
23 pthread_cond_t  memoryCond;
24 pthread_mutex_t calendarMutex;
25 pthread_cond_t  calendarCond;
26 pthread_mutex_t smsMutex;
27 pthread_mutex_t sendSMSMutex;
28 pthread_cond_t  sendSMSCond;
29 pthread_mutex_t callMutex;
30 pthread_mutex_t netMonMutex;
31 pthread_mutex_t speedDialMutex;
32 pthread_cond_t  speedDialCond;
33 pthread_mutex_t callerGroupMutex;
34 pthread_cond_t  callerGroupCond;
35 pthread_mutex_t smsCenterMutex;  
36 pthread_cond_t  smsCenterCond;
37 pthread_mutex_t alarmMutex;  
38 pthread_cond_t  alarmCond;
39 pthread_mutex_t getBitmapMutex;
40 pthread_cond_t  getBitmapCond;
41 pthread_mutex_t setBitmapMutex;
42 pthread_cond_t  setBitmapCond;
43 pthread_mutex_t getNetworkInfoMutex;
44 pthread_cond_t  getNetworkInfoCond;
45 static pthread_mutex_t eventsMutex;
46 static GSList *ScheduledEvents = NULL;
47
48
49 inline void GUI_InsertEvent (PhoneEvent *event)
50 {
51   while (phoneMonitor.working) {
52     usleep(1);
53   }
54
55 # ifdef XDEBUG
56   g_print ("Inserting Event: %d\n", event->event);
57 # endif
58   pthread_mutex_lock (&eventsMutex);
59   ScheduledEvents = g_slist_prepend (ScheduledEvents, event);
60   pthread_mutex_unlock (&eventsMutex);
61 }
62
63
64 inline static PhoneEvent *RemoveEvent (void)
65 {
66   GSList *list;
67   PhoneEvent *event = NULL;
68
69   pthread_mutex_lock (&eventsMutex);
70   list = g_slist_last (ScheduledEvents);
71   if (list)
72   {
73     event = (PhoneEvent *) list->data;
74     ScheduledEvents = g_slist_remove_link (ScheduledEvents, list);
75     g_slist_free_1 (list);
76   }
77   pthread_mutex_unlock (&eventsMutex);
78
79   return (event);
80 }
81
82
83 static void InitModelInf (void)
84 {
85   gchar buf[64];
86   GSM_Error error;
87   register gint i = 0;
88
89   while ((error = GSM->GetModel(buf)) != GE_NONE && i++ < 15)
90     sleep(1);
91
92   if (error == GE_NONE)
93   {
94     g_free (phoneMonitor.phone.model);
95     phoneMonitor.phone.version = g_strdup (buf);
96     phoneMonitor.phone.model = GetModelName (buf);
97     if (phoneMonitor.phone.model == NULL)
98       phoneMonitor.phone.model = g_strdup (_("unknown"));
99   }
100
101   i = 0;
102   while ((error = GSM->GetRevision (buf)) != GE_NONE && i++ < 5)
103     sleep(1);
104
105   if (error == GE_NONE)
106   {
107     g_free (phoneMonitor.phone.revision);
108     phoneMonitor.phone.revision = g_strdup (buf);
109   }
110
111   i = 0;
112   while ((error = GSM->GetIMEI (buf)) != GE_NONE && i++ < 5)
113     sleep(1);
114
115   if (error == GE_NONE)
116   {
117     g_free (phoneMonitor.phone.imei);
118     phoneMonitor.phone.imei = g_strdup (buf);
119   }
120
121
122 #ifdef XDEBUG
123   g_print ("Version: %s\n", phoneMonitor.phone.version);
124   g_print ("Model: %s\n", phoneMonitor.phone.model);
125   g_print ("IMEI: %s\n", phoneMonitor.phone.imei);
126   g_print ("Revision: %s\n", phoneMonitor.phone.revision);
127 #endif
128 }
129
130 static GSM_Error fbusinit(bool enable_monitoring)
131 {
132   int count=0;
133   static GSM_Error error=GE_NOLINK;
134
135 #ifndef WIN32
136   if (strcmp(GetMygnokiiVersion(),VERSION)!=0)
137     fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of xgnokii (%s)\n"),GetMygnokiiVersion(),VERSION);
138 #endif
139
140   /* Initialise the code for the GSM interface. */     
141   if (error == GE_NOLINK)
142     error = GSM_Initialise (xgnokiiConfig.model, xgnokiiConfig.port,
143                             xgnokiiConfig.initlength,
144                             GetConnectionTypeFromString(xgnokiiConfig.connection),
145                             RLP_DisplayF96Frame,
146                             xgnokiiConfig.synchronizetime);
147
148 #ifdef XDEBUG
149   g_print ("fbusinit: error %d\n", error);
150 #endif
151
152   if (error != GE_NONE) {
153     g_print (_("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
154     /* FIXME: should popup some message... */
155     return (error);
156   }
157
158   while (count++ < 40 && *GSM_LinkOK == false)
159     usleep(50000);
160 #ifdef XDEBUG
161   g_print("After usleep. GSM_LinkOK: %d\n", *GSM_LinkOK);
162 #endif
163
164   if (*GSM_LinkOK == true)
165     InitModelInf ();
166
167   return *GSM_LinkOK;
168 }
169
170
171 void GUI_InitPhoneMonitor (void)
172 {
173   phoneMonitor.phone.model = g_strdup (_("unknown"));
174   phoneMonitor.phone.version = phoneMonitor.phone.model;
175   phoneMonitor.phone.revision = g_strdup (_("unknown"));
176   phoneMonitor.phone.imei = g_strdup (_("unknown"));
177   phoneMonitor.rfLevel = phoneMonitor.batteryLevel = -1;
178   phoneMonitor.powerSource = GPS_BATTERY;
179   phoneMonitor.working = FALSE;
180   phoneMonitor.alarm = FALSE;
181   phoneMonitor.sms.unRead = phoneMonitor.sms.number = phoneMonitor.sms.number2 = 0;
182   phoneMonitor.sms.messages = NULL;
183   phoneMonitor.call.callInProgress = CS_Idle;
184   *phoneMonitor.call.callNum = '\0';
185   phoneMonitor.netmonitor.number = 0;
186   *phoneMonitor.netmonitor.screen = *phoneMonitor.netmonitor.screen3 = 
187   *phoneMonitor.netmonitor.screen4 = *phoneMonitor.netmonitor.screen5 = '\0';
188   pthread_mutex_init (&memoryMutex, NULL);
189   pthread_cond_init (&memoryCond, NULL);
190   pthread_mutex_init (&calendarMutex, NULL);
191   pthread_cond_init (&calendarCond, NULL);
192   pthread_mutex_init (&smsMutex, NULL);
193   pthread_mutex_init (&sendSMSMutex, NULL);
194   pthread_cond_init (&sendSMSCond, NULL);
195   pthread_mutex_init (&callMutex, NULL);
196   pthread_mutex_init (&eventsMutex, NULL);
197   pthread_mutex_init (&callMutex, NULL);
198   pthread_mutex_init (&netMonMutex, NULL);
199   pthread_mutex_init (&speedDialMutex, NULL);
200   pthread_cond_init (&speedDialCond, NULL);
201   pthread_mutex_init (&callerGroupMutex, NULL);
202   pthread_cond_init (&callerGroupCond, NULL);
203   pthread_mutex_init (&smsCenterMutex, NULL);
204   pthread_cond_init (&smsCenterCond, NULL);
205   pthread_mutex_init (&getBitmapMutex, NULL);
206   pthread_cond_init (&getBitmapCond, NULL);
207   pthread_mutex_init (&setBitmapMutex, NULL);
208   pthread_cond_init (&setBitmapCond, NULL);
209   pthread_mutex_init (&getNetworkInfoMutex, NULL);
210   pthread_cond_init (&getNetworkInfoCond, NULL);
211 }
212
213
214 static inline void FreeElement (gpointer data, gpointer userData)
215 {
216   g_free ((GSM_SMSMessage *) data);
217 }
218
219
220 static inline void FreeArray (GSList **array)
221 {
222   if (*array)
223   {
224     g_slist_foreach (*array, FreeElement, NULL);
225     g_slist_free (*array);
226     *array = NULL;
227   }
228 }
229
230
231 void RefreshSMS (const gint number)
232 {
233   GSM_Error error;
234   GSM_SMSMessage *msg;
235   register gint i;
236
237 # ifdef XDEBUG
238   g_print ("RefreshSMS is running...\n");
239 # endif
240
241   pthread_mutex_lock (&smsMutex);
242   FreeArray (&(phoneMonitor.sms.messages));
243   phoneMonitor.sms.number = 0;
244   phoneMonitor.sms.number2 = 0;
245   pthread_mutex_unlock (&smsMutex);
246
247   i = 1;
248   while (1)
249   {
250     msg = g_malloc (sizeof (GSM_SMSMessage));
251     msg->MemoryType = GMT_SM;
252     msg->Location = i;
253 #ifdef XDEBUG
254     fprintf(stdout, _("test: %d %i %i %i\n"),msg->Location,phoneMonitor.sms.number,phoneMonitor.sms.number2,number);
255 #endif
256     pthread_mutex_lock (&smsMutex);
257     if( GetModelFeature(FN_SMS)==F_SMS71 ) msg->Location = 0;  /* read next sms for 6210/7110 */
258     error = GSM->GetSMSMessage (msg);
259     pthread_mutex_unlock (&smsMutex);
260     switch (error) {
261       case GE_NONE:
262         pthread_mutex_lock (&smsMutex);
263 #ifdef XDEBUG
264     fprintf(stdout, _("Refresh SMS: g_slist_append: sms message"));
265     fprintf(stdout, _(" Location: %d"),msg->Location);
266     fprintf(stdout, _(" folder: %d"),msg->folder);
267     if ( msg-> SMSData) fprintf(stdout, _(" SMSData true\n"));
268         else  fprintf(stdout, _(" SMSData false\n"));
269 #endif
270         /* RTH:  unread sms from folder 0 to INBOX */
271         phoneMonitor.sms.messages = g_slist_append (phoneMonitor.sms.messages, msg);
272         phoneMonitor.sms.number++;
273         phoneMonitor.sms.number2++;
274         pthread_mutex_unlock (&smsMutex);
275         if (phoneMonitor.sms.number2 == number) return;
276         break;
277       case GE_SMSTOOLONG: /* Picture Image in 7110 comp phone */
278         g_free (msg);
279         phoneMonitor.sms.number2++;
280         if (phoneMonitor.sms.number2 == number) return;
281         break;
282       default:
283         g_free (msg);
284         break;
285     }
286     i++;
287   }
288 }
289
290
291 static gint A_GetMemoryStatus (gpointer data)
292 {
293   GSM_Error error;
294   D_MemoryStatus *ms = (D_MemoryStatus *) data;
295
296   error = ms->status = GE_UNKNOWN;
297
298   if (ms)
299   {
300     pthread_mutex_lock (&memoryMutex);
301     error = ms->status = GSM->GetMemoryStatus (&(ms->memoryStatus));
302     pthread_cond_signal (&memoryCond);
303     pthread_mutex_unlock (&memoryMutex);
304   }
305
306   return (error);
307 }
308
309
310 static gint A_GetMemoryLocation (gpointer data)
311 {
312   GSM_Error error;
313   D_MemoryLocation *ml = (D_MemoryLocation *) data;
314
315   error = ml->status = GE_UNKNOWN;
316
317   if (ml)
318   {
319     pthread_mutex_lock (&memoryMutex);
320     error = ml->status = GSM->GetMemoryLocation (ml->entry);
321     pthread_cond_signal (&memoryCond);
322     pthread_mutex_unlock (&memoryMutex);
323   }
324
325   return (error);
326 }
327
328
329 static gint A_GetMemoryLocationAll (gpointer data)
330 {
331   GSM_PhonebookEntry entry;
332   GSM_Error error;
333   D_MemoryLocationAll *mla = (D_MemoryLocationAll *) data;
334   register gint i;
335   gint readed=0;
336
337   error = mla->status = GE_NONE;
338   entry.MemoryType = mla->type;
339
340   pthread_mutex_lock (&memoryMutex);
341   for (i = mla->min; i <= mla->max; i++)
342   {
343     entry.Location = i;
344     if (readed<mla->used) {
345       error = GSM->GetMemoryLocation (&entry);
346       if (error != GE_NONE)
347       {
348         gint err_count = 0;
349
350         while (error != GE_NONE &&
351                error != GE_INVALIDPHBOOKLOCATION && error != GE_UNKNOWN) //n7110.c
352         {
353           g_print (_("%s: line %d: Can't get memory entry number %d from memory %d! %d\n"),
354                    __FILE__, __LINE__, i, entry.MemoryType, error);
355           if (err_count++ > 3)
356           {
357             mla->ReadFailed (i);
358             mla->status = error;
359             pthread_cond_signal (&memoryCond);
360             pthread_mutex_unlock (&memoryMutex);
361             return (error);
362           }
363
364           error = GSM->GetMemoryLocation (&entry);
365           sleep (2);
366         }
367       }
368       
369       if (strcmp(entry.Number, "\0") || strcmp(entry.Name, "\0"))
370         readed++;
371
372     } else {
373       entry.Number[0]='\0';
374       entry.Name[0]='\0';
375     }
376
377     error = mla->InsertEntry (&entry);
378     if (error != GE_NONE)
379       break;
380   }
381   mla->status = error;
382   pthread_cond_signal (&memoryCond);
383   pthread_mutex_unlock (&memoryMutex);
384   return (error);
385 }
386
387
388 static gint A_WriteMemoryLocation (gpointer data)
389 {
390   GSM_Error error;
391   D_MemoryLocation *ml = (D_MemoryLocation *) data;
392
393   error = ml->status = GE_UNKNOWN;
394
395   if (ml)
396   {
397     pthread_mutex_lock (&memoryMutex);
398     error = ml->status = GSM->WritePhonebookLocation (ml->entry);
399     pthread_cond_signal (&memoryCond);
400     pthread_mutex_unlock (&memoryMutex);
401   }
402
403   return (error);
404 }
405
406
407 static gint A_WriteMemoryLocationAll (gpointer data)
408 {
409 /*  GSM_PhonebookEntry entry; */
410   GSM_Error error;
411   D_MemoryLocationAll *mla = (D_MemoryLocationAll *) data;
412 /*  register gint i;
413 */
414   error = mla->status = GE_NONE;
415 /*  entry.MemoryType = mla->type;
416
417   pthread_mutex_lock (&memoryMutex);
418   for (i = mla->min; i <= mla->max; i++)
419   {
420     entry.Location = i;
421     error = GSM->GetMemoryLocation (&entry);
422     if (error != GE_NONE)
423     {
424       gint err_count = 0;
425
426       while (error != GE_NONE)
427       {
428         g_print (_("%s: line %d: Can't get memory entry number %d from memory %d! %d\n"),
429                  __FILE__, __LINE__, i, entry.MemoryType, error);
430         if (err_count++ > 3)
431         {
432           mla->ReadFailed (i);
433           mla->status = error;
434           pthread_cond_signal (&memoryCond);
435           pthread_mutex_unlock (&memoryMutex);
436           return (error);
437         }
438
439         error = GSM->GetMemoryLocation (&entry);
440         sleep (2);
441       }
442     }
443     error = mla->InsertEntry (&entry);
444     if (error != GE_NONE)
445       break;
446   }
447   mla->status = error;
448   pthread_cond_signal (&memoryCond);
449   pthread_mutex_unlock (&memoryMutex); */
450   return (error);
451 }
452
453
454 static gint A_GetCalendarNote (gpointer data)
455 {
456   GSM_Error error;
457   D_CalendarNote *cn = (D_CalendarNote *) data;
458
459   error = cn->status = GE_UNKNOWN;
460
461   if (cn)
462   {
463     pthread_mutex_lock (&calendarMutex);
464     error = cn->status = GSM->GetCalendarNote (cn->entry);
465     pthread_cond_signal (&calendarCond);
466     pthread_mutex_unlock (&calendarMutex);
467   }
468
469   return (error);
470 }
471
472
473 static gint A_GetCalendarNoteAll (gpointer data)
474 {
475   GSM_CalendarNote entry;
476   D_CalendarNoteAll *cna = (D_CalendarNoteAll *) data;
477   GSM_Error e;
478   register gint i = 1;
479
480   pthread_mutex_lock (&calendarMutex);
481   while (1)
482   {
483     entry.Location = i++;
484
485     if ((e = GSM->GetCalendarNote (&entry)) != GE_NONE)
486       break;
487
488     if (cna->InsertEntry (&entry) != GE_NONE)
489       break;
490   }
491
492   pthread_mutex_unlock (&calendarMutex);
493   g_free (cna);
494   if (e == GE_INVALIDCALNOTELOCATION)
495     return (GE_NONE);
496   else
497     return (e);
498 }
499
500 static gint A_WriteCalendarNote (gpointer data)
501 {
502   GSM_Error error;
503   D_CalendarNote *cn = (D_CalendarNote *) data;
504
505   error = cn->status = GE_UNKNOWN;
506
507   if (cn)
508   {
509     pthread_mutex_lock (&calendarMutex);
510     error = cn->status = GSM->WriteCalendarNote (cn->entry);
511     pthread_cond_signal (&calendarCond);
512     pthread_mutex_unlock (&calendarMutex);
513   }
514
515   return (error);
516 }
517
518
519 static gint A_DeleteCalendarNote (gpointer data)
520 {
521   GSM_CalendarNote *note = (GSM_CalendarNote *) data;
522   GSM_Error error = GE_UNKNOWN;
523
524   if (note)
525   {
526     error = GSM->DeleteCalendarNote (note);
527     g_free (note);
528   }
529
530   return (error);
531 }
532
533 static gint A_GetCallerGroup (gpointer data)
534 {
535   GSM_Bitmap bitmap;
536   GSM_Error error;
537   D_CallerGroup *cg = (D_CallerGroup *) data;
538
539   error = cg->status = GE_UNKNOWN;
540
541   if (cg)
542   {
543     bitmap.type = GSM_CallerLogo;
544     bitmap.number = cg->number;
545
546     pthread_mutex_lock (&callerGroupMutex);
547     error = cg->status = GSM->GetBitmap (&bitmap);
548     strncpy (cg->text, bitmap.text, 256);
549     cg->text[255] = '\0';
550     pthread_cond_signal (&callerGroupCond);
551     pthread_mutex_unlock (&callerGroupMutex);
552   }
553
554   return (error);
555 }
556
557
558 static gint A_SendCallerGroup (gpointer data)
559 {
560   GSM_Bitmap bitmap;
561   D_CallerGroup *cg = (D_CallerGroup *) data;
562   GSM_Error error;
563
564   if (!cg)
565     return (GE_UNKNOWN);
566
567   bitmap.type = GSM_CallerLogo;
568   bitmap.number = cg->number;
569   if ((error = GSM->GetBitmap (&bitmap)) != GE_NONE)
570   {
571     g_free (cg);
572     return (error);
573   }
574   strncpy (bitmap.text, cg->text, 256);
575   bitmap.text[255] = '\0';
576   g_free (cg);
577   return (GSM->SetBitmap (&bitmap));
578 }
579
580
581 static gint A_GetSMSCenter (gpointer data)
582 {
583   D_SMSCenter *c = (D_SMSCenter *) data;
584   GSM_Error error;
585
586   error = c->status = GE_UNKNOWN;
587   if (c)
588   {
589     pthread_mutex_lock (&smsCenterMutex);
590     error = c->status = GSM->GetSMSCenter (c->center);
591     pthread_cond_signal (&smsCenterCond);
592     pthread_mutex_unlock (&smsCenterMutex);
593   }
594
595   return (error);
596 }
597
598
599 static gint A_SetSMSCenter (gpointer data)
600 {
601   D_SMSCenter *c = (D_SMSCenter *) data;
602   GSM_Error error;
603
604   error = c->status = GE_UNKNOWN;
605   if (c)
606   {
607     //pthread_mutex_lock (&smsCenterMutex);
608     error = c->status = GSM->SetSMSCenter (c->center);
609     g_free (c);
610     //pthread_cond_signal (&smsCenterCond);
611     //pthread_mutex_unlock (&smsCenterMutex);
612   }
613
614   return (error);
615 }
616
617
618 static gint A_SendSMSMessage (gpointer data)
619 {
620   D_SMSMessage *d = (D_SMSMessage *) data;
621   GSM_Error error;
622
623   error = d->status = GE_UNKNOWN;
624   if (d)
625   {
626     pthread_mutex_lock (&sendSMSMutex);
627     error = d->status = GSM->SendSMSMessage (d->sms);
628     pthread_cond_signal (&sendSMSCond);
629     pthread_mutex_unlock (&sendSMSMutex);
630   }
631
632   if (d->status == GE_SMSSENDOK)
633     return (GE_NONE);
634   else
635     return (error);
636 }
637
638
639 static gint A_DeleteSMSMessage (gpointer data)
640 {
641   GSM_SMSMessage *sms = (GSM_SMSMessage *) data;
642   GSM_Error error = GE_UNKNOWN;
643
644   if (sms)
645   {
646     error = GSM->DeleteSMSMessage(sms);
647     g_free (sms);
648   }
649
650   return (error);
651 }
652
653
654 static gint A_GetSpeedDial (gpointer data)
655 {
656   D_SpeedDial *d = (D_SpeedDial *) data;
657   GSM_Error error;
658
659   error = d->status = GE_UNKNOWN;
660
661   if (d)
662   {
663     pthread_mutex_lock (&speedDialMutex);
664     error = d->status = GSM->GetSpeedDial (&(d->entry));
665     pthread_cond_signal (&speedDialCond);
666     pthread_mutex_unlock (&speedDialMutex);
667   }
668
669   return (error);
670 }
671
672
673 static gint A_SendSpeedDial (gpointer data)
674 {
675   D_SpeedDial *d = (D_SpeedDial *) data;
676   GSM_Error error;
677
678   error = d->status = GE_UNKNOWN;
679
680   if (d)
681   {
682     //pthread_mutex_lock (&speedDialMutex);
683     error = d->status = GSM->SetSpeedDial (&(d->entry));
684     g_free (d);
685     //pthread_cond_signal (&speedDialCond);
686     //pthread_mutex_unlock (&speedDialMutex);
687   }
688
689   return (error);
690 }
691
692
693 static gint A_SendDTMF (gpointer data)
694 {
695   gchar *buf = (gchar *) data;
696   GSM_Error error = GE_UNKNOWN;
697
698   if (buf) 
699   {
700     error = GSM->SendDTMF (buf);
701     g_free (buf);
702   }
703
704   return (error);
705 }
706
707
708 static gint A_NetMonOnOff (gpointer data)
709 {
710   gchar screen[50];
711   gint mode = GPOINTER_TO_INT (data);
712   GSM_Error error = GE_UNKNOWN;
713
714   if (mode)
715     error = GSM->NetMonitor (0xf3, screen);
716   else
717     error = GSM->NetMonitor (0xf1, screen);
718
719   return (error);
720 }
721
722
723 static gint A_NetMonitor (gpointer data)
724 {
725   gint number = GPOINTER_TO_INT (data);
726
727   if (data == 0)
728     phoneMonitor.netmonitor.number = 0;
729   else
730     phoneMonitor.netmonitor.number = number;
731     
732   return (0);
733 }
734
735
736 static gint A_DialVoice (gpointer data)
737 {
738   gchar *number = (gchar *) data;
739   GSM_Error error = GE_UNKNOWN;
740
741   if (number)
742   {
743     error = GSM->DialVoice (number);
744     g_free (number);
745   }
746
747   return (error);
748 }
749
750
751 static gint A_GetAlarm (gpointer data)
752 {
753   D_Alarm *a = (D_Alarm *) data;
754   GSM_Error error;
755
756   error = a->status = GE_UNKNOWN;
757
758   if (a)
759   {
760     pthread_mutex_lock (&alarmMutex);
761     error = a->status = GSM->GetAlarm (0, &(a->time));
762     pthread_cond_signal (&alarmCond);
763     pthread_mutex_unlock (&alarmMutex);
764   }
765
766   return (error);
767 }
768
769
770 static gint A_SetAlarm (gpointer data)
771 {
772   D_Alarm *a = (D_Alarm *) data;
773   GSM_Error error;
774
775   error = a->status = GE_UNKNOWN;
776
777   if (a)
778   {
779     error = a->status = GSM->SetAlarm (0, &(a->time));
780     g_free (a);
781   }
782
783   return (error);
784 }
785
786
787 static gint A_SendKeyStroke (gpointer data)
788 {
789   gchar *buf = (gchar *) data;
790
791   if (buf) 
792   {
793     GSM->PressKey(buf[1], buf[0]);
794     g_free (buf);
795   }
796
797   return (0);
798 }
799
800 static gint A_GetBitmap(gpointer data) {
801   GSM_Error error;
802   D_Bitmap *d = (D_Bitmap *)data;
803
804   pthread_mutex_lock(&getBitmapMutex);
805   error = d->status = GSM->GetBitmap(d->bitmap);
806   pthread_cond_signal(&getBitmapCond);
807   pthread_mutex_unlock(&getBitmapMutex);
808   return error;
809 }
810
811 static gint A_SetBitmap(gpointer data) {
812   GSM_Error error;
813   D_Bitmap *d = (D_Bitmap *)data;
814   GSM_Bitmap bitmap;
815   
816   pthread_mutex_lock(&setBitmapMutex);
817   if (d->bitmap->type == GSM_CallerLogo) {
818     bitmap.type = d->bitmap->type;
819     bitmap.number = d->bitmap->number;
820     error = d->status = GSM->GetBitmap(&bitmap);
821     if (error == GE_NONE) {
822       strncpy(d->bitmap->text,bitmap.text,sizeof(bitmap.text));
823       d->bitmap->ringtone = bitmap.ringtone;
824       error = d->status = GSM->SetBitmap(d->bitmap);
825     }
826   } else {
827     error = d->status = GSM->SetBitmap(d->bitmap);
828   }
829   pthread_cond_signal(&setBitmapCond);
830   pthread_mutex_unlock(&setBitmapMutex);
831   return error;
832 }
833
834 static gint A_GetNetworkInfo(gpointer data) {
835   GSM_Error error;
836   D_NetworkInfo *d = (D_NetworkInfo *)data;
837
838   pthread_mutex_lock(&getNetworkInfoMutex);
839   error = d->status = GSM->GetNetworkInfo(d->info);
840   pthread_cond_signal(&getNetworkInfoCond);
841   pthread_mutex_unlock(&getNetworkInfoMutex);
842   return error;
843 }
844
845 static gint A_Exit (gpointer data)
846 {
847   pthread_exit (0);
848   return (0); /* just to be proper */
849 }
850
851
852 gint (*DoAction[])(gpointer) = {
853   A_GetMemoryStatus,
854   A_GetMemoryLocation,
855   A_GetMemoryLocationAll,
856   A_WriteMemoryLocation,
857   A_WriteMemoryLocationAll,
858   A_GetCalendarNote,
859   A_GetCalendarNoteAll,
860   A_WriteCalendarNote,
861   A_DeleteCalendarNote,
862   A_GetCallerGroup,
863   A_SendCallerGroup,
864   A_GetSMSCenter,
865   A_SetSMSCenter,
866   A_SendSMSMessage,
867   A_DeleteSMSMessage,
868   A_GetSpeedDial,
869   A_SendSpeedDial,
870   A_SendDTMF,
871   A_NetMonOnOff,
872   A_NetMonitor,
873   A_DialVoice,
874   A_GetAlarm,
875   A_SetAlarm,
876   A_SendKeyStroke,
877   A_GetBitmap,
878   A_SetBitmap,
879   A_GetNetworkInfo,
880   A_Exit
881 };
882
883 void *GUI_Connect (void *a)
884 {
885   /* Define required unit types for RF and Battery level meters. */
886   GSM_RFUnits rf_units = GRF_Arbitrary;
887   GSM_BatteryUnits batt_units = GBU_Arbitrary;
888
889   GSM_DateTime Alarm;
890   gchar number[INCALL_NUMBER_LENGTH];
891   PhoneEvent *event=NULL;
892   GSM_Error error;
893   gint status;
894
895
896 # ifdef XDEBUG
897   g_print ("Initializing connection...\n");
898 # endif
899
900   phoneMonitor.working = _("Connecting...");
901   while (!fbusinit (true))
902     sleep (1);
903
904 # ifdef XDEBUG
905   g_print ("Phone connected. Starting monitoring...\n");
906 # endif
907
908   while (1)
909   {
910     if (event != NULL) {
911       phoneMonitor.working = _("Working...");
912     } else {
913       phoneMonitor.working = NULL;
914
915       if (GSM->GetRFLevel (&rf_units, &phoneMonitor.rfLevel) != GE_NONE)
916         phoneMonitor.rfLevel = -1;
917
918       if (rf_units == GRF_Arbitrary)
919         phoneMonitor.rfLevel *= 25;
920
921       if (GSM->GetPowerSource (&phoneMonitor.powerSource) == GE_NONE 
922           && phoneMonitor.powerSource == GPS_ACDC)
923         phoneMonitor.batteryLevel = ((gint) phoneMonitor.batteryLevel + 25) % 125;
924       else
925       {
926         if (GSM->GetBatteryLevel (&batt_units, &phoneMonitor.batteryLevel) != GE_NONE)
927           phoneMonitor.batteryLevel = -1;
928         if (batt_units == GBU_Arbitrary)
929           phoneMonitor.batteryLevel *= 25;
930       }
931
932       if (GSM->GetAlarm (0, &Alarm) == GE_NONE && Alarm.IsSet != 0)
933         phoneMonitor.alarm = TRUE;
934       else
935         phoneMonitor.alarm = FALSE;
936
937       if (GSM->GetIncomingCallNr (number) == GE_NONE)
938       {
939 #   ifdef XDEBUG
940         g_print ("Call in progress: %s\n", phoneMonitor.call.callNum);
941 #   endif
942
943         if (GSM->GetDisplayStatus (&status)==GE_NONE) {
944           if (status & (1<<DS_Call_In_Progress))
945           {
946             pthread_mutex_lock (&callMutex);
947             phoneMonitor.call.callInProgress = CS_InProgress;
948             pthread_mutex_unlock (&callMutex);
949           }
950           else
951           {
952             pthread_mutex_lock (&callMutex);
953             phoneMonitor.call.callInProgress = CS_Waiting;
954             strncpy (phoneMonitor.call.callNum, number, INCALL_NUMBER_LENGTH);
955             pthread_mutex_unlock (&callMutex);
956           }
957         } else {
958           pthread_mutex_lock (&callMutex);
959           phoneMonitor.call.callInProgress = CS_Idle;
960           *phoneMonitor.call.callNum = '\0';
961           pthread_mutex_unlock (&callMutex);
962         }
963       }
964       else
965       {
966         pthread_mutex_lock (&callMutex);
967         phoneMonitor.call.callInProgress = CS_Idle;
968         *phoneMonitor.call.callNum = '\0';
969         pthread_mutex_unlock (&callMutex);
970       }
971
972       pthread_mutex_lock (&netMonMutex);
973       if (phoneMonitor.netmonitor.number)
974       {
975         GSM->NetMonitor (phoneMonitor.netmonitor.number,
976                          phoneMonitor.netmonitor.screen);
977         GSM->NetMonitor (3, phoneMonitor.netmonitor.screen3);
978         GSM->NetMonitor (4, phoneMonitor.netmonitor.screen4);
979         GSM->NetMonitor (5, phoneMonitor.netmonitor.screen5);
980       }
981       else
982       {
983         *phoneMonitor.netmonitor.screen = *phoneMonitor.netmonitor.screen3 = 
984         *phoneMonitor.netmonitor.screen4 = *phoneMonitor.netmonitor.screen5 = '\0';
985       }
986       pthread_mutex_unlock (&netMonMutex);
987     }
988     while ((event = RemoveEvent ()) != NULL)
989     {
990 #     ifdef XDEBUG      
991       g_print ("Processing Event: %d\n", event->event);
992 #     endif
993       phoneMonitor.working = _("Working...");
994       if (event->event <= Event_Exit)
995         if ((error = DoAction[event->event] (event->data)) != GE_NONE)
996           g_print (_("Event %d failed with return code %d!\n"), event->event, error);
997       g_free (event);
998     }
999   }
1000 }