5 A Linux/Unix GUI for Nokia mobile phones.
6 Copyright (C) 1999 Pavel Janík ml., Hugh Blemings
7 & Ján Derfiòák <ja@mail.upjs.sk>.
9 Released under the terms of the GNU GPL, see file COPYING for more details.
14 Revision 1.1.1.3 2002/04/03 00:08:22 short
15 Found in "gnokii-working" directory, some November-patches version
17 Revision 1.4 2001/05/30 14:36:47 pkot
18 Fix smsd to use StateMachine and let it compile.
20 Revision 1.3 2001/03/29 08:42:59 ja
21 Enabling compilation of smsd.
23 Revision 1.2 2001/02/02 08:09:57 ja
24 New dialogs for 6210/7110 in xgnokii. Fixed the smsd for new capabilty code.
34 #include "gsm-common.h"
36 #include "fbus-6110.h"
37 #include "fbus-3810.h"
42 PhoneMonitor phoneMonitor;
43 pthread_mutex_t smsMutex;
44 pthread_cond_t smsCond;
45 pthread_mutex_t sendSMSMutex;
46 pthread_cond_t sendSMSCond;
47 static pthread_mutex_t eventsMutex;
48 static GSList *ScheduledEvents = NULL;
51 inline void InsertEvent (PhoneEvent *event)
54 g_print ("Inserting Event: %d\n", event->event);
56 pthread_mutex_lock (&eventsMutex);
57 ScheduledEvents = g_slist_prepend (ScheduledEvents, event);
58 pthread_mutex_unlock (&eventsMutex);
62 inline static PhoneEvent *RemoveEvent (void)
65 PhoneEvent *event = NULL;
67 pthread_mutex_lock (&eventsMutex);
68 list = g_slist_last (ScheduledEvents);
71 event = (PhoneEvent *) list->data;
72 ScheduledEvents = g_slist_remove_link (ScheduledEvents, list);
73 g_slist_free_1 (list);
75 pthread_mutex_unlock (&eventsMutex);
81 static void InitModelInf (void)
87 while ((error = GSM->GetModel(buf)) != GE_NONE && i++ < 15)
92 g_free (phoneMonitor.phone.model);
93 phoneMonitor.phone.version = g_strdup (buf);
94 phoneMonitor.phone.model = GetModel (buf);
95 if (phoneMonitor.phone.model == NULL)
96 phoneMonitor.phone.model = g_strdup (_("unknown"));
98 phoneMonitor.supported = GetPhoneModel(buf)->flags;
102 while ((error = GSM->GetRevision (buf)) != GE_NONE && i++ < 5)
105 if (error == GE_NONE)
107 g_free (phoneMonitor.phone.revision);
108 phoneMonitor.phone.revision = g_strdup (buf);
112 while ((error = GSM->GetIMEI (buf)) != GE_NONE && i++ < 5)
115 if (error == GE_NONE)
117 g_free (phoneMonitor.phone.imei);
118 phoneMonitor.phone.imei = g_strdup (buf);
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);
131 static GSM_Error fbusinit(bool enable_monitoring)
134 GSM_Error error=GE_NOLINK;
135 GSM_ConnectionType connection=GCT_Serial;
136 static GSM_Statemachine sm;
138 if (!strcmp(smsdConfig.connection, "infrared"))
139 connection = GCT_Infrared;
141 /* Initialise the code for the GSM interface. */
143 if (error == GE_NOLINK)
144 error = GSM_Initialise (smsdConfig.model, smsdConfig.port,
145 smsdConfig.initlength, connection, NULL, &sm);
148 g_print ("fbusinit: error %d\n", error);
151 if (error != GE_NONE) {
152 g_print (_("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
156 while (count++ < 40 && *GSM_LinkOK == false)
159 g_print("After usleep. GSM_LinkOK: %d\n", *GSM_LinkOK);
162 if (*GSM_LinkOK != true) {
171 void InitPhoneMonitor (void)
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.supported = 0;
178 phoneMonitor.working = FALSE;
179 phoneMonitor.sms.unRead = phoneMonitor.sms.used = phoneMonitor.sms.slots = 0;
180 phoneMonitor.sms.messages = NULL;
181 pthread_mutex_init (&smsMutex, NULL);
182 pthread_cond_init (&smsCond, NULL);
183 pthread_mutex_init (&sendSMSMutex, NULL);
184 pthread_cond_init (&sendSMSCond, NULL);
185 pthread_mutex_init (&eventsMutex, NULL);
189 static inline void FreeElement (gpointer data, gpointer userData)
191 g_free ((GSM_SMSMessage *) data);
195 static inline void FreeArray (GSList **array)
199 g_slist_foreach (*array, FreeElement, NULL);
200 g_slist_free (*array);
206 static void RefreshSMS (const gint slots)
214 g_print ("RefreshSMS is running...\n");
217 pthread_mutex_lock (&smsMutex);
218 FreeArray (&(phoneMonitor.sms.messages));
219 phoneMonitor.sms.used = 0;
220 // pthread_mutex_unlock (&smsMutex);
222 for (i=1; i<=slots; i++)
224 msg = g_malloc (sizeof (GSM_SMSMessage));
225 msg->MemoryType = GMT_SM;
228 if ((error = GSM->GetSMSMessage (msg)) == GE_NONE)
230 // pthread_mutex_lock (&smsMutex);
231 phoneMonitor.sms.messages = g_slist_append (phoneMonitor.sms.messages, msg);
232 phoneMonitor.sms.used++;
233 if (msg->Type == GST_MT && msg->Status == GSS_NOTSENTREAD)
235 // pthread_mutex_unlock (&smsMutex);
237 else if (error == GE_INVALIDSMSLOCATION) /* All positions are readed */
245 /* FIXME: Why is any delay here?
247 /* usleep (750000); */
249 /* Update it after the whole run as otherwise "Refreshing SMSes..."
250 * would collide with "Short Message received" message.
252 phoneMonitor.sms.unRead = unread;
254 pthread_cond_signal (&smsCond);
255 pthread_mutex_unlock (&smsMutex);
259 static gint A_SendSMSMessage (gpointer data)
261 D_SMSMessage *d = (D_SMSMessage *) data;
264 error = d->status = GE_UNKNOWN;
267 pthread_mutex_lock (&sendSMSMutex);
268 error = d->status = GSM->SendSMSMessage (d->sms);
269 pthread_cond_signal (&sendSMSCond);
270 pthread_mutex_unlock (&sendSMSMutex);
273 if (d->status == GE_SMSSENDOK)
280 static gint A_DeleteSMSMessage (gpointer data)
282 GSM_SMSMessage *sms = (GSM_SMSMessage *) data;
283 GSM_Error error = GE_UNKNOWN;
287 error = GSM->DeleteSMSMessage(sms);
288 // I don't use copy, I don't need free message.
296 static gint A_Exit (gpointer data)
299 return (0); /* just to be proper */
303 gint (*DoAction[])(gpointer) = {
310 void *Connect (void *a)
312 GSM_SMSStatus SMSStatus = {0, 0, 0};
318 g_print ("Initializing connection...\n");
321 while (fbusinit (true))
325 g_print ("Phone connected. Starting monitoring...\n");
330 phoneMonitor.working = FALSE;
332 if (GSM->GetSMSStatus (&SMSStatus) == GE_NONE)
334 /* Change of "UnRead" shouldn't be interesting - user may have read some of his
335 * SMSes by the phone interface.
337 if (phoneMonitor.sms.unRead != SMSStatus.UnRead ||
338 phoneMonitor.sms.used != SMSStatus.Used ||
339 phoneMonitor.sms.slots != SMSStatus.Slots) /* shouldn't change, just to be sure */
341 /* We are primarily interested in SMSStatus.Slots so try to fix it up if it is broken
343 if (SMSStatus.UnRead > SMSStatus.Used)
344 SMSStatus.Used = SMSStatus.UnRead;
345 if (SMSStatus.Used > SMSStatus.Slots)
346 SMSStatus.Slots = SMSStatus.Used;
347 phoneMonitor.sms.slots = SMSStatus.Slots; /* shouldn't change, just to be sure */
348 /* phoneMonitor.sms.{unRead,used} will be updated by RefreshSMS()
351 phoneMonitor.working = TRUE;
352 RefreshSMS (SMSStatus.Slots);
353 phoneMonitor.working = FALSE;
356 phoneMonitor.sms.unRead = SMSStatus.UnRead;
359 while ((event = RemoveEvent ()) != NULL)
362 g_print ("Processing Event: %d\n", event->event);
364 phoneMonitor.working = TRUE;
365 if (event->event <= Event_Exit)
366 if (((error = DoAction[event->event] (event->data)) != GE_NONE) && error != GE_SMSSENDOK)
367 g_print (_("Event %d failed with return code %d!\n"), event->event, error);