1 /* -------------------------------------------------------------------- */
2 /* SMS Client, send messages to mobile phones and pagers */
3 /* */
4 /* driver.c */
5 /* */
6 /* Copyright (C) 1997,1998,1999 Angelo Masci */
7 /* */
8 /* This library is free software; you can redistribute it and/or */
9 /* modify it under the terms of the GNU Library General Public */
10 /* License as published by the Free Software Foundation; either */
11 /* version 2 of the License, or (at your option) any later version. */
12 /* */
13 /* This library is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* Library General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU Library General Public */
19 /* License along with this library; if not, write to the Free */
20 /* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* */
22 /* You can contact the author at this e-mail address: */
23 /* */
24 /* angelo@styx.demon.co.uk */
25 /* */
26 /* -------------------------------------------------------------------- */
27 /* $Id: driver.c,v 5.1 1998/02/01 07:10:39 root Exp $
28 -------------------------------------------------------------------- */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <ctype.h>
33
34 #if defined(MODEMLIB) && (MODEMLIB == LIBMODEM)
35 #include <termios.h>
36 #include <dial/modems.h>
37 #else
38 #include "comms/comms.h"
39 #endif
40
41 #include "common/common.h"
42 #include "logfile/logfile.h"
43 #include "driver.h"
44 #include "driver_comms.h"
45 #include "error.h"
46 #include "parser/gs_translate.h"
47
48 /* -------------------------------------------------------------------- */
49
50 #if !defined(MSERVICEDIR)
51 #error "MSERVICEDIR undefined"
52 #else
53 #define SERVICEDIR MSERVICEDIR
54 #endif
55
56 /* -------------------------------------------------------------------- */
57 /* The 'device_list' is simply and array of pointer to device entry */
58 /* structures. If you write a new device you MUST add it's */
59 /* device structure to this list. */
60 /* -------------------------------------------------------------------- */
61
62 DEVICE_ENTRY *device_list[] = {
63 #if defined(TAP)
64 &tap_device,
65 #endif
66 #if defined(VODAFONE)
67 &vodafone_device,
68 #endif
69 #if defined(ORANGE)
70 &orange_device,
71 #endif
72 #if defined(PAGEONE)
73 &pageone_device,
74 #endif
75 #if defined(VODACOM)
76 &vodacom_device,
77 #endif
78 #if defined(MTN)
79 &mtn_device,
80 #endif
81 #if defined(ONE2ONE)
82 &one2one_device,
83 #endif
84 #if defined(LIBERTEL)
85 &libertel_device,
86 #endif
87 #if defined(TIM)
88 &tim_device,
89 #endif
90 #if defined(SNPP)
91 &snpp_device,
92 #endif
93 #if defined(CIMD)
94 &cimd_device,
95 #endif
96 #if defined(VODAPAGE_BLOCK)
97 &vodapage_block_device,
98 #endif
99 #if defined(PROXIMUS)
100 &proximus_device,
101 #endif
102 #if defined(KPN)
103 &kpn_device,
104 #endif
105 #if defined(ANSWER)
106 &answer_device,
107 #endif
108 #if defined(GENERIC)
109 &generic_device,
110 #endif
111 #if defined(UCP)
112 &ucp_device,
113 #endif
114 #if defined(UCP_TCP)
115 &ucp_tcp_device,
116 #endif
117 #if defined(WWW)
118 &www_device,
119 #endif
120 #if defined(ORANGE_WEB)
121 &orange_web_device,
122 #endif
123 #if defined(LYCOS_WEB)
124 &lycos_web_device,
125 #endif
126 #if defined(CELLNET_WEB)
127 &cellnet_web_device,
128 #endif
129 #if defined(PROXIMUS_WEB)
130 &proximus_web_device,
131 #endif
132 #if defined(ATT_WEB)
133 &att_web_device,
134 #endif
135 #if defined(NEXTEL_WEB)
136 &nextel_web_device,
137 #endif
138 #if defined(PAGENET_WEB)
139 &pagenet_web_device,
140 #endif
141 #if defined(MOBISTAR)
142 &mobistar_device,
143 #endif
144 NULL
145 };
146
147 /* -------------------------------------------------------------------- */
148 /* Return a device entry structure by supplying its name. */
149 /* -------------------------------------------------------------------- */
get_device(char * name)150 DEVICE_ENTRY *get_device(char *name)
151 {
152 DEVICE_ENTRY **device;
153
154
155 if (name == NULL)
156 { return NULL;
157 }
158
159
160 device = device_list;
161
162 while (*device != NULL)
163 {
164 if ((*device)->name != NULL)
165 { if (strcmp((*device)->name, name) == 0)
166 {
167 lprintf(LOG_VERBOSE, "Device Found: %s\n", name);
168 return *device;
169 }
170 }
171
172 device++;
173 }
174
175 lprintf(LOG_VERBOSE, "Device NOT Found: %s\n", name);
176 return NULL;
177 }
178
179
180 /* -------------------------------------------------------------------- */
181 /* List all the device entries currently compiled in. */
182 /* -------------------------------------------------------------------- */
display_drivers(void)183 void display_drivers(void)
184 {
185 DEVICE_ENTRY **device;
186
187
188 device = device_list;
189
190 if (*device == NULL)
191 { lprintf(LOG_WARNING, "No drivers have been included!\n");
192 }
193
194 while (*device != NULL)
195 {
196 lprintf(LOG_STANDARD, "%s %s\n",
197 ((*device)->name != NULL)?(*device)->name:"<NULL>",
198 ((*device)->version_string != NULL)?(*device)->version_string:"<NULL>");
199
200 device++;
201 }
202 }
203
204
205 /* -------------------------------------------------------------------- */
206 /* -------------------------------------------------------------------- */
default_dial(DRIVER_DEFAULT_ENV * env)207 int default_dial(DRIVER_DEFAULT_ENV *env)
208 {
209 lprintf(LOG_STANDARD, "Dialing SMSC %s...\n", env->centre_number);
210
211 env->fd = SMS_dial(env->centre_number, env->comms_params, env->baud);
212 if (env->fd < 0)
213 { lprintf(LOG_WARNING, "Failed to connect\n");
214 return EDIAL;
215 }
216
217 lprintf(LOG_STANDARD, "Connection Established.\n");
218 return 0;
219 }
220
221
222 /* -------------------------------------------------------------------- */
223 /* -------------------------------------------------------------------- */
default_tcpip_connect(DRIVER_DEFAULT_ENV * env)224 int default_tcpip_connect(DRIVER_DEFAULT_ENV *env)
225 {
226 lprintf(LOG_STANDARD, "Connecting to Server %s:%ld...\n",
227 env->server_name,
228 env->server_port);
229
230 env->fd = TCPIP_connect(env->server_name,
231 env->server_port);
232 if (env->fd < 0)
233 { lprintf(LOG_WARNING, "Failed to Connect.\n");
234 return EDIAL;
235 }
236
237 lprintf(LOG_STANDARD, "Connection Established.\n");
238 return 0;
239 }
240
241
242 /* -------------------------------------------------------------------- */
243 /* -------------------------------------------------------------------- */
default_tcpip_disconnect(DRIVER_DEFAULT_ENV * env)244 void default_tcpip_disconnect(DRIVER_DEFAULT_ENV *env)
245 {
246 lprintf(LOG_STANDARD, "Disconnecting...\n");
247 TCPIP_disconnect(env->fd);
248 }
249
250
251 /* -------------------------------------------------------------------- */
252 /* -------------------------------------------------------------------- */
default_hangup(DRIVER_DEFAULT_ENV * env)253 void default_hangup(DRIVER_DEFAULT_ENV *env)
254 {
255 lprintf(LOG_STANDARD, "Hangup...\n");
256 SMS_hangup(env->fd);
257
258 env->connection_status = SERVICE_NOT_CONNECTED;
259 }
260
261 /* -------------------------------------------------------------------- */
262 /* -------------------------------------------------------------------- */
default_main(void * list,void * (* get_first)(void * list),void * (* get_next)(void * list),char * (* get_number)(void * node),char * (* get_message)(void * node),void (* set_delivery)(void * node,int result),DRIVER_DEFAULT_ENV * env)263 void default_main(void *list,
264 void *(* get_first)(void *list),
265 void *(* get_next)(void *list),
266 char *(* get_number)(void *node),
267 char *(* get_message)(void *node),
268 void (* set_delivery)(void *node, int result),
269 DRIVER_DEFAULT_ENV *env)
270 {
271 void *node;
272 char *msisdn,
273 *message;
274 int result;
275
276
277 lprintf(LOG_VERBOSE, "%s %s driver called\n",
278 (env->device->name != NULL)?env->device->name:"<NULL>",
279 (env->device->version_string != NULL)?env->device->version_string:"<NULL>");
280
281
282
283 env->connection_status = SERVICE_NOT_CONNECTED;
284 result = 0;
285
286 node = (* get_first)(list);
287 while (node != NULL)
288 {
289 msisdn = (* get_number)(node);
290 message = (* get_message)(node);
291
292
293 result = (* env->device->deliver)(msisdn, message, env);
294 (* set_delivery)(node, result);
295
296 if (result)
297 { (* env->device->hangup)(env);
298
299 env->connection_status = SERVICE_NOT_CONNECTED;
300 }
301
302 node = (* get_next)(node);
303 }
304
305 if ((result == 0) && (env->connection_status == SERVICE_CONNECTED))
306 {
307 (* env->device->disconnect)();
308 (* env->device->hangup)(env);
309
310 env->connection_status = SERVICE_NOT_CONNECTED;
311 }
312 }
313
314 /* -------------------------------------------------------------------- */
315 /* -------------------------------------------------------------------- */
default_multiple_deliver(char * msisdn,char * message,DRIVER_DEFAULT_ENV * env)316 int default_multiple_deliver(char *msisdn, char *message, DRIVER_DEFAULT_ENV *env)
317 {
318 int error;
319
320
321 if (env->connection_status == SERVICE_NOT_CONNECTED)
322 {
323 env->connection_status = SERVICE_CONNECTED;
324
325 error = (* env->device->dial)(env);
326 if (error)
327 { return error;
328 }
329
330 error = (* env->device->login)();
331 if (error)
332 { return error;
333 }
334 }
335
336 error = (* env->device->sendmessage)(msisdn, message);
337 if (error)
338 { return error;
339 }
340
341 return 0;
342 }
343
344 /* -------------------------------------------------------------------- */
345 /* Send as many messages as we are allowed. */
346 /* Keep track of number of messages sent and compare against */
347 /* Max allowed, disconnecting when number sent reaches */
348 /* the max allowed. */
349 /* -------------------------------------------------------------------- */
default_multiple_counted_deliver(char * msisdn,char * message,DRIVER_DEFAULT_ENV * env)350 int default_multiple_counted_deliver(char *msisdn, char *message, DRIVER_DEFAULT_ENV *env)
351 {
352 int error;
353
354
355 if (env->connection_status == SERVICE_NOT_CONNECTED)
356 {
357 env->num_sent = 0;
358 env->connection_status = SERVICE_CONNECTED;
359
360 error = (* env->device->dial)(env);
361 if (error)
362 { return error;
363 }
364
365 error = (* env->device->login)();
366 if (error)
367 { return error;
368 }
369 }
370
371 error = (* env->device->sendmessage)(msisdn, message);
372 if (error)
373 { return error;
374 }
375
376
377 env->num_sent++;
378
379 lprintf(LOG_VERBOSE, "Num sent = %ld\n", env->num_sent);
380 lprintf(LOG_VERBOSE, "Max deliver = %ld\n", env->max_deliver);
381
382 if ((env->max_deliver != 0) &&
383 (env->num_sent >= env->max_deliver))
384 {
385 (* env->device->disconnect)();
386 (* env->device->hangup)(env);
387
388 env->connection_status = SERVICE_NOT_CONNECTED;
389 }
390
391 return 0;
392 }
393
394 /* -------------------------------------------------------------------- */
395 /* -------------------------------------------------------------------- */
default_send_disconnect(void)396 int default_send_disconnect(void)
397 { return 0;
398 }
399
400 /* -------------------------------------------------------------------- */
401 /* -------------------------------------------------------------------- */
default_single_deliver(char * msisdn,char * message,DRIVER_DEFAULT_ENV * env)402 int default_single_deliver(char *msisdn, char *message, DRIVER_DEFAULT_ENV *env)
403 {
404 int error;
405
406
407 env->connection_status = SERVICE_CONNECTED;
408
409 error = (* env->device->dial)(env);
410 if (error)
411 { return error;
412 }
413
414 error = (* env->device->login)();
415 if (error)
416 { return error;
417 }
418
419 error = (* env->device->sendmessage)(msisdn, message);
420 if (error)
421 { return error;
422 }
423
424 (* env->device->disconnect)();
425 (* env->device->hangup)(env);
426
427 env->connection_status = SERVICE_NOT_CONNECTED;
428 return 0;
429 }
430
431 /* -------------------------------------------------------------------- */
432 /* -------------------------------------------------------------------- */
default_validate_numeric_id(char * ptr)433 int default_validate_numeric_id(char *ptr)
434 {
435 while (*ptr != '\0')
436 {
437 if (!isdigit(*ptr))
438 { return FALSE;
439 }
440
441 ptr++;
442 }
443
444 return TRUE;
445 }
446
447 /* -------------------------------------------------------------------- */
448 /* -------------------------------------------------------------------- */
default_validate_always_true(char * id)449 int default_validate_always_true(char *id)
450 { return TRUE;
451 }
452
453 /* -------------------------------------------------------------------- */
454 /* -------------------------------------------------------------------- */
default_init(char * mservice,DEVICE_ENTRY * device)455 int default_init(char *mservice, DEVICE_ENTRY *device)
456 {
457 char fname[1024];
458
459 strcpy(fname, SERVICEDIR);
460 libcommon_strfcat(fname, "services");
461 libcommon_strfcat(fname, mservice);
462
463 if (read_resource_file(fname, device->resource_list, TRUE) != RESOURCE_FILE_OK)
464 {
465 lprintf(LOG_ERROR, "Unrecoverable Failure Parsing file '%s'\n", fname);
466 return -1;
467 }
468
469 device->env->device = device;
470 return 0;
471 }
472
473 /* -------------------------------------------------------------------- */
474 /* -------------------------------------------------------------------- */
default_login(void)475 int default_login(void)
476 { return 0;
477 }
478
479 /* -------------------------------------------------------------------- */
480 /* -------------------------------------------------------------------- */
default_sendmessage(char * msisdn,char * message)481 int default_sendmessage(char *msisdn, char *message)
482 { return 0;
483 }
484
485 /* -------------------------------------------------------------------- */
486 /* Search 'sms_services' for 'service' and return 'protocol' */
487 /* -------------------------------------------------------------------- */
get_protocol(char * service)488 char *get_protocol(char *service)
489 {
490 char fname[1024],
491 *protocol;
492
493 TOKEN_HEAP
494 *heap;
495
496 strcpy(fname, SERVICEDIR);
497 libcommon_strfcat(fname, "sms_services");
498
499 heap = gs_parse_file(fname);
500 if (heap == NULL)
501 {
502 lprintf(LOG_ERROR, "Parsing file '%s'\n", fname);
503 exit(-1);
504 }
505
506 protocol = get_strvalue(heap, service);
507 if (protocol == NULL)
508 {
509 lprintf(LOG_VERBOSE, "Service '%s' Not Found\n", service);
510
511 free_heap(heap);
512 return NULL;
513 }
514
515 lprintf(LOG_VERBOSE, "Service '%s' using protocol '%s'\n", service, protocol);
516 return strdup(protocol);
517 }
518
519
520