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