Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
[gnokii.git] / xgnokii / xgnokii_lowlevel.c
index a606d73..73b0b50 100644 (file)
 
   Released under the terms of the GNU GPL, see file COPYING for more details.
 
+  $Log$
+  Revision 1.1.1.5  2002/04/03 01:44:15  short
+  Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
+
+  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>
@@ -19,8 +64,8 @@
 #include "misc.h"
 #include "gsm-common.h"
 #include "gsm-api.h"
-//#include "6110.h"
-//#include "fbus-3810.h"
+#include "fbus-6110.h"
+#include "fbus-3810.h"
 #include "xgnokii_lowlevel.h"
 #include "xgnokii.h"
 #include "gsm-statemachine.h"
@@ -35,6 +80,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;
@@ -54,9 +101,9 @@ pthread_cond_t  getNetworkInfoCond;
 static pthread_mutex_t eventsMutex;
 static GSList *ScheduledEvents = NULL;
 
-static GSM_Statemachine statemachine;
-/* FIXME - don't really know what should own the statemachine in */
-/* the xgnokii scheme of things - Chris */
+/* This symbol must be export as it is (mis)used by xgnokii_logos.c
+ */
+GSM_Statemachine xgnokii_statemachine;
 
 
 inline void GUI_InsertEvent (PhoneEvent *event)
@@ -98,7 +145,7 @@ static void InitModelInf (void)
 
   GSM_DataClear(&data);
   data.Model=buf;
-  while ((error = SM_Functions(GOP_GetModel,&data,&statemachine)) != GE_NONE && i++ < 15)
+  while ((error = SM_Functions(GOP_GetModel,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 15)
     sleep(1);
 
   if (error == GE_NONE)
@@ -114,7 +161,7 @@ static void InitModelInf (void)
 
   i = 0;
   data.Revision=buf;
-  while ((error = SM_Functions(GOP_GetRevision,&data,&statemachine)) != GE_NONE && i++ < 5)
+  while ((error = SM_Functions(GOP_GetRevision,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 5)
     sleep(1);
 
   if (error == GE_NONE)
@@ -125,7 +172,7 @@ static void InitModelInf (void)
 
   i = 0;
   data.Imei=buf;
-  while ((error = SM_Functions(GOP_GetImei,&data,&statemachine)) != GE_NONE && i++ < 5)
+  while ((error = SM_Functions(GOP_GetImei,&data,&xgnokii_statemachine)) != GE_NONE && i++ < 5)
     sleep(1);
 
   if (error == GE_NONE)
@@ -147,7 +194,7 @@ static void InitModelInf (void)
 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;
 
   if (!strcmp(xgnokiiConfig.connection, "infrared"))
@@ -156,11 +203,14 @@ static GSM_Error fbusinit(bool enable_monitoring)
   if (!strcmp(xgnokiiConfig.connection, "irda"))
     connection = GCT_Irda;
 
+  if (!strcmp(xgnokiiConfig.connection, "tcp"))
+    connection = GCT_TCP;
+
   /* Initialise the code for the GSM interface. */     
 
   if (error == GE_NOLINK)
     error = GSM_Initialise (xgnokiiConfig.model, xgnokiiConfig.port,
-                            xgnokiiConfig.initlength, connection, RLP_DisplayF96Frame, &statemachine);
+                            xgnokiiConfig.initlength, connection, NULL /*RLP_DisplayF96Frame*/, &xgnokii_statemachine);
 
 #ifdef XDEBUG
   g_print ("fbusinit: error %d\n", error);
@@ -178,10 +228,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);
 }
 
 
@@ -196,7 +248,7 @@ void GUI_InitPhoneMonitor (void)
   phoneMonitor.powerSource = GPS_BATTERY;
   phoneMonitor.working = NULL;
   phoneMonitor.alarm = FALSE;
-  phoneMonitor.sms.unRead = phoneMonitor.sms.number = 0;
+  phoneMonitor.sms.unRead = phoneMonitor.sms.used = phoneMonitor.sms.slots = 0;
   phoneMonitor.sms.messages = NULL;
   phoneMonitor.call.callInProgress = CS_Idle;
   *phoneMonitor.call.callNum = '\0';
@@ -210,6 +262,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);
@@ -246,11 +300,12 @@ static inline void FreeArray (GSList **array)
 }
 
 
-static 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");
@@ -258,27 +313,26 @@ static void RefreshSMS (const gint number)
 
   pthread_mutex_lock (&smsMutex);
   FreeArray (&(phoneMonitor.sms.messages));
-  phoneMonitor.sms.number = 0;
+  phoneMonitor.sms.used = 0;
   pthread_mutex_unlock (&smsMutex);
 
-  i = 0;
-  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->Number = ++i;
+    msg->Location = i;
     gdat.SMSMessage = msg;
 
-    if ((error = SM_Functions(GOP_GetSMS, &gdat, &statemachine)) == GE_NONE)
+    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.number++;
+      phoneMonitor.sms.used++;
+      if (msg->Type == GST_MT && msg->Status == GSS_NOTSENTREAD)
+        unread++;
       pthread_mutex_unlock (&smsMutex);
