LDFLAGS -> LDLIBS
[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
173 static void ReadSMS (gpointer d, gpointer userData)
174 {
175   GSM_SMSMessage *data = (GSM_SMSMessage *) d;
176   PhoneEvent *e;
177   
178   if (data->Type == GST_MT || data->Type == GST_DR)
179   {
180     if (data->Type == GST_DR)
181     {
182 #ifdef XDEBUG
183       g_print ("Report\n");
184 #endif
185       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
186       e->event = Event_DeleteSMSMessage;
187       e->data = data;
188       InsertEvent (e);
189     }
190     else
191     { 
192 #ifdef XDEBUG 
193       g_print ("%d. %s   ", data->Location, data->Sender);
194       g_print ("%02d-%02d-%02d %02d:%02d:%02d+%02d %s\n", data->Time.Year + 2000,
195                data->Time.Month, data->Time.Day, data->Time.Hour,
196                data->Time.Minute, data->Time.Second, data->Time.Timezone,
197                data->MessageText);
198 #endif
199       DB_InsertSMS (data);
200       
201       e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
202       e->event = Event_DeleteSMSMessage;
203       e->data = data;
204       InsertEvent (e);
205     }
206   }
207 }
208
209
210 static void GetSMS (void)
211 {
212   while (1)
213   {
214     pthread_mutex_lock (&smsMutex);
215     pthread_cond_wait (&smsCond, &smsMutex);
216
217     // Waiting for signal
218     pthread_mutex_unlock (&smsMutex);
219     // Signal arrived.
220     
221     pthread_mutex_lock (&smsMutex);
222     g_slist_foreach (phoneMonitor.sms.messages, ReadSMS, (gpointer) NULL);
223     pthread_mutex_unlock (&smsMutex);
224   }
225 }
226
227
228 static void MainExit (gint sig)
229 {
230   PhoneEvent *e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent));
231
232   e->event = Event_Exit;
233   e->data = NULL;
234   InsertEvent (e);
235   
236   pthread_mutex_lock (&db_monitorMutex);
237   db_monitor = FALSE;
238   pthread_mutex_unlock (&db_monitorMutex);
239   
240   pthread_join (monitor_th, NULL);
241   pthread_join (db_monitor_th, NULL);
242   DB_Bye ();
243   exit (0);
244 }
245
246
247 static void Run (void)
248 {
249   struct sigaction act;
250   
251   act.sa_handler = MainExit;
252   sigemptyset (&(act.sa_mask));
253   
254   sigaction (SIGQUIT, &act, NULL);
255   sigaction (SIGTERM, &act, NULL);
256   sigaction (SIGINT, &act, NULL);
257
258 #if __unices__
259   act.sa_handler = SIG_IGN;
260   sigemptyset (&(act.sa_mask));
261   sigaction (SIGALRM, &act, NULL);
262 #endif
263
264   InitPhoneMonitor ();
265   if (DB_ConnectInbox (connect))
266     exit (2);
267   pthread_create (&monitor_th, NULL, Connect, NULL);
268   db_monitor = TRUE;
269   pthread_mutex_init (&db_monitorMutex, NULL);
270   pthread_create (&db_monitor_th, NULL, SendSMS, NULL);
271   GetSMS ();
272 }
273
274
275 int main (int argc, char *argv[])
276 {
277 #ifdef USE_NLS
278   textdomain("gnokii");
279 #endif
280
281   ReadConfig (argc, argv);
282   TerminateThread = false;
283   Run ();
284
285   return(0);
286 }