This commit was generated by cvs2svn to compensate for changes in r158,
[gnokii.git] / xgnokii / xgnokii_lowlevel.c
index 78a9ba4..528a433 100644 (file)
@@ -1,21 +1,72 @@
 /*
 
+  $Id$
+  
   X G N O K I I
 
   A Linux/Unix GUI for Nokia mobile phones.
+  Copyright (C) 1999 Pavel Janík ml., Hugh Blemings
+  & Ján Derfiòák <ja@mail.upjs.sk>.
 
   Released under the terms of the GNU GPL, see file COPYING for more details.
 
+  $Log$
+  Revision 1.1.1.4  2002/04/03 00:08:33  short
+  Found in "gnokii-working" directory, some November-patches version
+
+  Revision 1.19  2001/09/14 13:09:26  pkot
+  Xgnokii calendar updates
+
+  Revision 1.18  2001/06/20 21:27:36  pkot
+  IrDA patch (Martin Jancar)
+
+  Revision 1.17  2001/06/10 11:40:06  machek
+  xgnokii converted to new structure w.r.t. SMS messages.
+
+  Revision 1.16  2001/05/24 20:47:31  chris
+  More updating of 7110 code and some of xgnokii_lowlevel changed over.
+
+  Revision 1.15  2001/03/23 08:24:57  ja
+  New preview for 6210 in xgnokii's logos module.
+
+  Revision 1.14  2001/03/21 23:36:09  chris
+  Added the statemachine
+  This will break gnokii --identify and --monitor except for 6210/7110
+
+  Revision 1.13  2001/03/05 10:42:03  ja
+  Pavel Machek's vcard and finegrained indicators patch.
+
+  Revision 1.12  2001/02/02 08:09:57  ja
+  New dialogs for 6210/7110 in xgnokii. Fixed the smsd for new capabilty code.
+
+  Revision 1.11  2001/01/29 15:22:20  machek
+  Use integer as bitfield instead of struct of int:1.
+
+  Be able to read phonebook saved in gnokii format from xgnokii.
+
+  Revision 1.10  2001/01/17 02:54:56  chris
+  More 7110 work.  Use with care! (eg it is not possible to delete phonebook entries)
+  I can now edit my phonebook in xgnokii but it is 'work in progress'.
+
+  Revision 1.9  2001/01/15 21:10:20  ja
+  Better status reporting in xgnokii, fixed phone capabilities detection in xgnokii.
+
+  
 */
 
 #include <unistd.h>
 #include <pthread.h>
 #include <string.h>
 #include <glib.h>
+#include "misc.h"
+#include "gsm-common.h"
 #include "gsm-api.h"
+#include "fbus-6110.h"
+#include "fbus-3810.h"
 #include "xgnokii_lowlevel.h"
 #include "xgnokii.h"
-#include "xgnokii_common.h"
+#include "gsm-statemachine.h"
+//#include "xgnokii_common.h"
 
 pthread_t monitor_th;
 PhoneMonitor phoneMonitor;
@@ -26,6 +77,8 @@ pthread_cond_t  calendarCond;
 pthread_mutex_t smsMutex;
 pthread_mutex_t sendSMSMutex;
 pthread_cond_t  sendSMSCond;
+pthread_mutex_t saveSMSMutex;
+pthread_cond_t  saveSMSCond;
 pthread_mutex_t callMutex;
 pthread_mutex_t netMonMutex;
 pthread_mutex_t speedDialMutex;
@@ -45,13 +98,13 @@ pthread_cond_t  getNetworkInfoCond;
 static pthread_mutex_t eventsMutex;
 static GSList *ScheduledEvents = NULL;
 