-      if (phoneMonitor.sms.number == number)
-        return;
     }
     else if (error == GE_INVALIDSMSLOCATION)  /* All positions are readed */
     {
@@ -288,8 +342,14 @@ static void RefreshSMS (const gint number)
     else
       g_free (msg);
 
-    usleep (750000);
+    /* 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;
 }
 
 
@@ -306,7 +366,7 @@ static gint A_GetMemoryStatus (gpointer data)
     GSM_DataClear(&gdat);        
     pthread_mutex_lock (&memoryMutex);
     gdat.MemoryStatus=&(ms->memoryStatus);
-    error = ms->status = SM_Functions(GOP_GetMemoryStatus,&gdat,&statemachine);
+    error = ms->status = SM_Functions(GOP_GetMemoryStatus,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -328,7 +388,7 @@ static gint A_GetMemoryLocation (gpointer data)
     GSM_DataClear(&gdat);
     pthread_mutex_lock (&memoryMutex);
     gdat.PhonebookEntry=(ml->entry);
-    error = ml->status = SM_Functions(GOP_ReadPhonebook,&gdat,&statemachine);
+    error = ml->status = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -354,7 +414,7 @@ static gint A_GetMemoryLocationAll (gpointer data)
   for (i = mla->min; i <= mla->max; i++)
   {
     entry.Location = i;
-    error = SM_Functions(GOP_ReadPhonebook,&gdat,&statemachine);
+    error = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
     if (error != GE_NONE && error!=GE_INVALIDPHBOOKLOCATION)
     {
       gint err_count = 0;
@@ -372,7 +432,7 @@ static gint A_GetMemoryLocationAll (gpointer data)
           return (error);
         }
 
-        error = SM_Functions(GOP_ReadPhonebook,&gdat,&statemachine);
+        error = SM_Functions(GOP_ReadPhonebook,&gdat,&xgnokii_statemachine);
         sleep (2);
       }
     }
@@ -415,7 +475,7 @@ static gint A_WriteMemoryLocation (gpointer data)
   if (ml)
   {
     pthread_mutex_lock (&memoryMutex);
-    error = ml->status = SM_Functions(GOP_WritePhonebook,&gdat,&statemachine);
+    error = ml->status = SM_Functions(GOP_WritePhonebook,&gdat,&xgnokii_statemachine);
     pthread_cond_signal (&memoryCond);
     pthread_mutex_unlock (&memoryMutex);
   }
@@ -568,7 +628,7 @@ static gint A_GetCallerGroup (gpointer data)
     pthread_mutex_lock (&callerGroupMutex);
     GSM_DataClear(&gdat);
     gdat.Bitmap=&bitmap;
-    error = cg->status = SM_Functions(GOP_GetBitmap,&gdat,&statemachine);
+    error = cg->status = SM_Functions(GOP_GetBitmap,&gdat,&xgnokii_statemachine);
     strncpy (cg->text, bitmap.text, 256);
     cg->text[255] = '\0';
     pthread_cond_signal (&callerGroupCond);
@@ -648,7 +708,7 @@ static gint A_SendSMSMessage (gpointer data)
   if (d)
   {
     pthread_mutex_lock (&sendSMSMutex);
-    error = d->status = GSM->SendSMSMessage (d->sms, 0);
+    error = d->status = GSM->SendSMSMessage (d->sms);
     pthread_cond_signal (&sendSMSCond);
     pthread_mutex_unlock (&sendSMSMutex);
   }
@@ -660,6 +720,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;
@@ -670,7 +748,7 @@ static gint A_DeleteSMSMessage (gpointer data)
     GSM_Data gdat;
     GSM_DataClear(&gdat);
     gdat.SMSMessage = sms;
-    error = SM_Functions(GOP_DeleteSMS, &gdat, &statemachine);
+    error = SM_Functions(GOP_DeleteSMS, &gdat, &xgnokii_statemachine);
     g_free (sms);
   }
 
@@ -782,7 +860,7 @@ static gint A_GetAlarm (gpointer data)
 
   error = GE_UNKNOWN;
 
-  if (a)
+  if (a && GSM)
   {
     a->status = GE_UNKNOWN;
     pthread_mutex_lock (&alarmMutex);
@@ -814,14 +892,15 @@ static gint A_SetAlarm (gpointer data)
 
 static gint A_SendKeyStroke (gpointer data)
 {
-  /*  gchar *buf = (gchar *) data;*/
+  gchar *buf = (gchar *) data;
 
-  /* This is wrong. FIX IT */
-  /*  if (buf) 
+  if (buf) 
   {
+#if 0
     FB61_TX_SendMessage(0x07, 0x0c, buf);
+#endif
     g_free (buf);
-    }*/
+  }
 
   return (0);
 }
