/* -------------------------------------------------------------------- */ /* SMS Client, send messages to mobile phones and pagers */ /* */ /* generic.c */ /* */ /* Copyright (C) 1998,1999 Angelo Masci */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Library General Public */ /* License as published by the Free Software Foundation; either */ /* version 2 of the License, or (at your option) any later version. */ /* */ /* This library is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ /* Library General Public License for more details. */ /* */ /* You should have received a copy of the GNU Library General Public */ /* License along with this library; if not, write to the Free */ /* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* */ /* You can contact the author at this e-mail address: */ /* */ /* angelo@styx.demon.co.uk */ /* */ /* -------------------------------------------------------------------- */ /* $Id$ -------------------------------------------------------------------- */ #include #include #include "common/common.h" #include "logfile/logfile.h" #include "driver.h" #include "error.h" #include "resource/resource.h" #include "comms/comms.h" #include "gs_token.h" #include "gs_translate.h" /* -------------------------------------------------------------------- */ #if !defined(MSERVICEDIR) #error "MSERVICEDIR undefined" #else #define SERVICEDIR MSERVICEDIR #endif /* -------------------------------------------------------------------- */ /* The 'env' structure contains Service level data to be used for */ /* sending a message. */ /* -------------------------------------------------------------------- */ static struct generic_env { DRIVER_DEFAULT_ENV def; /* Place any extended driver */ /* variables here */ TOKEN_HEAP *heap; char *script_file, *dialer; } driver_env; /* -------------------------------------------------------------------- */ static RESOURCE resource_list[] = { { RESOURCE_STRING, "SMS_comms_params", 0, 1, NULL, 0, "8N1", 0, &(driver_env.def.comms_params) }, { RESOURCE_STRING, "SMS_centre_number", 0, 1, NULL, 0, NULL, 0, &(driver_env.def.centre_number) }, { RESOURCE_NUMERIC, "SMS_baud", 0, 1, NULL, 0, NULL, 1200, &(driver_env.def.baud) }, { RESOURCE_NUMERIC, "SMS_deliver_timeout", 0, 0, NULL, 0, NULL, 30, &(driver_env.def.deliver_timeout) }, { RESOURCE_NUMERIC, "SMS_timeout", 0, 0, NULL, 0, NULL, 10, &(driver_env.def.timeout) }, { RESOURCE_NUMERIC, "SMS_write_timeout", 0, 0, NULL, 0, NULL, 10, &(driver_env.def.write_timeout) }, { RESOURCE_NUMERIC, "SMS_max_deliver", 0, 0, NULL, 0, NULL, 0, &(driver_env.def.max_deliver) }, { RESOURCE_STRING, "SMS_dialer", 0, 1, NULL, 0, "tcpip", 0, &(driver_env.dialer) }, { RESOURCE_STRING, "SMS_script_file", 0, 1, NULL, 0, NULL, 0, &(driver_env.script_file) }, { RESOURCE_STRING, "SMS_server_name", 0, 1, NULL, 0, "localhost", 0, &(driver_env.def.server_name) }, { RESOURCE_NUMERIC, "SMS_server_port", 0, 1, NULL, 0, NULL, 444, &(driver_env.def.server_port) }, { RESOURCE_NULL, NULL, 0, 1, NULL, 0, NULL, 0, NULL } }; /* -------------------------------------------------------------------- */ #define DELIVERTIMEOUT (driver_env.def.deliver_timeout) #define TIMEOUT (driver_env.def.timeout) #define WRITETIMEOUT (driver_env.def.write_timeout) /* -------------------------------------------------------------------- */ #define FD (driver_env.def.fd) #define SCRIPT_FILE (driver_env.script_file) /* -------------------------------------------------------------------- */ /* The following defines are used to signify errors */ /* occuring during the dialogue between the driver and the */ /* service centre. This number will be returned as the delivery */ /* value for the message that was aborted */ /* */ /* The defines MUST be placed in 'error.h' */ #define EGENERIC_NONUMBER 250 #define EGENERIC_NOMESSAGE 251 #define EGENERIC_NODELIVERY 252 /* -------------------------------------------------------------------- */ static char *generic_message = NULL, *generic_id = NULL; /* -------------------------------------------------------------------- */ static void GENERIC_hangup(void); static int GENERIC_login(void); static int GENERIC_send_disconnect(void); static int GENERIC_sendmessage(char *msisdn, char *message); static int GENERIC_dial(DRIVER_DEFAULT_ENV *env); static void GENERIC_wrapper_hangup(DRIVER_DEFAULT_ENV *env); static int using_modem_dialer(void); static int using_tcpip_dialer(void); /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int using_modem_dialer(void) { return (strcmp(driver_env.dialer, "modem") == 0); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int using_tcpip_dialer(void) { return (strcmp(driver_env.dialer, "tcpip") == 0); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int GENERIC_dial(DRIVER_DEFAULT_ENV *env) { if (using_modem_dialer()) { return default_dial(env); } else if (using_tcpip_dialer()) { return default_tcpip_connect(env); } else { lprintf(LOG_ERROR, "dial() failed, using unsupported dialer '%s'\n", driver_env.dialer); return -1; } lprintf(LOG_STANDARD, "Connection Established.\n"); return 0; } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ int GENERIC_init(char *mservice, DEVICE_ENTRY *device) { if (default_init(mservice, device) == -1) { return -1; } if (SCRIPT_FILE == NULL) { lprintf(LOG_ERROR, "Failed to initialize driver\n"); return -1; } driver_env.heap = gs_parse_file(SCRIPT_FILE); if (driver_env.heap == NULL) { lprintf(LOG_ERROR, "Unrecoverable Failure Parsing file '%s'\n", SCRIPT_FILE); return -1; } return 0; } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int process_list(TOKEN_HEAP *current_heap) { int i, j; char *str, buf[1024]; TOKEN_HEAP *tmp_heap, *heap; i = 0; while(TRUE) { heap = get_varlist_element(current_heap, i); if (heap == NULL) { return 0; } str = get_strvalue(heap, "message"); if (str != NULL) { if (strlen(str) != 0) { lprintf(LOG_STANDARD, str); } } tmp_heap = get_varlist(heap, "send"); if (tmp_heap == NULL) { str = get_strvalue(heap, "send"); if (str != NULL) { if (strlen(str) != 0) { if (strcmp(str, "$MSG$") == 0) { if (generic_message != NULL) { twrite(FD, generic_message, strlen(generic_message), WRITETIMEOUT); } } else if (strcmp(str, "$ID$") == 0) { if (generic_id != NULL) { twrite(FD, generic_id, strlen(generic_id), WRITETIMEOUT); } } else { twrite(FD, str, strlen(str), WRITETIMEOUT); } } } } else { j = 0; while((str = get_strvalue_element(tmp_heap, j)) != NULL) { if (str != NULL) { if (strlen(str) != 0) { if (strcmp(str, "$MSG$") == 0) { if (generic_message != NULL) { twrite(FD, generic_message, strlen(generic_message), WRITETIMEOUT); } } else if (strcmp(str, "$ID$") == 0) { if (generic_id != NULL) { twrite(FD, generic_id, strlen(generic_id), WRITETIMEOUT); } } else { twrite(FD, str, strlen(str), WRITETIMEOUT); } } } j++; } } str = get_strvalue(heap, "expect"); if (str != NULL) { if (expstr(FD, buf, str, 1024, TIMEOUT) == 0) { tmp_heap = get_varlist(heap, "success"); if (tmp_heap == NULL) { str = get_strvalue(heap, "success"); if (str != NULL) { lprintf(LOG_STANDARD, str); } } else { if (process_list(tmp_heap)) { return -1; } } } else { tmp_heap = get_varlist(heap, "failure"); if (tmp_heap == NULL) { str = get_strvalue(heap, "failure"); if (str != NULL) { lprintf(LOG_STANDARD, str); } return -1; } else { if (process_list(tmp_heap)) { return -1; } } } } i++; } } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int process_script_list(TOKEN_HEAP *current_heap, char *listname) { TOKEN_HEAP *heap; heap = get_varlist(current_heap, listname); if (heap == NULL) { return 0; } return process_list(heap); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int GENERIC_login(void) { return process_script_list(driver_env.heap, "login"); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int GENERIC_sendmessage(char *msisdn, char *message) { generic_message = message; generic_id = msisdn; return process_script_list(driver_env.heap, "send"); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static int GENERIC_send_disconnect(void) { return process_script_list(driver_env.heap, "disconnect"); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static void GENERIC_hangup(void) { if (using_modem_dialer()) { default_hangup((DRIVER_DEFAULT_ENV *)(&driver_env)); } else if (using_tcpip_dialer()) { TCPIP_disconnect(FD); } else { lprintf(LOG_ERROR, "hangup() failed, using unsupported dialer '%s'\n", driver_env.dialer); } } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ static void GENERIC_wrapper_hangup(DRIVER_DEFAULT_ENV *env) { GENERIC_hangup(); } /* -------------------------------------------------------------------- */ /* The following structure is used by core driver code. */ /* The diagram below shows the call sequence of the functions. */ /* -------------------------------------------------------------------- */ DEVICE_ENTRY generic_device = { "GENERIC", "1.0", resource_list, (DRIVER_DEFAULT_ENV *)(&driver_env), GENERIC_init, /* Init */ default_main, /* Main */ default_validate_always_true, /* Validation */ GENERIC_dial, /* Dial */ GENERIC_wrapper_hangup, /* Hangup */ GENERIC_send_disconnect, /* Disconnect */ default_single_deliver, /* Deliver */ GENERIC_sendmessage, /* Send */ GENERIC_login /* Login */ };