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.4 2002/04/03 01:44:15 short
15 Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
17 Revision 1.1.1.3 2002/04/03 00:08:22 short
18 Found in "gnokii-working" directory, some November-patches version
20 Revision 1.4 2001/05/30 14:36:47 pkot
21 Fix smsd to use StateMachine and let it compile.
23 Revision 1.3 2001/03/29 08:42:59 ja
24 Enabling compilation of smsd.
26 Revision 1.2 2001/02/02 08:09:57 ja
27 New dialogs for 6210/7110 in xgnokii. Fixed the smsd for new capabilty code.
37 #include "gsm-common.h"
39 #include "fbus-6110.h"
40 #include "fbus-3810.h"
45 PhoneMonitor phoneMonitor;
46 pthread_mutex_t smsMutex;
47 pthread_cond_t smsCond;
48 pthread_mutex_t sendSMSMutex;
49 pthread_cond_t sendSMSCond;
50 static pthread_mutex_t eventsMutex;
51 static GSList *ScheduledEvents = NULL;
54 inline void InsertEvent (PhoneEvent *event)
57 g_print ("Inserting Event: %d\n", event->event);
59 pthread_mutex_lock (&eventsMutex);
60 ScheduledEvents = g_slist_prepend (ScheduledEvents, event);
61 pthread_mutex_unlock (&eventsMutex);
65 inline static PhoneEvent *RemoveEvent (void)
68 PhoneEvent *event = NULL;
70 pthread_mutex_lock (&eventsMutex);
71 list = g_slist_last (ScheduledEvents);
74 event = (PhoneEvent *) list->data;
75 ScheduledEvents = g_slist_remove_link (ScheduledEvents, list);
76 g_slist_free_1 (list);
78 pthread_mutex_unlock (&eventsMutex);
84 static void InitModelInf (void)
90 while ((error = GSM->GetModel(buf)) != GE_NONE && i++ < 15)
95 g_free (phoneMonitor.phone.model);
96 phoneMonitor.phone.version = g_strdup (buf);
97 phoneMonitor.phone.model = GetModel (buf);
98 if (phoneMonitor.phone.model == NULL)
99 phoneMonitor.phone.model = g_strdup (_("unknown"));
101 phoneMonitor.supported = GetPhoneModel(buf)->flags;
105 while ((error = GSM->GetRevision (buf)) != GE_NONE && i++ < 5)
108 if (error == GE_NONE)
110 g_free (phoneMonitor.phone.revision);
111 phoneMonitor.phone.revision = g_strdup (buf);
115 while ((error = GSM->GetIMEI (buf)) != GE_NONE && i++ < 5)
118 if (error == GE_NONE)
120 g_free (phoneMonitor.phone.imei);
121 phoneMonitor.phone.imei = g_strdup (buf);
126 g_print ("Version: %s\n", phoneMonitor.phone.version);
127 g_print ("Model: %s\n", phoneMonitor.phone.model);
128 g_print ("IMEI: %s\n", phoneMonitor.phone.imei);
129 g_print ("Revision: %s\n", phoneMonitor.phone.revision);
134 static GSM_Error fbusinit(bool enable_monitoring)
137 GSM_Error error=GE_NOLINK;
138 GSM_ConnectionType connection=GCT_Serial;
139 static GSM_Statemachine sm;
141 if (!strcmp(smsdConfig.connection, "infrared"))
142 connection = GCT_Infrared;
143 if (!strcmp(smsdConfig.connection, "tcp"))
144 connection = GCT_TCP;
146 /* Initialise the code for the GSM interface. */
148 if (error == GE_NOLINK)
149 error = GSM_Initialise (smsdConfig.model, smsdConfig.port,
150 smsdConfig.initlength, connection, NULL, &sm);
153 g_print ("fbusinit: error %d\n", error);
156 if (error != GE_NONE) {
157 g_print (_("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
161 while (count++ < 40 && *GSM_LinkOK == false)
164 g_print("After usleep. GSM_LinkOK: %d\n", *GSM_LinkOK);
167 if (*GSM_LinkOK != true) {
176 void InitPhoneMonitor (void)
178 phoneMonitor.phone.model = g_strdup (_("unknown"));
179 phoneMonitor.phone.version = phoneMonitor.phone.model;
180 phoneMonitor.phone.revision = g_strdup (_("unknown"));
181 phoneMonitor.phone.imei = g_strdup (_("unknown"));
182 phoneMonitor.supported = 0;
183 phoneMonitor.working = FALSE;
184 phoneMonitor.sms.unRead = phoneMonitor.sms.used = phoneMonitor.sms.slots = 0;
185 phoneMonitor.sms.messages = NULL;
186 pthread_mutex_init (&smsMutex, NULL);
187 pthread_cond_init (&smsCond, NULL);
188 pthread_mutex_init (&sendSMSMutex, NULL);
189 pthread_cond_init (&sendSMSCond, NULL);
190 pthread_mutex_init (&eventsMutex, NULL);
194 static inline void FreeElement (gpointer data, gpointer userData)
196 g_free ((GSM_SMSMessage *) data);
200 static inline void FreeArray (GSList **array)
204 g_slist_foreach (*array, FreeElement, NULL);
205 g_slist_free (*array);
211 static void RefreshSMS (const gint slots)
219 g_print ("RefreshSMS is running...\n");
222 pthread_mutex_lock (&smsMutex);
223 FreeArray (&(phoneMonitor.sms.messages));
224 phoneMonitor.sms.used = 0;
225 // pthread_mutex_unlock (&smsMutex);
227 for (i=1; i<=slots; i++)
229 msg = g_malloc (sizeof (GSM_SMSMessage));
230 msg->MemoryType = GMT_SM;
233 if ((error = GSM->GetSMSMessage (msg)) == GE_NONE)
235 // pthread_mutex_lock (&smsMutex);
236 phoneMonitor.sms.messages = g_slist_append (phoneMonitor.sms.messages, msg);
237 phoneMonitor.sms.used++;
238 if (msg->Type == GST_MT && msg->Status == GSS_NOTSENTREAD)
240 // pthread_mutex_unlock (&smsMutex);
242 else if (error == GE_INVALIDSMSLOCATION) /* All positions are readed */
250 /* FIXME: Why is any delay here?
252 /* usleep (750000); */
254 /* Update it after the whole run as otherwise "Refreshing SMSes..."
255 * would collide with "Short Message received" message.
257 phoneMonitor.sms.unRead = unread;
259 pthread_cond_signal (&smsCond);
260 pthread_mutex_unlock (&smsMutex);
264 static gint A_SendSMSMessage (gpointer data)
266 D_SMSMessage *d = (D_SMSMessage *) data;
269 error = d->status = GE_UNKNOWN;
272 pthread_mutex_lock (&sendSMSMutex);
273 error = d->status = GSM->SendSMSMessage (d->sms);
274 pthread_cond_signal (&sendSMSCond);
275 pthread_mutex_unlock (&sendSMSMutex);
278 if (d->status == GE_SMSSENDOK)
285 static gint A_DeleteSMSMessage (gpointer data)
287 GSM_SMSMessage *sms = (GSM_SMSMessage *) data;
288 GSM_Error error = GE_UNKNOWN;
292 error = GSM->DeleteSMSMessage(sms);
293 // I don't use copy, I don't need free message.
301 static gint A_Exit (gpointer data)
304 return (0); /* just to be proper */
308 gint (*DoAction[])(gpointer) = {
315 void *Connect (void *a)
317 GSM_SMSStatus SMSStatus = {0, 0, 0};
323 g_print ("Initializing connection...\n");
326 while (fbusinit (true))
330 g_print ("Phone connected. Starting monitoring...\n");
335 phoneMonitor.working = FALSE;
337 if (GSM->GetSMSStatus (&SMSStatus) == GE_NONE)
339 /* Change of "UnRead" shouldn't be interesting - user may have read some of his
340 * SMSes by the phone interface.
342 if (phoneMonitor.sms.unRead != SMSStatus.UnRead ||
343 phoneMonitor.sms.used != SMSStatus.Used ||
344 phoneMonitor.sms.slots != SMSStatus.Slots) /* shouldn't change, just to be sure */
346 /* We are primarily interested in SMSStatus.Slots so try to fix it up if it is broken
348 if (SMSStatus.UnRead > SMSStatus.Used)
349 SMSStatus.Used = SMSStatus.UnRead;
350 if (SMSStatus.Used > SMSStatus.Slots)
351 SMSStatus.Slots = SMSStatus.Used;
352 phoneMonitor.sms.slots = SMSStatus.Slots; /* shouldn't change, just to be sure */
353 /* phoneMonitor.sms.{unRead,used} will be updated by RefreshSMS()
356 phoneMonitor.working = TRUE;
357 RefreshSMS (SMSStatus.Slots);
358 phoneMonitor.working = FALSE;
361 phoneMonitor.sms.unRead = SMSStatus.UnRead;
364 while ((event = RemoveEvent ()) != NULL)
367 g_print ("Processing Event: %d\n", event->event);
369 phoneMonitor.working = TRUE;
370 if (event->event <= Event_Exit)
371 if (((error = DoAction[event->event] (event->data)) != GE_NONE) && error != GE_SMSSENDOK)
372 g_print (_("Event %d failed with return code %d!\n"), event->event, error);