@@ -834,7 +913,7 @@ static gint A_GetBitmap(gpointer data) {
   GSM_DataClear(&gdat);
   pthread_mutex_lock(&getBitmapMutex);
   gdat.Bitmap=d->bitmap;
-  error = d->status = SM_Functions(GOP_GetBitmap,&gdat,&statemachine);
+  error = d->status = SM_Functions(GOP_GetBitmap,&gdat,&xgnokii_statemachine);
   pthread_cond_signal(&getBitmapCond);
   pthread_mutex_unlock(&getBitmapMutex);
   return error;
@@ -852,16 +931,16 @@ static gint A_SetBitmap(gpointer data) {
     bitmap.type = d->bitmap->type;
     bitmap.number = d->bitmap->number;
     gdat.Bitmap=&bitmap;
-    error = d->status = SM_Functions(GOP_GetBitmap,&gdat,&statemachine);
+    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;
       gdat.Bitmap=d->bitmap;
-      error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&statemachine);
+      error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&xgnokii_statemachine);
     }
   } else {
     gdat.Bitmap=d->bitmap;
-    error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&statemachine);
+    error = d->status = SM_Functions(GOP_SetBitmap,&gdat,&xgnokii_statemachine);
   }
   pthread_cond_signal(&setBitmapCond);
   pthread_mutex_unlock(&setBitmapMutex);
@@ -877,7 +956,7 @@ static gint A_GetNetworkInfo(gpointer data) {
 
   pthread_mutex_lock(&getNetworkInfoMutex);
   gdat.NetworkInfo=d->info;
-  error = d->status = SM_Functions(GOP_GetNetworkInfo,&gdat,&statemachine);
+  error = d->status = SM_Functions(GOP_GetNetworkInfo,&gdat,&xgnokii_statemachine);
   pthread_cond_signal(&getNetworkInfoCond);
   pthread_mutex_unlock(&getNetworkInfoMutex);
   return error;
@@ -905,6 +984,7 @@ gint (*DoAction[])(gpointer) = {
   A_GetSMSCenter,
   A_SetSMSCenter,
   A_SendSMSMessage,
+  A_SaveSMSMessage,
   A_DeleteSMSMessage,
   A_GetSpeedDial,
   A_SendSpeedDial,
@@ -929,7 +1009,7 @@ void *GUI_Connect (void *a)
   GSM_BatteryUnits batt_units = GBU_Percentage;
 
   GSM_DateTime Alarm;
-  GSM_SMSMemoryStatus SMSStatus = {0, 0};
+  GSM_SMSStatus SMSStatus = {0, 0, 0};
   gchar number[INCALL_NUMBER_LENGTH];
   PhoneEvent *event;
   GSM_Error error;
@@ -943,7 +1023,7 @@ void *GUI_Connect (void *a)
 # endif
 
   phoneMonitor.working = _("Connecting...");
-  while (!fbusinit (true))
+  while (fbusinit (true))
     sleep (1);
 
 # ifdef XDEBUG
@@ -968,42 +1048,57 @@ void *GUI_Connect (void *a)
     /* FIXME - this loop goes mad on my 7110 - so I've put in a usleep */
     usleep(50000);
 
-    if (SM_Functions(GOP_GetRFLevel,&data,&statemachine) != GE_NONE)
+    if (SM_Functions(GOP_GetRFLevel,&data,&xgnokii_statemachine) != GE_NONE)
       phoneMonitor.rfLevel = -1;
 
     if (rf_units == GRF_Arbitrary)
       phoneMonitor.rfLevel *= 25;
 
-    if (SM_Functions(GOP_GetPowersource,&data,&statemachine)  == GE_NONE 
+    if (SM_Functions(GOP_GetPowersource,&data,&xgnokii_statemachine)  == GE_NONE 
         && phoneMonitor.powerSource == GPS_ACDC)
-      phoneMonitor.batteryLevel = ((gint) phoneMonitor.batteryLevel + 25) % 125;
-    else
     {
-      if (SM_Functions(GOP_GetBatteryLevel,&data,&statemachine) != GE_NONE)
+      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,&statemachine) == GE_NONE && Alarm.AlarmEnabled != 0)
+    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,&statemachine) == GE_NONE)
+    if (SM_Functions(GOP_GetSMSStatus,&data,&xgnokii_statemachine) == GE_NONE)
     {
-      if (phoneMonitor.sms.unRead != SMSStatus.Unread ||
-          phoneMonitor.sms.number != SMSStatus.Number)
+      /* 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 */
       {
+       /* 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.Number);
+        RefreshSMS (SMSStatus.Slots);
         phoneMonitor.working = NULL;
       }
 
-      phoneMonitor.sms.unRead = SMSStatus.Unread;
     }
 
-    if (SM_Functions(GOP_GetIncomingCallNr,&data,&statemachine) == GE_NONE)
+    if (SM_Functions(GOP_GetIncomingCallNr,&data,&xgnokii_statemachine) == GE_NONE)
     {
 #   ifdef XDEBUG
       g_print ("Call in progress: %s\n", phoneMonitor.call.callNum);