+/* This symbol must be export as it is (mis)used by xgnokii_logos.c
+ */
+GSM_Statemachine xgnokii_statemachine;
+
 
 inline void GUI_InsertEvent (PhoneEvent *event)
 {
-  while (phoneMonitor.working) {
-    usleep(1);
-  }
-
 # ifdef XDEBUG
   g_print ("Inserting Event: %d\n", event->event);
 # endif
@@ -85,21 +138,27 @@ static void InitModelInf (void)
   gchar buf[64];
   GSM_Error error;
   register gint i = 0;
+  GSM_Data data;
 
-  while ((error = GSM->GetModel(buf)) != GE_NONE && i++ < 15)
+  GSM_DataClear(&data);
+  data.Model=buf;
+  while ((error = SM_Functions(GOP_GetModel,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 15)
     sleep(1);
 
   if (error == GE_NONE)
   {
     g_free (phoneMonitor.phone.model);
     phoneMonitor.phone.version = g_strdup (buf);
-    phoneMonitor.phone.model = GetModelName (buf);
+    phoneMonitor.phone.model = GetModel (buf);
     if (phoneMonitor.phone.model == NULL)
       phoneMonitor.phone.model = g_strdup (_("unknown"));
+
+    phoneMonitor.supported = GetPhoneModel(buf)->flags;
   }
 
   i = 0;
-  while ((error = GSM->GetRevision (buf)) != GE_NONE && i++ < 5)
+  data.Revision=buf;
+  while ((error = SM_Functions(GOP_GetRevision,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 5)
     sleep(1);
 
   if (error == GE_NONE)
@@ -109,7 +168,8 @@ static void InitModelInf (void)
   }
 
   i = 0;
-  while ((error = GSM->GetIMEI (buf)) != GE_NONE && i++ < 5)
+  data.Imei=buf;
+  while ((error = SM_Functions(GOP_GetImei,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 5)
     sleep(1);
 
   if (error == GE_NONE)
@@ -127,23 +187,24 @@ static void InitModelInf (void)
 #endif
 }
 
+
 static GSM_Error fbusinit(bool enable_monitoring)
 {
   int count=0;
-  static GSM_Error error=GE_NOLINK;
+  GSM_Error error=GE_NOLINK;
+  GSM_ConnectionType connection=GCT_Serial;
 
-#ifndef WIN32
-  if (strcmp(GetMygnokiiVersion(),VERSION)!=0)
-    fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of xgnokii (%s)\n"),GetMygnokiiVersion(),VERSION);
-#endif
+  if (!strcmp(xgnokiiConfig.connection, "infrared"))
+    connection = GCT_Infrared;
+
+  if (!strcmp(xgnokiiConfig.connection, "irda"))
+    connection = GCT_Irda;
 
   /* Initialise the code for the GSM interface. */     
+
   if (error == GE_NOLINK)
     error = GSM_Initialise (xgnokiiConfig.model, xgnokiiConfig.port,
-                            xgnokiiConfig.initlength,
-                           GetConnectionTypeFromString(xgnokiiConfig.connection),
-                           RLP_DisplayF96Frame,
-                           xgnokiiConfig.synchronizetime);
+                            xgnokiiConfig.initlength, connection, NULL /*RLP_DisplayF96Frame*/, &xgnokii_statemachine);
 
 #ifdef XDEBUG
   g_print ("fbusinit: error %d\n", error);
@@ -161,10 +222,12 @@ static GSM_Error fbusinit(bool enable_monitoring)
   g_print("After usleep. GSM_LinkOK: %d\n", *GSM_LinkOK);
 #endif
 
-  if (*GSM_LinkOK == true)
-    InitModelInf ();
+  if (*GSM_LinkOK != true) {
+    return (GE_NOLINK);
+  }
 
-  return *GSM_LinkOK;
+  InitModelInf ();
+  return(GE_NONE);
 }
 
 
@@ -174,11 +237,12 @@ void GUI_InitPhoneMonitor (void)
   phoneMonitor.phone.version = phoneMonitor.phone.model;
   phoneMonitor.phone.revision = g_strdup (_("unknown"));
   phoneMonitor.phone.imei = g_strdup (_("unknown"));
+  phoneMonitor.supported = 0;
   phoneMonitor.rfLevel = phoneMonitor.batteryLevel = -1;
   phoneMonitor.powerSource = GPS_BATTERY;
-  phoneMonitor.working = FALSE;
+  phoneMonitor.working = NULL;
   phoneMonitor.alarm = FALSE;
-  phoneMonitor.sms.unRead = phoneMonitor.sms.number = phoneMonitor.sms.number2 = 0;
+  phoneMonitor.sms.unRead = phoneMonitor.sms.used = phoneMonitor.sms.slots = 0;
   phoneMonitor.sms.messages = NULL;
   phoneMonitor.call.callInProgress = CS_Idle;
   *phoneMonitor.call.callNum = '\0';
@@ -192,6 +256,8 @@ void GUI_InitPhoneMonitor (void)
   pthread_mutex_init (&smsMutex, NULL);
   pthread_mutex_init (&sendSMSMutex, NULL);
   pthread_cond_init (&sendSMSCond, NULL);
+  pthread_mutex_init (&saveSMSMutex, NULL);
+  pthread_cond_init (&saveSMSCond, NULL);
   pthread_mutex_init (&callMutex, NULL);
   pthread_mutex_init (&eventsMutex, NULL);
   pthread_mutex_init (&callMutex, NULL);
@@ -228,11 +294,12 @@ static inline void FreeArray (GSList **array)
 }
 
 
-void RefreshSMS (const gint number)
+static void RefreshSMS (const gint slots)
 {
   GSM_Error error;
   GSM_SMSMessage *msg;
   register gint i;
+  gint unread = 0;
 
 # ifdef XDEBUG
   g_print ("RefreshSMS is running...\n");
@@ -240,51 +307,43 @@ void RefreshSMS (const gint number)
 
   pthread_mutex_lock (&smsMutex);
   FreeArray (&(phoneMonitor.sms.messages));
-  phoneMonitor.sms.number = 0;
-  phoneMonitor.sms.number2 = 0;
+  phoneMonitor.sms.used = 0;
   pthread_mutex_unlock (&smsMutex);
 
-  i = 1;
-  while (1)
+  for (i=1; i<=slots; i++)
   {
+    GSM_Data gdat;
+    GSM_DataClear(&gdat);
     msg = g_malloc (sizeof (GSM_SMSMessage));
     msg->MemoryType = GMT_SM;
     msg->Location = i;
-#ifdef XDEBUG
-    fprintf(stdout, _("test: %d %i %i %i\n"),msg->Location,phoneMonitor.sms.number,phoneMonitor.sms.number2,number);
-#endif
-    pthread_mutex_lock (&smsMutex);
-    if( GetModelFeature(FN_SMS)==F_SMS71 ) msg->Location = 0;  /* read next sms for 6210/7110 */
-    error = GSM->GetSMSMessage (msg);
-    pthread_mutex_unlock (&smsMutex);
-    switch (error) {
-      case GE_NONE:
-        pthread_mutex_lock (&smsMutex);
-#ifdef XDEBUG
-    fprintf(stdout, _("Refresh SMS: g_slist_append: sms message"));
-    fprintf(stdout, _(" Location: %d"),msg->Location);
-    fprintf(stdout, _(" folder: %d"),msg->folder);
-    if ( msg-> SMSData) fprintf(stdout, _(" SMSData true\n"));
-       else  fprintf(stdout, _(" SMSData false\n"));
-#endif
-       /* RTH:  unread sms from folder 0 to INBOX */
-        phoneMonitor.sms.messages = g_slist_append (phoneMonitor.sms.messages, msg);
-        phoneMonitor.sms.number++;
-        phoneMonitor.sms.number2++;
-        pthread_mutex_unlock (&smsMutex);
-        if (phoneMonitor.sms.number2 == number) return;
-       break;
-      case GE_SMSTOOLONG: /* Picture Image in 7110 comp phone */
-        g_free (msg);
-        phoneMonitor.sms.number2++;
-        if (phoneMonitor.sms.number2 == number) return;
-       break;
-      default:
-        g_free (msg);
-       break;
+    gdat.SMSMessage = msg;
+
+    if ((error = SM_Functions(GOP_GetSMS, &gdat, &xgnokii_statemachine)) == GE_NONE)
+    {
+      pthread_mutex_lock (&smsMutex);
+      phoneMonitor.sms.messages = g_slist_append (phoneMonitor.sms.messages, msg);
+      phoneMonitor.sms.used++;
+      if (msg->Type == GST_MT && msg->Status == GSS_NOTSENTREAD)
+        unread++;
+      pthread_mutex_unlock (&smsMutex);
     }
-    i++;
+    else if (error == GE_INVALIDSMSLOCATION)  /* All positions are readed */
+    {
+      g_free (msg);
+      break;
+    }
+    else
+      g_free (msg);
+
+    /* FIXME: Why is any delay here?
+     */
+    /* usleep (750000); */
   }
+  /* Update it after the whole run as otherwise "Refreshing SMSes..."
+   * would collide with "Short Message received" message.
+   */
+  phoneMonitor.sms.unRead = unread;
 }
 
 
@@ -292,13 +351,16 @@ static gint A_GetMemoryStatus (gpointer data)
 {
   GSM_Error error;
   D_MemoryStatus *ms = (D_MemoryStatus *) data;
+  GSM_Data gdat;
 
   error = ms->status = GE_UNKNOWN;
 
   if (ms)
   {
+    GSM_DataClear(&gdat);        
     pthread_mutex_lock (&memoryMutex);
-    error = ms->status = GSM->GetMemoryStatus (&(ms->memoryStatus));
+    gdat.MemoryStatus=&(ms->memoryStatus);
+    error = ms->status = SM_Functions(GOP_GetMemoryStatus,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -311,13 +373,16 @@ static gint A_GetMemoryLocation (gpointer data)
 {
   GSM_Error error;
   D_MemoryLocation *ml = (D_MemoryLocation *) data;
+  GSM_Data gdat;
 
   error = ml->status = GE_UNKNOWN;
 
   if (ml)
   {
+    GSM_DataClear(&gdat);
     pthread_mutex_lock (&memoryMutex);
-    error = ml->status = GSM->GetMemoryLocation (ml->entry);
+    gdat.PhonebookEntry=(ml->entry);
+    error = ml->status = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -332,46 +397,51 @@ static gint A_GetMemoryLocationAll (gpointer data)
   GSM_Error error;
   D_MemoryLocationAll *mla = (D_MemoryLocationAll *) data;
   register gint i;
-  gint readed=0;
+  GSM_Data gdat;
 
   error = mla->status = GE_NONE;
   entry.MemoryType = mla->type;
+  GSM_DataClear(&gdat);
+  gdat.PhonebookEntry=&entry;
 
   pthread_mutex_lock (&memoryMutex);
   for (i = mla->min; i <= mla->max; i++)
   {
     entry.Location = i;
-    if (readed<mla->used) {
-      error = GSM->GetMemoryLocation (&entry);
-      if (error != GE_NONE)
-      {
-        gint err_count = 0;
+    error = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
+    if (error != GE_NONE && error!=GE_INVALIDPHBOOKLOCATION)
+    {
+      gint err_count = 0;
 
-        while (error != GE_NONE &&
-              error != GE_INVALIDPHBOOKLOCATION && error != GE_UNKNOWN) //n7110.c
+      while (error != GE_NONE)
+      {
+        g_print (_("%s: line %d: Can't get memory entry number %d from memory %d! %d\n"),
+                 __FILE__, __LINE__, i, entry.MemoryType, error);
+        if (err_count++ > 3)
         {
-          g_print (_("%s: line %d: Can't get memory entry number %d from memory %d! %d\n"),
-                   __FILE__, __LINE__, i, entry.MemoryType, error);
-          if (err_count++ > 3)
-          {
-            mla->ReadFailed (i);
-            mla->status = error;
-            pthread_cond_signal (&memoryCond);
-            pthread_mutex_unlock (&memoryMutex);
-            return (error);
-          }
-
-          error = GSM->GetMemoryLocation (&entry);
-          sleep (2);
+          mla->ReadFailed (i);
+          mla->status = error;
+          pthread_cond_signal (&memoryCond);
+          pthread_mutex_unlock (&memoryMutex);
+          return (error);
         }
+
+        error = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
+        sleep (2);
       }
-      
-      if (strcmp(entry.Number, "\0") || strcmp(entry.Name, "\0"))
-        readed++;
+    }
 
-    } else {
-      entry.Number[0]='\0';
-      entry.Name[0]='\0';
+    /* If the phonebook location was invalid - just fill up the rest */
+    /* This works on a 7110 anyway...*/
+
+    if (error==GE_INVALIDPHBOOKLOCATION) {
+       entry.Empty=true;
+       entry.Name[0]=0;
+        entry.Number[0]=0;
+       for (i = mla->min; i <= mla->max; i++) {
+               error = mla->InsertEntry (&entry);
+               if (error != GE_NONE) break;
+       }       
     }
 
     error = mla->InsertEntry (&entry);
@@ -389,13 +459,17 @@ static gint A_WriteMemoryLocation (gpointer data)
 {
   GSM_Error error;
   D_MemoryLocation *ml = (D_MemoryLocation *) data;
+  GSM_Data gdat;
 
   error = ml->status = GE_UNKNOWN;
 
+  GSM_DataClear(&gdat);
+  gdat.PhonebookEntry=(ml->entry);
+
   if (ml)
   {
     pthread_mutex_lock (&memoryMutex);
-    error = ml->status = GSM->WritePhonebookLocation (ml->entry);
+    error = ml->status = SM_Functions(GOP_WritePhonebook,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -497,6 +571,7 @@ static gint A_GetCalendarNoteAll (gpointer data)
     return (e);
 }
 
+
 static gint A_WriteCalendarNote (gpointer data)
 {
   GSM_Error error;
@@ -535,6 +610,7 @@ static gint A_GetCallerGroup (gpointer data)
   GSM_Bitmap bitmap;
   GSM_Error error;
   D_CallerGroup *cg = (D_CallerGroup *) data;
+  GSM_Data gdat;
 
   error = cg->status = GE_UNKNOWN;
 
@@ -544,7 +620,9 @@ static gint A_GetCallerGroup (gpointer data)
     bitmap.number = cg->number;
 
     pthread_mutex_lock (&callerGroupMutex);
-    error = cg->status = GSM->GetBitmap (&bitmap);
+    GSM_DataClear(&gdat);
+    gdat.Bitmap=&bitmap;
+    error = cg->status = SM_Functions(GOP_GetBitmap,&gdat,&xgnokii_statemachine);
     strncpy (cg->text, bitmap.text, 256);
     cg->text[255] = '\0';
     pthread_cond_signal (&callerGroupCond);
@@ -636,6 +714,24 @@ static gint A_SendSMSMessage (gpointer data)
 }
 
 
+static gint A_SaveSMSMessage (gpointer data)
+{
+  D_SMSMessage *d = (D_SMSMessage *) data;
+  GSM_Error error;
+
+  error = d->status = GE_UNKNOWN;
+  if (d)
+  {
+    pthread_mutex_lock (&saveSMSMutex);
+    error = d->status = GSM->SaveSMSMessage (d->sms);
+    pthread_cond_signal (&saveSMSCond);
+    pthread_mutex_unlock (&saveSMSMutex);
+  }
+
+  return (error);
+}
+
+
 static gint A_DeleteSMSMessage (gpointer data)
 {
   GSM_SMSMessage *sms = (GSM_SMSMessage *) data;
@@ -643,7 +739,10 @@ static gint A_DeleteSMSMessage (gpointer data)
 
   if (sms)
   {
-    error = GSM->DeleteSMSMessage(sms);
+    GSM_Data gdat;
+    GSM_DataClear(&gdat);
+    gdat.SMSMessage = sms;
+    error = SM_Functions(GOP_DeleteSMS, &gdat, &xgnokii_statemachine);
     g_free (sms);
   }
 
@@ -753,10 +852,11 @@ static gint A_GetAlarm (gpointer data)
   D_Alarm *a = (D_Alarm *) data;
   GSM_Error error;
 
-  error = a->status = GE_UNKNOWN;
+  error = GE_UNKNOWN;
 
-  if (a)
+  if (a && GSM)
   {
+    a->status = GE_UNKNOWN;
     pthread_mutex_lock (&alarmMutex);
     error = a->status = GSM->GetAlarm (0, &(a->time));
     pthread_cond_signal (&alarmCond);
@@ -790,7 +890,9 @@ static gint A_SendKeyStroke (gpointer data)
 
   if (buf) 
   {
-    GSM->PressKey(buf[1], buf[0]);
+#if 0
+    FB61_TX_SendMessage(0x07, 0x0c, buf);
+#endif
     g_free (buf);
   }
 
@@ -800,9 +902,12 @@ static gint A_SendKeyStroke (gpointer data)
 static gint A_GetBitmap(gpointer data) {
   GSM_Error error;
   D_Bitmap *d = (D_Bitmap *)data;
+  GSM_Data gdat;
 
+  GSM_DataClear(&gdat);
   pthread_mutex_lock(&getBitmapMutex);
-  error = d->status = GSM->GetBitmap(d->bitmap);
+  gdat.Bitmap=d->bitmap;
+  error = d->status = SM_Functions(GOP_GetBitmap,&gdat,&xgnokii_statemachine);
   pthread_cond_signal(&getBitmapCond);
   pthread_mutex_unlock(&getBitmapMutex);
   return error;
@@ -812,19 +917,24 @@ static gint A_SetBitmap(gpointer data) {
   GSM_Error error;
   D_Bitmap *d = (D_Bitmap *)data;
   GSM_Bitmap bitmap;
+  GSM_Data gdat;
   
+  GSM_DataClear(&gdat);
   pthread_mutex_lock(&setBitmapMutex);
   if (d->bitmap->type == GSM_CallerLogo) {
     bitmap.type = d->bitmap->type;
     bitmap.number = d->bitmap->number;
-    error = d->status = GSM->GetBitmap(&bitmap);
+    gdat.Bitmap=&bitmap;
+    error = d->status = SM_Functions(GOP_GetBitmap,&gdat,&xgnokii_statemachine);
     if (error == GE_NONE) {
       strncpy(d->bitmap->text,bitmap.text,sizeof(bitmap.text));
       d->bitmap->ringtone = bitmap.ringtone;
-      error = d->status = GSM->SetBitmap(d->bitmap);
+      gdat.Bitmap=d->bitmap;
+      error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&xgnokii_statemachine);
     }
   } else {
-    error = d->status = GSM->SetBitmap(d->bitmap);
+    gdat.Bitmap=d->bitmap;
+    error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&xgnokii_statemachine);
   }
   pthread_cond_signal(&setBitmapCond);
   pthread_mutex_unlock(&setBitmapMutex);
@@ -834,9 +944,13 @@ static gint A_SetBitmap(gpointer data) {
 static gint A_GetNetworkInfo(gpointer data) {
   GSM_Error error;
   D_NetworkInfo *d = (D_NetworkInfo *)data;
+  GSM_Data gdat;
+  
+  GSM_DataClear(&gdat);
 
   pthread_mutex_lock(&getNetworkInfoMutex);
-  error = d->status = GSM->GetNetworkInfo(d->info);
+  gdat.NetworkInfo=d->info;
+  error = d->status = SM_Functions(GOP_GetNetworkInfo,&gdat,&xgnokii_statemachine);
   pthread_cond_signal(&getNetworkInfoCond);
   pthread_mutex_unlock(&getNetworkInfoMutex);
   return error;
@@ -864,6 +978,7 @@ gint (*DoAction[])(gpointer) = {
   A_GetSMSCenter,
   A_SetSMSCenter,
   A_SendSMSMessage,
+  A_SaveSMSMessage,
   A_DeleteSMSMessage,
   A_GetSpeedDial,
   A_SendSpeedDial,
@@ -880,111 +995,148 @@ gint (*DoAction[])(gpointer) = {
   A_Exit
 };
 
+
 void *GUI_Connect (void *a)
 {
   /* Define required unit types for RF and Battery level meters. */
-  GSM_RFUnits rf_units = GRF_Arbitrary;
-  GSM_BatteryUnits batt_units = GBU_Arbitrary;
+  GSM_RFUnits rf_units = GRF_Percentage;
+  GSM_BatteryUnits batt_units = GBU_Percentage;
 
   GSM_DateTime Alarm;
+  GSM_SMSStatus SMSStatus = {0, 0, 0};
   gchar number[INCALL_NUMBER_LENGTH];
-  PhoneEvent *event=NULL;
+  PhoneEvent *event;
   GSM_Error error;
   gint status;
+  GSM_Data data;
 
+  GSM_DataClear(&data);
 
 # ifdef XDEBUG
   g_print ("Initializing connection...\n");
 # endif
 
   phoneMonitor.working = _("Connecting...");
-  while (!fbusinit (true))
+  while (fbusinit (true))
     sleep (1);
 
 # ifdef XDEBUG
   g_print ("Phone connected. Starting monitoring...\n");
 # endif
 
+  sleep(1);
+
+  data.RFLevel=&phoneMonitor.rfLevel;
+  data.RFUnits=&rf_units;
+  data.PowerSource=&phoneMonitor.powerSource;
+  data.BatteryUnits=&batt_units; 
+  data.BatteryLevel=&phoneMonitor.batteryLevel;
+  data.DateTime=&Alarm;
+  data.SMSStatus=&SMSStatus;
+  data.IncomingCallNr=number;
+
   while (1)
   {
-    if (event != NULL) {
-      phoneMonitor.working = _("Working...");
-    } else {
-      phoneMonitor.working = NULL;
+    phoneMonitor.working = NULL;
 
-      if (GSM->GetRFLevel (&rf_units, &phoneMonitor.rfLevel) != GE_NONE)
-        phoneMonitor.rfLevel = -1;
+    /* FIXME - this loop goes mad on my 7110 - so I've put in a usleep */
+    usleep(50000);
 
-      if (rf_units == GRF_Arbitrary)
-        phoneMonitor.rfLevel *= 25;
+    if (SM_Functions(GOP_GetRFLevel,&data,&xgnokii_statemachine) != GE_NONE)
+      phoneMonitor.rfLevel = -1;
 
-      if (GSM->GetPowerSource (&phoneMonitor.powerSource) == GE_NONE 
-          && phoneMonitor.powerSource == GPS_ACDC)
-        phoneMonitor.batteryLevel = ((gint) phoneMonitor.batteryLevel + 25) % 125;
-      else
+    if (rf_units == GRF_Arbitrary)
+      phoneMonitor.rfLevel *= 25;
+
+    if (SM_Functions(GOP_GetPowersource,&data,&xgnokii_statemachine)  == GE_NONE 
+        && phoneMonitor.powerSource == GPS_ACDC)
+    {
+      if (phoneMonitor.batteryLevel < 0 || phoneMonitor.batteryLevel > 100)
+        phoneMonitor.batteryLevel = 100;
+    }
+    else {
+      if (SM_Functions(GOP_GetBatteryLevel,&data,&xgnokii_statemachine) != GE_NONE)
+        phoneMonitor.batteryLevel = -1;
+      if (batt_units == GBU_Arbitrary)
+        phoneMonitor.batteryLevel *= 25;
+    }
+
+    if (SM_Functions(GOP_GetAlarm,&data,&xgnokii_statemachine) == GE_NONE && Alarm.AlarmEnabled != 0)
+      phoneMonitor.alarm = TRUE;
+    else
+      phoneMonitor.alarm = FALSE;
+
+    if (SM_Functions(GOP_GetSMSStatus,&data,&xgnokii_statemachine) == GE_NONE)
+    {
+      /* Change of "UnRead" shouldn't be interesting - user may have read some of his
+       * SMSes by the phone interface.
+       */
+      if (phoneMonitor.sms.unRead != SMSStatus.UnRead ||
+          phoneMonitor.sms.used   != SMSStatus.Used ||
+          phoneMonitor.sms.slots  != SMSStatus.Slots)  /* shouldn't change, just to be sure */
       {
-        if (GSM->GetBatteryLevel (&batt_units, &phoneMonitor.batteryLevel) != GE_NONE)
-          phoneMonitor.batteryLevel = -1;
-        if (batt_units == GBU_Arbitrary)
-          phoneMonitor.batteryLevel *= 25;
+       /* We are primarily interested in SMSStatus.Slots so try to fix it up if it is broken
+        */
+       if (SMSStatus.UnRead > SMSStatus.Used)
+         SMSStatus.Used = SMSStatus.UnRead;
+       if (SMSStatus.Used > SMSStatus.Slots)
+         SMSStatus.Slots = SMSStatus.Used;
+        phoneMonitor.sms.slots = SMSStatus.Slots;      /* shouldn't change, just to be sure */
+       /* phoneMonitor.sms.{unRead,used} will be updated by RefreshSMS()
+        */
+
+        phoneMonitor.working = _("Refreshing SMSes...");
+        RefreshSMS (SMSStatus.Slots);
+        phoneMonitor.working = NULL;
       }
 
-      if (GSM->GetAlarm (0, &Alarm) == GE_NONE && Alarm.IsSet != 0)
-        phoneMonitor.alarm = TRUE;
-      else
-        phoneMonitor.alarm = FALSE;
+    }
 
-      if (GSM->GetIncomingCallNr (number) == GE_NONE)
-      {
+    if (SM_Functions(GOP_GetIncomingCallNr,&data,&xgnokii_statemachine) == GE_NONE)
+    {
 #   ifdef XDEBUG
-        g_print ("Call in progress: %s\n", phoneMonitor.call.callNum);
+      g_print ("Call in progress: %s\n", phoneMonitor.call.callNum);
 #   endif
 
-        if (GSM->GetDisplayStatus (&status)==GE_NONE) {
-          if (status & (1<<DS_Call_In_Progress))
-          {
-            pthread_mutex_lock (&callMutex);
-            phoneMonitor.call.callInProgress = CS_InProgress;
-            pthread_mutex_unlock (&callMutex);
-          }
-          else
-          {
-            pthread_mutex_lock (&callMutex);
-            phoneMonitor.call.callInProgress = CS_Waiting;
-            strncpy (phoneMonitor.call.callNum, number, INCALL_NUMBER_LENGTH);
-            pthread_mutex_unlock (&callMutex);
-         }
-        } else {
-          pthread_mutex_lock (&callMutex);
-          phoneMonitor.call.callInProgress = CS_Idle;
-          *phoneMonitor.call.callNum = '\0';
-          pthread_mutex_unlock (&callMutex);
-       }
-      }
-      else
+      GSM->GetDisplayStatus (&status);
+      if (status & (1<<DS_Call_In_Progress))
       {
         pthread_mutex_lock (&callMutex);
-        phoneMonitor.call.callInProgress = CS_Idle;
-        *phoneMonitor.call.callNum = '\0';
+        phoneMonitor.call.callInProgress = CS_InProgress;
         pthread_mutex_unlock (&callMutex);
       }
-
-      pthread_mutex_lock (&netMonMutex);
-      if (phoneMonitor.netmonitor.number)
-      {
-        GSM->NetMonitor (phoneMonitor.netmonitor.number,
-                         phoneMonitor.netmonitor.screen);
-        GSM->NetMonitor (3, phoneMonitor.netmonitor.screen3);
-        GSM->NetMonitor (4, phoneMonitor.netmonitor.screen4);
-        GSM->NetMonitor (5, phoneMonitor.netmonitor.screen5);
-      }
       else
       {
-        *phoneMonitor.netmonitor.screen = *phoneMonitor.netmonitor.screen3 = 
-        *phoneMonitor.netmonitor.screen4 = *phoneMonitor.netmonitor.screen5 = '\0';
+        pthread_mutex_lock (&callMutex);
+        phoneMonitor.call.callInProgress = CS_Waiting;
+        strncpy (phoneMonitor.call.callNum, number, INCALL_NUMBER_LENGTH);
+        pthread_mutex_unlock (&callMutex);
       }
-      pthread_mutex_unlock (&netMonMutex);
     }
+    else
+    {
+      pthread_mutex_lock (&callMutex);
+      phoneMonitor.call.callInProgress = CS_Idle;
+      *phoneMonitor.call.callNum = '\0';
+      pthread_mutex_unlock (&callMutex);
+    }
+
+    pthread_mutex_lock (&netMonMutex);
+    if (phoneMonitor.netmonitor.number)
+    {
+      GSM->NetMonitor (phoneMonitor.netmonitor.number,
+                       phoneMonitor.netmonitor.screen);
+      GSM->NetMonitor (3, phoneMonitor.netmonitor.screen3);
+      GSM->NetMonitor (4, phoneMonitor.netmonitor.screen4);
+      GSM->NetMonitor (5, phoneMonitor.netmonitor.screen5);
+    }
+    else
+    {
+      *phoneMonitor.netmonitor.screen = *phoneMonitor.netmonitor.screen3 = 
+      *phoneMonitor.netmonitor.screen4 = *phoneMonitor.netmonitor.screen5 = '\0';
+    }
+    pthread_mutex_unlock (&netMonMutex);
+
     while ((event = RemoveEvent ()) != NULL)
     {
 #     ifdef XDEBUG