Update: orig2001_11_27_05_17 -> orig2001_12_04_22_45
[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 "phones/nk7110.h"
40 #include "phones/nk6100.h"
41 #include "phones/nk3110.h"
42 #include "phones/nk2110.h"
43 #include "cfgreader.h"
44 #include "smsd.h"
45 #include "lowlevel.h"
46 #include "db.h"
47
48 #define DB_CONNECT      "dbname=sms"
49
50  
51 /* Hold main configuration data for smsd */
52 SmsdConfig smsdConfig;
53
54 /* Global variables */
55 bool TerminateThread;
56
57 /* Local variables */
58 static gchar *connect;
59
60 static pthread_t db_monitor_th;
61 pthread_mutex_t db_monitorMutex;
62 static volatile bool db_monitor;
63
64 static void Usage (gchar *p)
65 {
66   g_print ("\nUsage:  %s [options]\n"
67            "            -d, --db     DBconnectInfo\n"
68            "            -h, --help\n", p);
69 }
70
71
72 static void ReadConfig (gint argc, gchar *argv[])
73 {
74   connect = g_strdup (DB_CONNECT);
75   while (1)
76   {
77     gint optionIndex = 0;
78     gchar c;
79     static struct option longOptions[] =
80     {
81       {"db", 1, 0, 'd'}
82     };
83     
84     c = getopt_long (argc, argv, "d:h", longOptions, &optionIndex);
85     if (c == EOF)
86       break;
87     switch (c)
88     {
89       case 'd':
90         g_free (connect);
91         connect = g_strdup (optarg);
92         memset (optarg, 'x', strlen (optarg));
93         break;
94
95         case 'h':
96         case '?':
97           Usage (argv[0]);
98           exit (1);
99           break;
100
101         default:
102           g_print ("getopt returned 0%o\n", c);
103     }
104   }
105   
106   if ((argc - optind) != 0)
107   {
108     g_print ("Wrong argument number!\n");
109     Usage (argv[0]);
110     exit (1);
111   }
112    
113   if (readconfig (&smsdConfig.model, &smsdConfig.port, &smsdConfig.initlength,
114       &smsdConfig.connection, &smsdConfig.bindir) < 0)
115     exit (-1);
116   
117   smsdConfig.smsSets = 0;
118 }
119
120
121
122 static void *SendSMS (void *a)
123 {
124   if (DB_ConnectOutbox (connect))
125   {
126     pthread_exit (0);
127     return (0);
128   }
129
130   while (1)
131   {
132     pthread_mutex_lock (&db_monitorMutex);
133     if (!db_monitor)
134     {
135       pthread_mutex_unlock (&db_monitorMutex);
136       pthread_exit (0);
137       return (0);
138     }
139     pthread_mutex_unlock (&db_monitorMutex);
140
141     DB_Look ();
142
143     sleep (3);
144   }
145 }
146
147
148 gint WriteSMS (GSM_SMSMessage *sms)
149 {
150   GSM_Error error;
151   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
152   D_SMSMessage *m = (D_SMSMessage *) g_malloc (sizeof (D_SMSMessage));
153
154   m->sms = sms;
155   e->event = Event_SendSMSMessage;
156   e->data = m;
157   InsertEvent (e);
158   pthread_mutex_lock (&sendSMSMutex);
159   pthread_cond_wait (&sendSMSCond, &sendSMSMutex);
160   pthread_mutex_unlock (&sendSMSMutex);
161
162 #ifdef XDEBUG
163   g_print ("Address: %s\nText: %s\n",
164   sms->Destination,
165   sms->MessageText);
166 #endif
167
168   error = m->status;
169   g_free (m);
170
171   return (error);
172 }
173
174
175 static void ReadSMS (gpointer d, gpointer userData)
176 {
177   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
178   PhoneEvent *e;
179   
180   if (data->Type == SMS_Deliver || data->Type == SMS_Delivery_Report)
181   {
182     if (data->Type == SMS_Delivery_Report)
183     {
184 #ifdef XDEBUG
185       g_print ("Report\n");
186 #endif
187       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
188       e->event = Event_DeleteSMSMessage;
189       e->data = data;
190       InsertEvent (e);
191     }
192     else
193     { 
194 #ifdef XDEBUG 
195       g_print ("%d. %s   ", data->Location, data->Sender);
196       g_print ("%02d-%02d-%02d %02d:%02d:%02d+%02d %s\n", data->Time.Year + 2000,
197                data->Time.Month, data->Time.Day, data->Time.Hour,
198                data->Time.Minute, data->Time.Second, data->Time.Timezone,
199                data->MessageText);
200 #endif
201       DB_InsertSMS (data);
202       
203       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
204       e->event = Event_DeleteSMSMessage;
205       e->data = data;
206       InsertEvent (e);
207     }
208   }
209 }
210
211
212 static void GetSMS (void)
213 {
214   while (1)
215   {
216     pthread_mutex_lock (&smsMutex);
217     pthread_cond_wait (&smsCond, &smsMutex);
218
219     // Waiting for signal
220     pthread_mutex_unlock (&smsMutex);
221     // Signal arrived.
222     
223     pthread_mutex_lock (&smsMutex);
224     g_slist_foreach (phoneMonitor.sms.messages, ReadSMS, (gpointer) NULL);
225     pthread_mutex_unlock (&smsMutex);
226   }
227 }
228
229
230 static void MainExit (gint sig)
231 {
232   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
233
234   e->event = Event_Exit;
235   e->data = NULL;
236   InsertEvent (e);
237   
238   pthread_mutex_lock (&db_monitorMutex);
239   db_monitor = FALSE;
240   pthread_mutex_unlock (&db_monitorMutex);
241   
242   pthread_join (monitor_th, NULL);
243   pthread_join (db_monitor_th, NULL);
244   DB_Bye ();
245   exit (0);
246 }
247
248
249 static void Run (void)
250 {
251   struct sigaction act;
252   
253   act.sa_handler = MainExit;
254   sigemptyset (&(act.sa_mask));
255   
256   sigaction (SIGQUIT, &act, NULL);
257   sigaction (SIGTERM, &act, NULL);
258   sigaction (SIGINT, &act, NULL);
259
260 #if __unices__
261   act.sa_handler = SIG_IGN;
262   sigemptyset (&(act.sa_mask));
263   sigaction (SIGALRM, &act, NULL);
264 #endif
265
266   InitPhoneMonitor ();
267   if (DB_ConnectInbox (connect))
268     exit (2);
269   pthread_create (&monitor_th, NULL, Connect, NULL);
270   db_monitor = TRUE;
271   pthread_mutex_init (&db_monitorMutex, NULL);
272   pthread_create (&db_monitor_th, NULL, SendSMS, NULL);
273   GetSMS ();
274 }
275
276
277 int main (int argc, char *argv[])
278 {
279 #ifdef USE_NLS
280   textdomain("gnokii");
281 #endif
282
283   ReadConfig (argc, argv);
284   TerminateThread = false;
285   Run ();
286
287   return(0);
288 }