This commit was generated by cvs2svn to compensate for changes in r158,
[gnokii.git] / smsd / smsd.c
1 /*
2
3   S M S D
4
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>.
8
9   Released under the terms of the GNU GPL, see file COPYING for more details.
10
11   Last modification: Sun Dec 17 2000
12   Modified by Jan Derfinak
13
14 */
15
16 #include <string.h>
17 #include <pthread.h>
18 #include <getopt.h>
19
20 #ifndef WIN32
21 # include <unistd.h>  /* for usleep */
22 # include <signal.h>
23 #else
24 # include <windows.h>
25 # include "../win32/winserial.h"
26 # define WRITEPHONE(a, b, c) WriteCommBlock(b, c)
27 # undef IN
28 # undef OUT
29 # define sleep(x) Sleep((x) * 1000)
30 # define usleep(x) Sleep(((x) < 1000) ? 1 : ((x) / 1000))
31 #endif
32
33 #include <glib.h>
34
35 #include "misc.h"
36
37 #include "gsm-common.h"
38 #include "gsm-api.h"
39 #include "fbus-6110.h"
40 #include "fbus-3810.h"
41 #include "cfgreader.h"
42 #include "smsd.h"
43 #include "lowlevel.h"
44 #include "db.h"
45
46 #define DB_CONNECT      "dbname=sms"
47
48  
49 /* Hold main configuration data for smsd */
50 SmsdConfig smsdConfig;
51
52 /* Global variables */
53 bool TerminateThread;
54
55 /* Local variables */
56 static gchar *connect;
57
58 static pthread_t db_monitor_th;
59 pthread_mutex_t db_monitorMutex;
60 static volatile bool db_monitor;
61
62 static void Usage (gchar *p)
63 {
64   g_print ("\nUsage:  %s [options]\n"
65            "            -d, --db     DBconnectInfo\n"
66            "            -h, --help\n", p);
67 }
68
69
70 static void ReadConfig (gint argc, gchar *argv[])
71 {
72   connect = g_strdup (DB_CONNECT);
73   while (1)
74   {
75     gint optionIndex = 0;
76     gchar c;
77     static struct option longOptions[] =
78     {
79       {"db", 1, 0, 'd'}
80     };
81     
82     c = getopt_long (argc, argv, "d:h", longOptions, &optionIndex);
83     if (c == EOF)
84       break;
85     switch (c)
86     {
87       case 'd':
88         g_free (connect);
89         connect = g_strdup (optarg);
90         memset (optarg, 'x', strlen (optarg));
91         break;
92
93         case 'h':
94         case '?':
95           Usage (argv[0]);
96           exit (1);
97           break;
98
99         default:
100           g_print ("getopt returned 0%o\n", c);
101     }
102   }
103   
104   if ((argc - optind) != 0)
105   {
106     g_print ("Wrong argument number!\n");
107     Usage (argv[0]);
108     exit (1);
109   }
110    
111   if (readconfig (&smsdConfig.model, &smsdConfig.port, &smsdConfig.initlength,
112       &smsdConfig.connection, &smsdConfig.bindir) < 0)
113     exit (-1);
114   
115   smsdConfig.smsSets = 0;
116 }
117
118
119
120 static void *SendSMS (void *a)
121 {
122   if (DB_ConnectOutbox (connect))
123   {
124     pthread_exit (0);
125     return (0);
126   }
127
128   while (1)
129   {
130     pthread_mutex_lock (&db_monitorMutex);
131     if (!db_monitor)
132     {
133       pthread_mutex_unlock (&db_monitorMutex);
134       pthread_exit (0);
135       return (0);
136     }
137     pthread_mutex_unlock (&db_monitorMutex);
138
139     DB_Look ();
140
141     sleep (3);
142   }
143 }
144
145
146 gint WriteSMS (GSM_SMSMessage *sms)
147 {
148   GSM_Error error;
149   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
150   D_SMSMessage *m = (D_SMSMessage *) g_malloc (sizeof (D_SMSMessage));
151
152   m->sms = sms;
153   e->event = Event_SendSMSMessage;
154   e->data = m;
155   InsertEvent (e);
156   pthread_mutex_lock (&sendSMSMutex);
157   pthread_cond_wait (&sendSMSCond, &sendSMSMutex);
158   pthread_mutex_unlock (&sendSMSMutex);
159
160 #ifdef XDEBUG
161   g_print ("Address: %s\nText: %s\n",
162   sms->Destination,
163   sms->MessageText);
164 #endif
165
166   error = m->status;
167   g_free (m);
168
169   return (error);
170 }
171
172 GSM_Error WriteSMS_deconcatenated(GSM_SMSMessage *sms,char *buf,size_t buflen,bool useudh)
173 {
174         GSM_Deconcatenate_state SMS_Deconcatenate_state;
175         GSM_Error error;
176
177         SMS_Deconcatenate_state.first=true;
178         while (SMS_Deconcatenate(&SMS_Deconcatenate_state,sms,buf,buflen,useudh)) {
179                 /* Send the message. */
180                 if (GE_SMSSENDOK != (error = WriteSMS(sms)))
181                         return(error);
182         }
183         return(GE_SMSSENDOK);
184 }
185
186 static void ReadSMS (gpointer d, gpointer userData)
187 {
188   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
189   PhoneEvent *e;
190   
191   if (data->Type == GST_MT || data->Type == GST_DR)
192   {
193     if (data->Type == GST_DR)
194     {
195 #ifdef XDEBUG
196       g_print ("Report\n");
197 #endif
198       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
199       e->event = Event_DeleteSMSMessage;
200       e->data = data;
201       InsertEvent (e);
202     }
203     else
204     { 
205 #ifdef XDEBUG 
206       g_print ("%d. %s   ", data->Location, data->Sender);
207       g_print ("%02d-%02d-%02d %02d:%02d:%02d+%02d %s\n", data->Time.Year + 2000,
208                data->Time.Month, data->Time.Day, data->Time.Hour,
209                data->Time.Minute, data->Time.Second, data->Time.Timezone,
210                data->MessageText);
211 #endif
212       DB_InsertSMS (data);
213       
214       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
215       e->event = Event_DeleteSMSMessage;
216       e->data = data;
217       InsertEvent (e);
218     }
219   }
220 }
221
222
223 static void GetSMS (void)
224 {
225   while (1)
226   {
227     pthread_mutex_lock (&smsMutex);
228     pthread_cond_wait (&smsCond, &smsMutex);
229
230     // Waiting for signal
231     pthread_mutex_unlock (&smsMutex);
232     // Signal arrived.
233     
234     pthread_mutex_lock (&smsMutex);
235     g_slist_foreach (phoneMonitor.sms.messages, ReadSMS, (gpointer) NULL);
236     pthread_mutex_unlock (&smsMutex);
237   }
238 }
239
240
241 static void MainExit (gint sig)
242 {
243   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
244
245   e->event = Event_Exit;
246   e->data = NULL;
247   InsertEvent (e);
248   
249   pthread_mutex_lock (&db_monitorMutex);
250   db_monitor = FALSE;
251   pthread_mutex_unlock (&db_monitorMutex);
252   
253   pthread_join (monitor_th, NULL);
254   pthread_join (db_monitor_th, NULL);
255   DB_Bye ();
256   exit (0);
257 }
258
259
260 static void Run (void)
261 {
262   struct sigaction act;
263   
264   act.sa_handler = MainExit;
265   sigemptyset (&(act.sa_mask));
266   
267   sigaction (SIGQUIT, &act, NULL);
268   sigaction (SIGTERM, &act, NULL);
269   sigaction (SIGINT, &act, NULL);
270
271 #if __unices__
272   act.sa_handler = SIG_IGN;
273   sigemptyset (&(act.sa_mask));
274   sigaction (SIGALRM, &act, NULL);
275 #endif
276
277   InitPhoneMonitor ();
278   if (DB_ConnectInbox (connect))
279     exit (2);
280   pthread_create (&monitor_th, NULL, Connect, NULL);
281   db_monitor = TRUE;
282   pthread_mutex_init (&db_monitorMutex, NULL);
283   pthread_create (&db_monitor_th, NULL, SendSMS, NULL);
284   GetSMS ();
285 }
286
287
288 int main (int argc, char *argv[])
289 {
290 #ifdef USE_NLS
291   textdomain("gnokii");
292 #endif
293
294   ReadConfig (argc, argv);
295   TerminateThread = false;
296   Run ();
297
298   return(0);
299 }