Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
smsc_soap.c File Reference
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <limits.h>
#include "gwlib/gwlib.h"
#include "gwlib/http.h"
#include "smscconn.h"
#include "smscconn_p.h"
#include "bb_smscconn_cb.h"
#include "msg.h"
#include "sms.h"
#include "dlr.h"
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include "msg-decl.h"

Go to the source code of this file.

Data Structures

struct  privdata
 
struct  client_data
 
struct  argument_map
 

Macros

#define SOAP_SLEEP_TIME   0.01
 
#define SOAP_MAX_MESSAGE_PER_ROUND   1
 
#define SOAP_DEFAULT_SENDER_STRING   "Kannel"
 
#define SOAP_DEFAULT_VALIDITY   60
 
#define SOAP_MO_URI   "/mo"
 
#define SOAP_DLR_URI   "/dlr"
 
#define SOAP_DEFAULT_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>No method by that name</Error>"
 
#define SOAP_ERROR_NO_DLR_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Sorry - no DLR for that MT</Error>"
 
#define SOAP_ERROR_DLR_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Fatal error while trying to parse delivery report</Error>"
 
#define SOAP_ERROR_MO_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Fatal error while trying to parse incoming MO</Error>"
 
#define SOAP_ERROR_NO_DATA_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>No data received</Error>"
 
#define SOAP_ERROR_MALFORMED_DATA_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Malformed data received</Error>"
 
#define SOAP_ERROR_NO_DLR_CODE   HTTP_BAD_METHOD
 
#define SOAP_DEFAULT_CODE   HTTP_NOT_FOUND
 
#define SOAP_ERROR_DLR_CODE   HTTP_INTERNAL_SERVER_ERROR
 
#define SOAP_ERROR_MO_CODE   HTTP_INTERNAL_SERVER_ERROR
 
#define SOAP_ERROR_NO_DATA_CODE   HTTP_NOT_IMPLEMENTED
 
#define SOAP_ERROR_MALFORMED_DATA_CODE   HTTP_BAD_GATEWAY
 
#define SOAP_QUERY_OK   HTTP_OK
 
#define MIN_SOAP_CLIENTS   5
 
#define MAX_SOAP_CLIENTS   50
 
#define CLIENT_BUSY_TIME   5
 
#define CLIENT_TEARDOWN_TIME   600
 
#define CLIENT_BUSY_LOAD   5
 
#define SPEC_DEFAULT   "default"
 
#define O_DESTROY(a)   { if(a) octstr_destroy(a); a=NULL; }
 
#define INTEGER(fieldname)
 
#define INT64(fieldname)
 
#define OCTSTR(fieldname)
 
#define UUID(fieldname)
 
#define VOID(fieldname)
 
#define MSG(type, stmt)   case type: { struct type *p = &msg->type; stmt } break;
 

Typedefs

typedef struct privdata PrivData
 
typedef struct client_data ClientData
 
typedef struct argument_map ArgumentMap
 

Functions

int smsc_soap_create (SMSCConn *conn, CfgGroup *cfg)
 
static int soap_add_msg_cb (SMSCConn *conn, Msg *sms)
 
static int soap_shutdown_cb (SMSCConn *conn, int finish_sending)
 
static void soap_start_cb (SMSCConn *conn)
 
static void soap_stop_cb (SMSCConn *conn)
 
static long soap_queued_cb (SMSCConn *conn)
 
static void soap_listener (void *arg)
 
static void soap_server (void *arg)
 
static void soap_send_loop (SMSCConn *conn)
 
static void soap_send (PrivData *privdata, Octstr *xmlbuffer, Msg *msgid)
 
static void soap_read_response (SMSCConn *conn)
 
static Octstrsoap_format_xml (Octstr *xml_file, Msg *msg, PrivData *privdata)
 
static long long soap_parse_response (PrivData *privdata, Octstr *xmlResponse)
 
static long soap_parse_mo (SMSCConn *conn, Octstr *request, Octstr **response)
 
static long soap_parse_dlr (SMSCConn *conn, Octstr *request, Octstr **response)
 
int soap_xmlnode_get_long (xmlNodePtr cur, long *out)
 
int soap_xmlnode_get_int64 (xmlNodePtr cur, long long *out)
 
int soap_xmlnode_get_octstr (xmlNodePtr cur, Octstr **out)
 
time_t soap_read_date (Octstr *dateString)
 
static Octstrsoap_write_date (time_t date)
 
int soap_server_start (SMSCConn *conn)
 
static void soap_server_stop (PrivData *privdata)
 
static ClientDatasoap_create_client_data ()
 
static void soap_destroy_client_data (void *data)
 
static void soap_client_init_query (PrivData *privdata, List *headers, Octstr *data, Msg *msg)
 
static ClientDatasoap_client_have_response (List *client_list)
 
static Octstrsoap_convert_token (Msg *msg, Octstr *name, PrivData *privdata)
 
Listsoap_create_map (Octstr *spec, long count, char *keywords[], char *types[], void *storage[])
 
void soap_destroy_map (void *item)
 
int soap_map_xml_data (xmlNodePtr xml, List *maps)
 
Octstrsoap_fetch_xml_data (xmlNodePtr xml, Octstr *path)
 
long soap_release_dependences (Octstr *deps, List *lstmaps, Msg *msg, PrivData *privdata)
 
int soap_process_deps (int key_index, int key_func_ind, Msg *msg, PrivData *privdata)
 
int soap_msgtype_deps (int key_func_index, Msg *msg)
 
int soap_msgdata_deps (int key_func_index, Msg *msg, PrivData *privdata)
 
int soap_lookup_function (Octstr *funcname)
 
Octstrsoap_select_function (int index, Msg *msg, PrivData *privdata)
 
Octstrsoap_bouyg_content_attribute (Msg *msg)
 
Octstrsoap_mobitai_content_attribute (Msg *msg)
 
Octstrsoap_o2o_msgdata_attribute (Msg *msg, PrivData *privdata)
 
Octstrsoap_msgdata_attribute (Msg *msg, PrivData *privdata)
 
Octstrsoap_o2o_validity30_attribute (Msg *msg)
 
Octstrsoap_mobitai_validity_date_attribute (Msg *msg)
 
Octstrsoap_bouyg_validity_attribute (Msg *msg)
 
Octstrsoap_o2o_date_attribute (Msg *msg)
 
Octstrsoap_mobitai_date_attribute (Msg *msg)
 
Octstrsoap_rand_attribute (Msg *msg)
 
Octstrsoap_o2o_dlrmask_smsc_yn_attribute (Msg *msg)
 
Octstrsoap_o2o_dlrmask_success_01_attribute (Msg *msg)
 
int soap_get_index (List *where, Octstr *key, int map_index)
 

Macro Definition Documentation

#define CLIENT_BUSY_LOAD   5

Definition at line 168 of file smsc_soap.c.

Referenced by soap_client_init_query().

#define CLIENT_BUSY_TIME   5

Definition at line 166 of file smsc_soap.c.

Referenced by soap_client_init_query().

#define CLIENT_TEARDOWN_TIME   600

Definition at line 167 of file smsc_soap.c.

#define INT64 (   fieldname)
Value:
if (!octstr_str_compare(name, #fieldname)) { \
sprintf(buf,"%lld", p->fieldname); \
return octstr_create(buf); \
}
char * name
Definition: smsc_cimd2.c:212
#define octstr_create(cstr)
Definition: octstr.h:125
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
#define INTEGER (   fieldname)
Value:
if (!octstr_str_compare(name, #fieldname)) { \
sprintf(buf,"%ld", p->fieldname); \
return octstr_create(buf); \
}
char * name
Definition: smsc_cimd2.c:212
#define octstr_create(cstr)
Definition: octstr.h:125
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
#define MAX_SOAP_CLIENTS   50

Definition at line 165 of file smsc_soap.c.

Referenced by soap_client_init_query().

#define MIN_SOAP_CLIENTS   5

Definition at line 164 of file smsc_soap.c.

#define MSG (   type,
  stmt 
)    case type: { struct type *p = &msg->type; stmt } break;
#define OCTSTR (   fieldname)
Value:
if (!octstr_str_compare(name, #fieldname)) \
return octstr_duplicate(p->fieldname);
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
#define SOAP_DEFAULT_CODE   HTTP_NOT_FOUND

Definition at line 154 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_DEFAULT_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>No method by that name</Error>"

Definition at line 145 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_DEFAULT_SENDER_STRING   "Kannel"

Definition at line 137 of file smsc_soap.c.

Referenced by soap_parse_mo().

#define SOAP_DEFAULT_VALIDITY   60

Definition at line 138 of file smsc_soap.c.

Referenced by soap_o2o_validity30_attribute().

#define SOAP_DLR_URI   "/dlr"

Definition at line 142 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_ERROR_DLR_CODE   HTTP_INTERNAL_SERVER_ERROR

Definition at line 155 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_ERROR_DLR_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Fatal error while trying to parse delivery report</Error>"

Definition at line 147 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_ERROR_MALFORMED_DATA_CODE   HTTP_BAD_GATEWAY

Definition at line 158 of file smsc_soap.c.

Referenced by soap_parse_dlr(), and soap_parse_mo().

#define SOAP_ERROR_MALFORMED_DATA_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Malformed data received</Error>"

Definition at line 150 of file smsc_soap.c.

Referenced by soap_parse_dlr(), and soap_parse_mo().

#define SOAP_ERROR_MO_CODE   HTTP_INTERNAL_SERVER_ERROR

Definition at line 156 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_ERROR_MO_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Fatal error while trying to parse incoming MO</Error>"

Definition at line 148 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_ERROR_NO_DATA_CODE   HTTP_NOT_IMPLEMENTED

Definition at line 157 of file smsc_soap.c.

Referenced by soap_parse_dlr(), and soap_parse_mo().

#define SOAP_ERROR_NO_DATA_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>No data received</Error>"

Definition at line 149 of file smsc_soap.c.

Referenced by soap_parse_dlr(), and soap_parse_mo().

#define SOAP_ERROR_NO_DLR_CODE   HTTP_BAD_METHOD

Definition at line 153 of file smsc_soap.c.

Referenced by soap_parse_dlr().

#define SOAP_ERROR_NO_DLR_MESSAGE   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<Error>Sorry - no DLR for that MT</Error>"

Definition at line 146 of file smsc_soap.c.

Referenced by soap_parse_dlr().

#define SOAP_MAX_MESSAGE_PER_ROUND   1

Definition at line 136 of file smsc_soap.c.

Referenced by soap_send_loop().

#define SOAP_MO_URI   "/mo"

Definition at line 141 of file smsc_soap.c.

Referenced by soap_server().

#define SOAP_QUERY_OK   HTTP_OK

Definition at line 159 of file smsc_soap.c.

Referenced by soap_parse_dlr(), and soap_parse_mo().

#define SOAP_SLEEP_TIME   0.01

Definition at line 135 of file smsc_soap.c.

Referenced by soap_listener(), and soap_server().

#define SPEC_DEFAULT   "default"

Definition at line 170 of file smsc_soap.c.

Referenced by soap_release_dependences().

#define UUID (   fieldname)
#define VOID (   fieldname)

Typedef Documentation

typedef struct argument_map ArgumentMap
typedef struct client_data ClientData
typedef struct privdata PrivData

Function Documentation

int smsc_soap_create ( SMSCConn conn,
CfgGroup cfg 
)

Definition at line 354 of file smsc_soap.c.

References privdata::allow_ip, privdata::alt_charset, cfg_get, cfg_get_bool(), cfg_get_integer(), smscconn::connect_time, smscconn::data, debug(), privdata::deny_ip, privdata::dlr_spec_file, privdata::dlr_xml_file, error(), privdata::form_urlencoded, privdata::form_variable, gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), gwthread_create, smscconn::id, info(), smscconn::is_stopped, privdata::listener_thread, privdata::mo_deps_file, privdata::mo_spec_file, privdata::mo_xml_file, privdata::mt_spec_file, privdata::mt_xml_file, privdata::name, smscconn::name, O_DESTROY, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_duplicate, octstr_format(), octstr_get_cstr, octstr_imm(), octstr_read_file(), octstr_split(), privdata::outgoing_queue, privdata::port, smscconn::queued, smscconn::send_msg, privdata::server_thread, privdata::shutdown, smscconn::shutdown, SMSCCONN_CONNECTING, SMSCCONN_DEAD, SMSCCONN_DISCONNECTED, SMSCCONN_KILLED_CANNOT_CONNECT, soap_add_msg_cb(), privdata::soap_client, soap_listener(), soap_queued_cb(), privdata::soap_server, soap_shutdown_cb(), soap_start_cb(), soap_stop_cb(), privdata::ssl, smscconn::start_conn, smscconn::status, smscconn::stop_conn, privdata::uri, and smscconn::why_killed.

355 {
357  Octstr* temp = NULL;
358  List* filenames = NULL;
359 
360  /* allocate and init internat data structure */
361  privdata = gw_malloc(sizeof(PrivData));
362  privdata->outgoing_queue = gwlist_create();
363  /* privdata->pending_ack_queue = gwlist_create(); */
364 
365  privdata->shutdown = 0;
366  privdata->soap_client = NULL;
367  privdata->soap_server = 0;
368 
369  /* read configuration data */
370  if (cfg_get_integer(&(privdata->port), cfg, octstr_imm("receive-port-ssl")) == -1)
371  if (cfg_get_integer(&(privdata->port), cfg, octstr_imm("receive-port")) == -1)
372  privdata->port = 0;
373  else
374  privdata->ssl = 0;
375  else
376 
377  privdata->ssl = 1;
378 
379  privdata->uri = cfg_get(cfg, octstr_imm("send-url"));
380 
381  privdata->allow_ip = cfg_get(cfg, octstr_imm("connect-allow-ip"));
382  if (privdata->allow_ip)
383  privdata->deny_ip = octstr_create("*.*.*.*");
384  else
385  privdata->deny_ip = NULL;
386 
387  /* read XML configuration */
388  privdata->form_variable = cfg_get(cfg, octstr_imm("form-variable"));
389  cfg_get_bool(&(privdata->form_urlencoded), cfg, octstr_imm("form-urlencoded"));
390 
391  privdata->alt_charset = cfg_get(cfg, octstr_imm("alt-charset"));
392  if (!privdata->alt_charset)
393  privdata->alt_charset = octstr_create("utf-8");
394 
395  /* check validity of stuff */
396  if (privdata->port <= 0 || privdata->port > 65535) {
397  error(0, "invalid port definition for SOAP server (%ld) - aborting",
398  privdata->port);
399  goto error;
400  }
401 
402  if (!privdata->uri) {
403  error(0, "invalid or missing send-url definition for SOAP - aborting.");
404  goto error;
405  }
406 
407  if (!privdata->form_variable) {
408  error(0, "invalid or missing form variable name definition for SOAP - aborting.");
409  goto error;
410  }
411 
412  /* load XML templates and specs */
413  filenames = octstr_split(temp = cfg_get(cfg,octstr_imm("xml-files")),
414  octstr_imm(";"));
415  octstr_destroy(temp);
416  if (gwlist_len(filenames) < 3) {
417  error(0,"SOAP: Not enough template files for XML generation, you need 3 - aborting");
418  goto error;
419  }
420  if ( !(privdata->mt_xml_file = octstr_read_file(
421  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
422  error(0,"SOAP: Can't load XML template for MT - aborting");
423  goto error;
424 
425  }
426  octstr_destroy(temp);
427  if ( !(privdata->mo_xml_file = octstr_read_file(
428  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
429  error(0,"SOAP: Can't load XML template for MO - aborting");
430  goto error;
431  }
432  octstr_destroy(temp);
433  if ( !(privdata->dlr_xml_file = octstr_read_file(
434  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
435 
436  error(0,"SOAP: Can't load XML template for DLR - aborting");
437  goto error;
438  }
439  octstr_destroy(temp);
441 
442  filenames = octstr_split(temp = cfg_get(cfg,octstr_imm("xmlspec-files")),
443  octstr_imm(";"));
444  octstr_destroy(temp);
445  if (gwlist_len(filenames) < 4) {
446  error(0,"Not enough spec files for XML parsing, you need 4 - aborting");
447  goto error;
448  }
449  if ( !(privdata->mt_spec_file = octstr_read_file(
450  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
451  error(0,"Can't load spec for MT parsing - aborting");
452  goto error;
453  }
454  octstr_destroy(temp);
455  if ( !(privdata->mo_spec_file = octstr_read_file(
456  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
457  error(0,"SOAP: Can't load spec for MO parsing - aborting");
458  goto error;
459  }
460  octstr_destroy(temp);
461  if ( !(privdata->dlr_spec_file = octstr_read_file(
462  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
463  error(0,"SOAP: Can't load spec for DLR parsing - aborting");
464  goto error;
465  }
466  octstr_destroy(temp);
467 
468  if ( !(privdata->mo_deps_file = octstr_read_file(
469  octstr_get_cstr(temp = gwlist_extract_first(filenames))))) {
470  error(0,"SOAP: Can't load 'deps' file for MO processing - aborting");
471  goto error;
472  }
473  octstr_destroy(temp);
474 
476 
477  debug("bb.soap.create",0,"Connecting to %s",
478  octstr_get_cstr(privdata->uri));
479 
480  /* store private data struct in connection data */
481  conn->data = privdata;
482 
483  /* state my name */
484  conn->name = octstr_format("SOAP: %s", octstr_get_cstr(privdata->uri) );
485  privdata->name = octstr_duplicate(conn->id);
486 
487  /* init status vars */
488  conn->status = SMSCCONN_CONNECTING;
489  conn->connect_time = time(NULL);
490 
491  /* set up call backs for bearerbox */
492  conn->shutdown = soap_shutdown_cb;
493  conn->queued = soap_queued_cb;
494  conn->start_conn = soap_start_cb;
495  conn->stop_conn = soap_stop_cb;
496  conn->send_msg = soap_add_msg_cb;
497 
498  privdata->listener_thread = 0;
499  privdata->server_thread = 0;
500 
501  /* check whether we can start right away */
502  if (!conn->is_stopped)
503  /* yes, we can */
504  conn->status = SMSCCONN_CONNECTING;
505  else
507 
508  /* any which way - start the connection thread */
509  if ((privdata->listener_thread = gwthread_create(soap_listener, conn)) == -1) {
510  error(0, "SOAP: soap_create, failed to spawn thread - aborting");
511  goto error;
512  }
513 
514  return 0; /* done - ok */
515 
516 error:
517  /* oh oh, problems */
518  error(0, "SOAP: Failed to create SOAP smsc connection");
519 
520  /* release stuff */
521  if (privdata != NULL) {
522  gwlist_destroy(privdata->outgoing_queue, NULL);
523  /* gwlist_destroy(privdata->pending_ack_queue, NULL); */
524 
525  O_DESTROY(privdata->uri);
526  O_DESTROY(privdata->allow_ip);
527  O_DESTROY(privdata->deny_ip);
528  O_DESTROY(privdata->form_variable);
529  O_DESTROY(privdata->alt_charset);
530  O_DESTROY(privdata->name);
531  O_DESTROY(privdata->mo_xml_file);
532  O_DESTROY(privdata->dlr_xml_file);
533  O_DESTROY(privdata->mt_xml_file);
534  O_DESTROY(privdata->mo_spec_file);
535  O_DESTROY(privdata->dlr_spec_file);
536  O_DESTROY(privdata->mt_spec_file);
537  O_DESTROY(privdata->mo_deps_file);
538  }
539  gw_free(privdata);
540  octstr_destroy(temp);
542 
543  /* notify bearerbox */
545  conn->status = SMSCCONN_DEAD;
546 
547  info(0, "exiting");
548  return -1; /* I'm dead */
549 }
int port
Definition: smsc_cgw.c:159
Octstr * name
Definition: smscconn_p.h:173
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
#define O_DESTROY(a)
Definition: smsc_soap.c:225
Octstr * id
Definition: smscconn_p.h:174
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
int form_urlencoded
Definition: smsc_soap.c:195
List * outgoing_queue
Definition: smsc_cgw.c:153
Octstr * mt_spec_file
Definition: smsc_soap.c:199
void(* stop_conn)(SMSCConn *conn)
Definition: smscconn_p.h:246
#define cfg_get(grp, varname)
Definition: cfg.h:86
static void soap_listener(void *arg)
Definition: smsc_soap.c:718
Octstr * mo_spec_file
Definition: smsc_soap.c:201
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * mt_xml_file
Definition: smsc_soap.c:198
void(* start_conn)(SMSCConn *conn)
Definition: smscconn_p.h:245
long listener_thread
Definition: smsc_soap.c:176
static void soap_stop_cb(SMSCConn *conn)
Definition: smsc_soap.c:665
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
static void soap_start_cb(SMSCConn *conn)
Definition: smsc_soap.c:634
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void * gwlist_extract_first(List *list)
Definition: list.c:305
static int soap_shutdown_cb(SMSCConn *conn, int finish_sending)
Definition: smsc_soap.c:594
time_t connect_time
Definition: smscconn_p.h:155
int soap_server
Definition: smsc_soap.c:180
#define octstr_duplicate(ostr)
Definition: octstr.h:187
Octstr * allow_ip
Definition: smsc_cgw.c:164
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Octstr * name
Definition: smsc_emi.c:96
Octstr * form_variable
Definition: smsc_soap.c:194
volatile sig_atomic_t is_stopped
Definition: smscconn_p.h:169
Octstr * dlr_spec_file
Definition: smsc_soap.c:203
int shutdown
Definition: smsc_cgw.c:156
Octstr * octstr_read_file(const char *filename)
Definition: octstr.c:1546
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:756
int alt_charset
Definition: smsc_emi.c:134
Octstr * uri
Definition: smsc_soap.c:185
Definition: octstr.c:118
int(* shutdown)(SMSCConn *conn, int finish_sending)
Definition: smscconn_p.h:229
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
Octstr * mo_xml_file
Definition: smsc_soap.c:200
Octstr * mo_deps_file
Definition: smsc_soap.c:204
smscconn_status_t status
Definition: smscconn_p.h:151
#define gwlist_create()
Definition: list.h:136
long(* queued)(SMSCConn *conn)
Definition: smscconn_p.h:240
List * soap_client
Definition: smsc_soap.c:189
int ssl
Definition: smsc_soap.c:183
int(* send_msg)(SMSCConn *conn, Msg *msg)
Definition: smscconn_p.h:235
long server_thread
Definition: smsc_soap.c:177
static int soap_add_msg_cb(SMSCConn *conn, Msg *sms)
Definition: smsc_soap.c:563
Octstr * dlr_xml_file
Definition: smsc_soap.c:202
Octstr * deny_ip
Definition: smsc_cgw.c:164
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
static long soap_queued_cb(SMSCConn *conn)
Definition: smsc_soap.c:688
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static int soap_add_msg_cb ( SMSCConn conn,
Msg sms 
)
static

Definition at line 563 of file smsc_soap.c.

References smscconn::data, debug(), gwlist_append(), gwlist_len(), gwthread_wakeup(), privdata::listener_thread, msg_duplicate(), privdata::name, octstr_get_cstr, privdata::outgoing_queue, SMSCCONN_DEAD, and smscconn::status.

Referenced by smsc_soap_create().

564 {
565 
566  PrivData *privdata = conn->data;
567  Msg *copy;
568 
569  /* I'm dead and cannot take any calls at the moment, please don't leave a message */
570  if (conn->status == SMSCCONN_DEAD)
571  return -1;
572 
573  copy = msg_duplicate(sms); /* copy the message */
574  gwlist_append(privdata->outgoing_queue, copy); /* put it in the queue */
575 
576  debug("bb.soap.add_msg",0,"SOAP[%s]: got a new MT from %s, list has now %ld MTs",
577  octstr_get_cstr(privdata->name), octstr_get_cstr(sms->sms.sender),
578  gwlist_len(privdata->outgoing_queue));
579 
580  gwthread_wakeup(privdata->listener_thread);
581 
582  return 0;
583 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
List * outgoing_queue
Definition: smsc_cgw.c:153
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long listener_thread
Definition: smsc_soap.c:176
Definition: msg.h:79
Octstr * name
Definition: smsc_emi.c:96
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
Octstr * soap_bouyg_content_attribute ( Msg msg)

Definition at line 2700 of file smsc_soap.c.

References DC_8BIT, and octstr_create.

Referenced by soap_select_function().

2701 {
2702 
2703  if (msg->sms.coding == DC_8BIT)
2704  return octstr_create("D");
2705  else
2706  return octstr_create("A");
2707 }
#define DC_8BIT
Definition: sms.h:111
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * soap_bouyg_validity_attribute ( Msg msg)

Definition at line 2851 of file smsc_soap.c.

References octstr_format().

Referenced by soap_select_function().

2852 {
2853  return octstr_format("%d", msg->sms.validity - time(NULL));
2854 }
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
static ClientData * soap_client_have_response ( List client_list)
static

Definition at line 2009 of file smsc_soap.c.

References client_data::caller, gwlist_get(), gwlist_len(), gwlist_lock(), and gwlist_unlock().

Referenced by soap_read_response().

2010 {
2011  long index;
2012  ClientData* cd;
2013 
2014  if (!client_list)
2015  return NULL;
2016 
2017  /* lock the list so nobody removes or adds clients while I'm looping on the list */
2018  gwlist_lock(client_list);
2019 
2020  for (index = gwlist_len(client_list) - 1; index >= 0; --index) {
2021  cd = gwlist_get(client_list,index);
2022  if (gwlist_len(cd->caller)) {
2023 
2024  gwlist_unlock(client_list);
2025  return gwlist_get(client_list, index);
2026  }
2027  }
2028 
2029  gwlist_unlock(client_list);
2030  return NULL;
2031 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
HTTPCaller * caller
Definition: smsc_soap.c:211
void gwlist_unlock(List *list)
Definition: list.c:354
void gwlist_lock(List *list)
Definition: list.c:347
static void soap_client_init_query ( PrivData privdata,
List headers,
Octstr data,
Msg msg 
)
static

Definition at line 1933 of file smsc_soap.c.

References client_data::caller, CLIENT_BUSY_LOAD, CLIENT_BUSY_TIME, debug(), gwlist_append(), gwlist_create, gwlist_delete(), gwlist_extract_first(), gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_unlock(), HTTP_METHOD_POST, http_start_request(), client_data::last_access, MAX_SOAP_CLIENTS, privdata::name, octstr_get_cstr, client_data::requests, privdata::soap_client, soap_create_client_data(), and privdata::uri.

Referenced by soap_send().

1934 {
1935  ClientData *cur_client = NULL;
1936  long index;
1937 
1938 
1939  /* no list yet, generate one */
1940  if (!privdata->soap_client)
1941  privdata->soap_client = gwlist_create();
1942 
1943  /* I'm going to change the list, so lock it */
1944  gwlist_lock(privdata->soap_client);
1945 
1946  /* find the next live caller */
1947  for (index = gwlist_len(privdata->soap_client) - 1 ; index >= 0; --index) {
1948  cur_client = gwlist_get(privdata->soap_client, index);
1949  if (
1950  cur_client->last_access + CLIENT_BUSY_TIME < time(NULL)
1951  &&
1952  cur_client->requests < CLIENT_BUSY_LOAD
1953  ) {
1954  debug("bb.soap.init_query",0,"SOAP[%s]: init_query getting a client",octstr_get_cstr(privdata->name));
1955 
1956  /* client is not busy - get it */
1957  gwlist_delete(privdata->soap_client, index, 1);
1958  break;
1959  }
1960  cur_client = NULL;
1961  }
1962 
1963  if (!cur_client) {
1964  if (gwlist_len(privdata->soap_client) > MAX_SOAP_CLIENTS) {
1965  debug("bb.soap.init_query",0,"SOAP[%s]: init_query all clients are busy, getting the first client",octstr_get_cstr(privdata->name));
1966  /* query not dispatched, and we have the max number of callers -
1967  grab the first caller (least used) from the list */
1968  cur_client = gwlist_extract_first(privdata->soap_client);
1969  } else {
1970  /* query not dispatched, and we don't have enough callers -
1971  start a new one */
1972  debug("bb.soap.init_query",0,"SOAP[%s]: init_query creates a new client",octstr_get_cstr(privdata->name));
1973  cur_client = soap_create_client_data();
1974  }
1975  }
1976 
1977  /* dispatch query to selected client */
1978  http_start_request(cur_client->caller, HTTP_METHOD_POST, privdata->uri, headers, data, 1, msg, NULL);
1979  cur_client->requests++;
1980  cur_client->last_access = time(NULL);
1981  gwlist_append(privdata->soap_client, cur_client);
1982  gwlist_unlock(privdata->soap_client);
1983 }
static ClientData * soap_create_client_data()
Definition: smsc_soap.c:1915
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
HTTPCaller * caller
Definition: smsc_soap.c:211
#define CLIENT_BUSY_TIME
Definition: smsc_soap.c:166
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void gwlist_unlock(List *list)
Definition: list.c:354
void http_start_request(HTTPCaller *caller, int method, Octstr *url, List *headers, Octstr *body, int follow, void *id, Octstr *certkeyfile)
Definition: http.c:1745
void * gwlist_extract_first(List *list)
Definition: list.c:305
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
time_t last_access
Definition: smsc_soap.c:209
#define CLIENT_BUSY_LOAD
Definition: smsc_soap.c:168
Octstr * name
Definition: smsc_emi.c:96
void gwlist_lock(List *list)
Definition: list.c:347
#define MAX_SOAP_CLIENTS
Definition: smsc_soap.c:165
Octstr * uri
Definition: smsc_soap.c:185
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
unsigned long requests
Definition: smsc_soap.c:210
#define gwlist_create()
Definition: list.h:136
List * soap_client
Definition: smsc_soap.c:189
static Octstr * soap_convert_token ( Msg msg,
Octstr name,
PrivData privdata 
)
static

Definition at line 2040 of file smsc_soap.c.

References error(), octstr_get_cstr, soap_lookup_function(), soap_select_function(), and Msg::type.

Referenced by soap_format_xml().

2042 {
2043  char buf[20];
2044  int index;
2045 
2046  if ( (index=soap_lookup_function(name)) >= 0 )
2047  return soap_select_function(index, msg, privdata);
2048 
2049 
2050 #define INTEGER(fieldname) \
2051  if (!octstr_str_compare(name, #fieldname)) { \
2052  sprintf(buf,"%ld", p->fieldname); \
2053  return octstr_create(buf); \
2054  }
2055 #define INT64(fieldname) \
2056  if (!octstr_str_compare(name, #fieldname)) { \
2057  sprintf(buf,"%lld", p->fieldname); \
2058  return octstr_create(buf); \
2059  }
2060 #define OCTSTR(fieldname) \
2061  if (!octstr_str_compare(name, #fieldname)) \
2062  return octstr_duplicate(p->fieldname);
2063 #define UUID(fieldname)
2064 #define VOID(fieldname)
2065 
2066 #define MSG(type, stmt) \
2067  case type: { struct type *p = &msg->type; stmt } break;
2068 
2069  switch (msg->type) {
2070 #include "msg-decl.h"
2071  default:
2072 
2073 
2074  error(0, "SOAP: Internal error: unknown message type %d", msg->type);
2075  return NULL;
2076  }
2077 
2078  error(0,"SOAP: soap_convert_token, can't find token named <%s>", octstr_get_cstr(name));
2079  return NULL;
2080 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int soap_lookup_function(Octstr *funcname)
Definition: smsc_soap.c:2637
Octstr * soap_select_function(int index, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2663
enum msg_type type
Definition: msg.h:80
static ClientData * soap_create_client_data ( )
static

Definition at line 1915 of file smsc_soap.c.

References client_data::caller, http_caller_create(), client_data::last_access, and client_data::requests.

Referenced by soap_client_init_query().

1916 {
1917 
1918  ClientData *cd = gw_malloc(sizeof(ClientData));
1919 
1920  cd->last_access = 0;
1921  cd->requests = 0;
1922  cd->caller = http_caller_create();
1923 
1924  return cd;
1925 }
HTTPCaller * caller
Definition: smsc_soap.c:211
time_t last_access
Definition: smsc_soap.c:209
unsigned long requests
Definition: smsc_soap.c:210
HTTPCaller * http_caller_create(void)
Definition: http.c:897
List * soap_create_map ( Octstr spec,
long  count,
char *  keywords[],
char *  types[],
void *  storage[] 
)

Definition at line 2088 of file smsc_soap.c.

References argument_map::attribute, debug(), gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), argument_map::name, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, octstr_imm(), octstr_split(), octstr_split_words(), octstr_str_compare(), argument_map::path, argument_map::sscan_type, and argument_map::store.

Referenced by soap_parse_dlr(), soap_parse_mo(), and soap_parse_response().

2089 {
2090  List *parse_items, *out;
2091 
2092  out = gwlist_create();
2093 
2094  /* read the list of items from the spec file */
2095  parse_items = octstr_split(spec, octstr_imm("\n"));
2096 
2097  while (gwlist_len(parse_items)) {
2098  ArgumentMap* map;
2099  int index;
2100  Octstr* temp = gwlist_extract_first(parse_items);
2101  List* item = octstr_split_words(temp);
2102 
2103 
2104  /* make sure we have at least two things in the item : a keyword and a path */
2105  if (gwlist_len(item) < 2) {
2106  debug("bb.soap.parse_create_map",0,"SOAP: broken spec file line <%s> in soap_create_map",
2107  octstr_get_cstr(temp));
2108  octstr_destroy(temp);
2110  continue;
2111  }
2112 
2113  /* check that the keyword matches something in the list of keywords */
2114  for (index = 0; index < count; ++index) {
2115  if (!octstr_str_compare(gwlist_get(item,0), keywords[index])) {
2116  /* allocate the structure */
2117  map = gw_malloc(sizeof(ArgumentMap));
2118  map->name = gwlist_extract_first(item);
2119  map->path = gwlist_extract_first(item);
2120  map->attribute = gwlist_extract_first(item); /* could be NULL, but that is ok */
2121  map->sscan_type = octstr_create(types[index]);
2122  map->store = storage[index];
2123  gwlist_append(out, map);
2124  break;
2125  }
2126  }
2127 
2128  /* destroy temporary variables; */
2130  octstr_destroy(temp);
2131  }
2132 
2133  gwlist_destroy(parse_items, octstr_destroy_item);
2134 
2135  return out;
2136 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * sscan_type
Definition: smsc_soap.c:219
static struct @117 keywords[]
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * attribute
Definition: smsc_soap.c:218
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Octstr * name
Definition: smsc_soap.c:216
Octstr * path
Definition: smsc_soap.c:217
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
#define gwlist_create()
Definition: list.h:136
void * store
Definition: smsc_soap.c:220
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static void soap_destroy_client_data ( void *  data)
static

Definition at line 1991 of file smsc_soap.c.

References client_data::caller, http_caller_destroy(), and http_caller_signal_shutdown().

Referenced by soap_listener().

1992 {
1993  ClientData *cd = (ClientData*) data;
1994 
1995  /* signal the caller to stop and then kill it */
1996  if (cd->caller) {
1999  }
2000 }
void http_caller_signal_shutdown(HTTPCaller *caller)
Definition: http.c:913
HTTPCaller * caller
Definition: smsc_soap.c:211
void http_caller_destroy(HTTPCaller *caller)
Definition: http.c:907
void soap_destroy_map ( void *  item)

Definition at line 2143 of file smsc_soap.c.

References argument_map::attribute, argument_map::name, octstr_destroy(), argument_map::path, and argument_map::sscan_type.

Referenced by soap_parse_dlr(), soap_parse_mo(), and soap_parse_response().

2144 {
2145  ArgumentMap* map = item;
2146  octstr_destroy(map->name);
2147  octstr_destroy(map->path);
2148  octstr_destroy(map->attribute);
2149  octstr_destroy(map->sscan_type);
2150  gw_free(map);
2151 }
Octstr * sscan_type
Definition: smsc_soap.c:219
Octstr * attribute
Definition: smsc_soap.c:218
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
Octstr * name
Definition: smsc_soap.c:216
Octstr * path
Definition: smsc_soap.c:217
Octstr * soap_fetch_xml_data ( xmlNodePtr  xml,
Octstr path 
)

Definition at line 2162 of file smsc_soap.c.

References content, debug(), found, gwlist_destroy(), gwlist_get(), gwlist_len(), octstr_copy, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_get_char(), octstr_get_cstr, octstr_imm(), octstr_len(), octstr_split(), and octstr_str_compare().

2163 {
2164  Octstr *temp, *xml_path, *attr_name = NULL;
2165  List* path_elements;
2166  unsigned char c;
2167  xmlNodePtr parent, node;
2168  int index;
2169 
2170 
2171  /* sanity check */
2172  if (!octstr_len(path) || !xml)
2173  return NULL;
2174 
2175 
2176  /* stop here for case (c) */
2177  if (((c = octstr_get_char(path, 0)) == '"' || c == '\'') &&
2178  (octstr_get_char(path, octstr_len(path)-1) == c))
2179  return octstr_copy(path, 1, octstr_len(path) - 2);
2180 
2181  /* split into XML path and attribute name */
2182  path_elements = octstr_split(path, octstr_imm(","));
2183  xml_path = gwlist_get(path_elements,0);
2184  if (gwlist_len(path_elements) > 1) /* case (b), we have an attribute */
2185  attr_name = gwlist_get(path_elements,1);
2186  gwlist_destroy(path_elements, NULL);
2187 
2188  /* split path into parts */
2189  path_elements = octstr_split(xml_path, octstr_imm("/"));
2190 
2191  /* walk the message tree down the path */
2192  parent = NULL;
2193  node = xml;
2194  index = 0;
2195  while (index < gwlist_len(path_elements)) {
2196  int found = 0;
2197  /* get the next path element */
2198  temp = gwlist_get(path_elements, index);
2199  do {
2200  if (!octstr_str_compare(temp,(char *)node->name)) {
2201  /* found what we're looking for */
2202  if (!(node->xmlChildrenNode) && index < (gwlist_len(path_elements)-1)) {
2203  /* while this is indeed the item we are looking for, it's not the end
2204  * of the path, and this item has no children */
2205  debug("bb.soap.fetch_xml_data",0,"SOAP: fetch_xml - error parsing XML, "
2206  "looking for <%s>, but element <%s> has no children",
2207  octstr_get_cstr(xml_path), octstr_get_cstr(temp));
2208  } else {
2209  ++index; /* go down the path */
2210  parent = node; /* remember where I came from */
2211  node = node->xmlChildrenNode; /* trace into the node */
2212  ++found; /* remember that I found it */
2213  break; /* escape to the next level */
2214  }
2215  }
2216  /* get the next node on this level - this runs if the current node is not in the path */
2217  } while ((node = node->next));
2218 
2219  if (!found) {
2220  /* didn't find anything - back track */
2221  node = parent;
2222  parent = node->parent;
2223  if (--index < 0)
2224  /* I backtracked too much up the tree, nowhere to go to */
2225  break; /* out of the main loop with nothing to show for it */
2226 
2227  if (!(node = node->next))
2228 
2229  /* after back tracking, go over to the next sibling of the node I just
2230  * finished searching under, or bail out if no more siblings */
2231  break;
2232  }
2233  }
2234 
2235  /* coming here there are two options:
2236  * 1) we looped over all the tree, but did not succeed in traveling the
2237  * requested path - index not pointing past the list of path elements - */
2238  if (index < gwlist_len(path_elements)) {
2239  /* didn't find the full path */
2240  debug("bb.soap.map_xml_data",0,"SOAP: fetch_xml - path <%s> cannot be traveled in input XML",
2241  octstr_get_cstr(xml_path));
2242  gwlist_destroy(path_elements, octstr_destroy_item);
2243  octstr_destroy(xml_path);
2244  octstr_destroy(attr_name);
2245  return NULL;
2246  }
2247 
2248 
2249  /* 2) index is pointing past the end of the path and the correct node
2250  * is stored in parent */
2251  if (attr_name) { /* The caller wants to get an attribute */
2252  xmlChar* content;
2253  content = xmlGetProp(parent, (xmlChar *)octstr_get_cstr(attr_name));
2254  if (content)
2255  temp = octstr_create((char *)content);
2256  else /* dont treat an empty or non-existant attribute as an error right away */
2257  temp = octstr_create("");
2258  xmlFree(content);
2259  } else { /* the caller wants to get the content */
2260  xmlChar* content;
2261  content = xmlNodeGetContent(parent);
2262  if (content)
2263  temp = octstr_create((char *)content);
2264  else /* don't treat an empty tag an error right away */
2265  temp = octstr_create("");
2266  xmlFree(content);
2267  }
2268 
2269  gwlist_destroy(path_elements, octstr_destroy_item);
2270  octstr_destroy(xml_path);
2271  octstr_destroy(attr_name);
2272 
2273  return temp;
2274 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
static struct pid_list * found
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
static Octstr * content
Definition: mtbatch.c:87
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static Octstr * soap_format_xml ( Octstr xml_file,
Msg msg,
PrivData privdata 
)
static

Definition at line 1014 of file smsc_soap.c.

References error(), octstr_append(), octstr_append_char(), octstr_copy, octstr_create, octstr_destroy(), octstr_get_char(), octstr_get_cstr, octstr_len(), soap_convert_token(), start, and token.

Referenced by soap_parse_dlr(), soap_parse_mo(), and soap_send_loop().

1015 {
1016  Octstr *xml;
1017  long t;
1018  long start = -1;
1019  int curly_enclose = 0;
1020 
1021  xml = octstr_create("");
1022 
1023  for (t = 0; t < octstr_len(xml_file); ++t) {
1024  unsigned char c;
1025 
1026  if ((c = octstr_get_char(xml_file,t)) == '%') {
1027  /* found start of token */
1028  start = t+1;
1029  continue;
1030  }
1031 
1032  if (c == '{' && start == t) { /* the token is enclosed in curlys */
1033  ++start; /* make sure the token is read from the next char */
1034  curly_enclose=1;
1035  }
1036 
1037  if (start < 0)
1038  octstr_append_char(xml,c);
1039  else if (
1040  (curly_enclose && (c == '}')) /* end of token in case of curly enclosure */
1041  ||
1042  (!curly_enclose && !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
1043  (c >= '0' && c <= '9') || c == '_'))) {
1044  /* found end of token */
1045  Octstr *data, *token;
1046 
1047  token = octstr_copy(xml_file,start,(t-start));
1048  if ((data = soap_convert_token(msg, token, privdata))) {
1049  octstr_append(xml, data);
1050  octstr_destroy(data);
1051  } else {
1052  error(0,"SOAP: format_xml - failed to format token %s using message",
1053  octstr_get_cstr(token));
1054  octstr_destroy(token);
1055  octstr_destroy(xml);
1056  return NULL;
1057 
1058  }
1059  octstr_destroy(token);
1060  start = -1;
1061  if (!curly_enclose)
1062  /* I want to get that char again, to let the normal behaviour
1063  * deal with it - only if it's not the ending curly */
1064  --t;
1065  else
1066  curly_enclose = 0;
1067  }
1068  }
1069 
1070  return xml;
1071 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static Octstr * soap_convert_token(Msg *msg, Octstr *name, PrivData *privdata)
Definition: smsc_soap.c:2040
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1515
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
int token
Definition: wslexer.c:157
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
static int start
int soap_get_index ( List where,
Octstr key,
int  map_index 
)

Definition at line 2889 of file smsc_soap.c.

References error(), gwlist_get(), gwlist_len(), argument_map::name, octstr_compare(), octstr_get_cstr, and octstr_str_compare().

Referenced by soap_release_dependences().

2890 {
2891  int i, j;
2892  ArgumentMap* map;
2893 
2894  /* ADD HERE: */
2895  /* key and key_deps values as defined in mo.deps */
2896  char* funcs_deps[] = {
2897  "msgtype", "msgdata"
2898  };
2899 
2900  for (i=0; i < gwlist_len(where); ++i) {
2901  map = gwlist_get(where, i);
2902  if (!octstr_compare(map->name, key)) {
2903  if (map_index==1) /* return index from the list where found name */
2904  return i;
2905 
2906  for (j=0; j < sizeof(funcs_deps)/sizeof(funcs_deps[0]); ++j) {
2907  if (!octstr_str_compare(map->name, funcs_deps[j]))
2908  return j;
2909  }
2910  }
2911  }
2912  error(0, "SOAP: soap_get_index, broken 'deps' file, can't find key <%s> ", octstr_get_cstr(key));
2913  return -1;
2914 }
void error(int err, const char *fmt,...)
Definition: log.c:612
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * name
Definition: smsc_soap.c:216
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
static void soap_listener ( void *  arg)
static

Definition at line 718 of file smsc_soap.c.

References privdata::allow_ip, privdata::alt_charset, bb_smscconn_connected(), bb_smscconn_killed(), bb_smscconn_send_failed(), smscconn::data, debug(), privdata::deny_ip, privdata::dlr_spec_file, privdata::dlr_xml_file, error(), smscconn::flow_mutex, privdata::form_variable, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), gwthread_sleep(), privdata::mo_deps_file, privdata::mo_spec_file, privdata::mo_xml_file, msg, privdata::mt_spec_file, privdata::mt_xml_file, mutex_lock, mutex_unlock, privdata::name, O_DESTROY, octstr_get_cstr, privdata::outgoing_queue, privdata::shutdown, SMSCCONN_ACTIVE, SMSCCONN_CONNECTING, SMSCCONN_DEAD, SMSCCONN_DISCONNECTED, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_RECONNECTING, privdata::soap_client, soap_destroy_client_data(), soap_read_response(), soap_send_loop(), privdata::soap_server, soap_server_start(), soap_server_stop(), SOAP_SLEEP_TIME, smscconn::status, and privdata::uri.

Referenced by smsc_soap_create(), and soap_start_cb().

719 {
720  SMSCConn *conn = arg;
721  PrivData *privdata = conn->data;
722  Msg *msg = NULL;
723  debug("bb.soap.listener",0,"SOAP[%s]: listener entering",
724  octstr_get_cstr(privdata->name));
725 
726  while (!privdata->shutdown) {
727 
728  /* check connection status */
729  switch (conn->status) {
731  case SMSCCONN_CONNECTING:
732  if (privdata->soap_server) {
733  soap_server_stop(privdata);
734  }
735 
736  if (soap_server_start(conn)) {
737  privdata->shutdown = 1;
738  error(0, "SOAP[%s]: failed to start HTTP server!",
739  octstr_get_cstr(privdata->name));
740  break;
741  }
742 
743  mutex_lock(conn->flow_mutex);
744  conn->status = SMSCCONN_ACTIVE;
745  mutex_unlock(conn->flow_mutex);
746 
747  bb_smscconn_connected(conn);
748  break;
749 
751  if (privdata->soap_server)
752  soap_server_stop(privdata);
753  break;
754 
755  case SMSCCONN_ACTIVE:
756  if (!privdata->soap_server) {
757  mutex_lock(conn->flow_mutex);
759  mutex_unlock(conn->flow_mutex);
760  break;
761  }
762 
763  /* run the normal send/receive loop */
764  if (gwlist_len(privdata->outgoing_queue) > 0) { /* we have messages to send */
765  soap_send_loop(conn); /* send any messages in queue */
766  }
767  break;
768 
769  case SMSCCONN_DEAD:
770  /* this shouldn't happen here -
771  * I'm the only one allowed to set SMSCCONN_DEAD */
772 
773  default:
774  break;
775  }
776 
777  soap_read_response(conn); /* collect HTTP responses */
778 
779  /* sleep for a while so I wont busy-loop */
781  }
782 
783  debug("bb.soap.connection",0,"SOAP[%s]: connection shutting down",
784  octstr_get_cstr(privdata->name));
785 
786  soap_server_stop(privdata);
787 
788  /* send all queued messages to bearerbox for recycling */
789  debug("bb.soap.connection",0,"SOAP[%s]: sending messages back to bearerbox",
790  octstr_get_cstr(privdata->name));
791 
792  while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL)
794 
795  /* lock module public state data */
796  mutex_lock(conn->flow_mutex);
797 
798  debug("bb.soap.connection",0,"SOAP[%s]: playing dead",
799  octstr_get_cstr(privdata->name));
800  conn->status = SMSCCONN_DEAD; /* set state */
801 
802  /* destroy lists */
803  debug("bb.soap.connection",0,"SOAP[%s]: don't need the queue anymore",
804  octstr_get_cstr(privdata->name));
805 
806  gwlist_destroy(privdata->outgoing_queue, NULL);
807  /* gwlist_destroy(privdata->pending_ack_queue, NULL); */
808 
809  /* clear the soap client collection */
810  debug("bb.soap.connection",0,"SOAP[%s]: tell caller to stop",
811  octstr_get_cstr(privdata->name));
812  if (privdata->soap_client)
814 
815  /* destroy private data stores */
816  debug("bb.soap.connection",0,"SOAP[%s]: done with privdata",
817  octstr_get_cstr(privdata->name));
818  O_DESTROY(privdata->uri);
819  O_DESTROY(privdata->allow_ip);
820  O_DESTROY(privdata->deny_ip);
821 
822  O_DESTROY(privdata->form_variable);
823 
824  O_DESTROY(privdata->alt_charset);
825  O_DESTROY(privdata->name);
826  O_DESTROY(privdata->mo_xml_file);
827 
828  O_DESTROY(privdata->dlr_xml_file);
829  O_DESTROY(privdata->mt_xml_file);
830  O_DESTROY(privdata->mo_spec_file);
831  O_DESTROY(privdata->dlr_spec_file);
832  O_DESTROY(privdata->mt_spec_file);
833  O_DESTROY(privdata->mo_deps_file);
834 
835  gw_free(privdata);
836  conn->data = NULL;
837 
838  mutex_unlock(conn->flow_mutex);
839 
840  debug("bb.soap.connection", 0, "SOAP: module has completed shutdown.");
842 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static void soap_send_loop(SMSCConn *conn)
Definition: smsc_soap.c:963
void bb_smscconn_connected(SMSCConn *conn)
Definition: bb_smscconn.c:192
static void soap_server_stop(PrivData *privdata)
Definition: smsc_soap.c:1875
#define mutex_unlock(m)
Definition: thread.h:136
void bb_smscconn_killed(void)
Definition: bb_smscconn.c:199
#define O_DESTROY(a)
Definition: smsc_soap.c:225
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
List * outgoing_queue
Definition: smsc_cgw.c:153
Octstr * mt_spec_file
Definition: smsc_soap.c:199
#define SOAP_SLEEP_TIME
Definition: smsc_soap.c:135
Octstr * mo_spec_file
Definition: smsc_soap.c:201
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * mt_xml_file
Definition: smsc_soap.c:198
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
int soap_server
Definition: smsc_soap.c:180
Mutex * flow_mutex
Definition: smscconn_p.h:157
Octstr * allow_ip
Definition: smsc_cgw.c:164
Octstr * name
Definition: smsc_emi.c:96
void gwthread_sleep(double seconds)
static void soap_destroy_client_data(void *data)
Definition: smsc_soap.c:1991
Octstr * form_variable
Definition: smsc_soap.c:194
Octstr * dlr_spec_file
Definition: smsc_soap.c:203
int shutdown
Definition: smsc_cgw.c:156
int alt_charset
Definition: smsc_emi.c:134
Octstr * uri
Definition: smsc_soap.c:185
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * mo_xml_file
Definition: smsc_soap.c:200
Octstr * mo_deps_file
Definition: smsc_soap.c:204
smscconn_status_t status
Definition: smscconn_p.h:151
List * soap_client
Definition: smsc_soap.c:189
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
Octstr * dlr_xml_file
Definition: smsc_soap.c:202
#define mutex_lock(m)
Definition: thread.h:130
Octstr * deny_ip
Definition: smsc_cgw.c:164
static void soap_read_response(SMSCConn *conn)
Definition: smsc_soap.c:1118
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int soap_server_start(SMSCConn *conn)
Definition: smsc_soap.c:1845
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
int soap_lookup_function ( Octstr funcname)

Definition at line 2637 of file smsc_soap.c.

References octstr_str_compare().

Referenced by soap_convert_token().

2638 {
2639  int i;
2640 
2641  /* ADD HERE: XML functions aliasis */
2642  char *aliasis[] = {
2643  "bouyg_content", "mobitai_content",
2644  "o2o_msgdata", "msgdata",
2645  "o2o_validity30", "mobitai_validity_date", "bouyg_validity",
2646  "o2o_date", "mobitai_date", "rand",
2647  "o2o_dlrmask_smsc_yn", "o2o_dlrmask_success_01"
2648  };
2649 
2650  for (i=0; i<sizeof(aliasis)/sizeof(aliasis[0]); ++i)
2651  {
2652  if (!octstr_str_compare(funcname, aliasis[i]))
2653  return i;
2654  }
2655  return -1;
2656 }
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
int soap_map_xml_data ( xmlNodePtr  xml,
List maps 
)

Definition at line 2282 of file smsc_soap.c.

References argument_map::attribute, content, debug(), found, gwlist_destroy(), gwlist_get(), gwlist_len(), argument_map::name, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, octstr_imm(), octstr_split(), octstr_str_compare(), octstr_strip_blanks(), argument_map::path, argument_map::sscan_type, and argument_map::store.

Referenced by soap_parse_dlr(), soap_parse_mo(), and soap_parse_response().

2283 {
2284  int mapindex = 0, args = 0;
2285  xmlNodePtr node, parent;
2286 
2287  /* step through the items on the map */
2288  while (mapindex < gwlist_len(maps)) {
2289 
2290  Octstr* temp;
2291 
2292  int index = 0;
2293  ArgumentMap* map = gwlist_get(maps,mapindex);
2294  /* split the path elements */
2295  List* path_elements = octstr_split(map->path, octstr_imm("/"));
2296 
2297  /* walk the message tree down the path */
2298  parent = NULL;
2299  node = xml;
2300  while (index < gwlist_len(path_elements)) {
2301  int found = 0;
2302  /* get the next path element */
2303  temp = gwlist_get(path_elements, index);
2304  do {
2305  if (!octstr_str_compare(temp,(char *)node->name)) {
2306  /* found what we're looking for */
2307  if (!(node->xmlChildrenNode) && index < (gwlist_len(path_elements)-1)) {
2308  /* while this is indeed the item we are looking for, it's not the end
2309  of the path, and this item has no children */
2310  debug("bb.soap.map_xml_data",0,"SOAP: error parsing XML, looking for <%s>, but element <%s> has no children",
2311  octstr_get_cstr(map->path), octstr_get_cstr(temp));
2312  } else {
2313  ++index; /* go down the path */
2314  parent = node; /* remember where I came from */
2315  node = node->xmlChildrenNode; /* trace into the node */
2316  ++found;
2317  break; /* escape to the next level */
2318  }
2319  }
2320  } while ((node = node->next));
2321 
2322  if (!found) {
2323  /* didn't find anything - back track */
2324  node = parent;
2325  if (parent==NULL) /* first tag not found, quickly go out ! */
2326  return 0;
2327 
2328  parent = node->parent;
2329  if (--index < 0)
2330  /* I backtracked too much up the tree, nowhere to go to */
2331  break;
2332 
2333  if (!(node = node->next))
2334  /* no more childs under the main tree to look under, abort */
2335  break;
2336 
2337  }
2338  }
2339 
2340 
2341  if (index < gwlist_len(path_elements)) {
2342  /* didn't find the full path */
2343  debug("bb.soap.map_xml_data",0,"SOAP: didn't find element for keyword <%s> in XML data",
2344  octstr_get_cstr(map->name));
2345  gwlist_destroy(path_elements, octstr_destroy_item);
2346  ++mapindex;
2347  continue;
2348  }
2349 
2350  /* found the correct node (it's stored in parent) */
2351  if (map->attribute) {
2352 
2353  /* The user wants to get an attribute */
2354  xmlChar* content;
2355  content = xmlGetProp(parent, (xmlChar *)octstr_get_cstr(map->attribute));
2356  if (content)
2357  temp = octstr_create((char *)content);
2358  else /* dont treat an empty or non-existant attribute as an error right away */
2359  temp = octstr_create("");
2360  xmlFree(content);
2361  } else {
2362  /* the user wants to get the content */
2363  xmlChar* content;
2364  content = xmlNodeGetContent(parent);
2365  if (content)
2366  temp = octstr_create((char *)content);
2367  else /* don't treat an empty tag an error right away */
2368 
2369  temp = octstr_create("");
2370  xmlFree(content);
2371  }
2372 
2373  /* parse the content using sscan_type from the map */
2374  octstr_strip_blanks(temp);
2375  if (!octstr_str_compare(map->sscan_type,"%s")) {
2376  /* special processing of %s - this means the whole string, while sscanf stops at spaces */
2377  strcpy(map->store,octstr_get_cstr(temp));
2378 
2379  ++args;
2380  } else {
2381  if (!sscanf(octstr_get_cstr(temp), octstr_get_cstr(map->sscan_type), map->store)) {
2382  debug("bb.soap.map_xml_data",0,"SOAP: failed to scan content '%s' for '%s' in xml parsing",
2384  } else {
2385  ++args;
2386  }
2387  }
2388 
2389 
2390  /* done for this item */
2391  octstr_destroy(temp);
2392  gwlist_destroy(path_elements, octstr_destroy_item);
2393  ++mapindex;
2394  }
2395  return args;
2396 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static struct pid_list * found
Octstr * sscan_type
Definition: smsc_soap.c:219
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Octstr * attribute
Definition: smsc_soap.c:218
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Octstr * name
Definition: smsc_soap.c:216
Octstr * path
Definition: smsc_soap.c:217
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
void * store
Definition: smsc_soap.c:220
static Octstr * content
Definition: mtbatch.c:87
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
Octstr * soap_mobitai_content_attribute ( Msg msg)

Definition at line 2709 of file smsc_soap.c.

References DC_8BIT, and octstr_create.

Referenced by soap_select_function().

2710 {
2711  if (msg->sms.coding == DC_8BIT)
2712  return octstr_create("binary");
2713  else
2714  return octstr_create("text");
2715 
2716 }
#define DC_8BIT
Definition: sms.h:111
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * soap_mobitai_date_attribute ( Msg msg)

Definition at line 2863 of file smsc_soap.c.

References date_create_iso().

Referenced by soap_select_function().

2864 {
2865  return date_create_iso(msg->sms.time);
2866 }
Octstr * date_create_iso(time_t unixtime)
Definition: date.c:292
Octstr * soap_mobitai_validity_date_attribute ( Msg msg)

Definition at line 2845 of file smsc_soap.c.

References date_create_iso().

Referenced by soap_select_function().

2846 {
2847  return date_create_iso(msg->sms.validity);
2848 }
Octstr * date_create_iso(time_t unixtime)
Definition: date.c:292
Octstr * soap_msgdata_attribute ( Msg msg,
PrivData privdata 
)

Definition at line 2789 of file smsc_soap.c.

References privdata::alt_charset, charset_convert(), DC_7BIT, DC_8BIT, DC_UCS2, DC_UNDEF, debug(), error(), O_DESTROY, octstr_append(), octstr_binary_to_hex(), octstr_convert_to_html_entities(), octstr_dump, octstr_duplicate, and octstr_get_cstr.

Referenced by soap_select_function().

2790 {
2791  Octstr *data, *udhdata;
2792  int ret;
2793 
2794 
2795  data = octstr_duplicate(msg->sms.msgdata);
2796 
2797  if (msg->sms.coding == DC_8BIT) {
2798  udhdata = octstr_duplicate(msg->sms.udhdata);
2799  octstr_append(udhdata, data);
2800  octstr_binary_to_hex(udhdata, 1);
2801  O_DESTROY(data);
2802  return udhdata;
2803  }
2804  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) {
2805  /* convert message data to target encoding */
2806  debug("bb.soap.msgdata_attribute", 0, "SOAP: converting from UTF-8 to %s", octstr_get_cstr(privdata->alt_charset));
2807  ret = charset_convert(data, "UTF-8", octstr_get_cstr(privdata->alt_charset));
2808  if (ret == -1) {
2809  error(0,"SOAP: soap_msgdata_attribute, charset_convert failed");
2810  octstr_dump(msg->sms.msgdata, 0);
2811  O_DESTROY(data);
2812  return NULL;
2813  }
2814  debug("bb.soap.msgdata_attribute",0,"SOAP: converting to HTML entities");
2816  return data;
2817  }
2818  else if (msg->sms.coding == DC_UCS2) {
2819  /* convert message data to target encoding */
2820  debug("bb.soap.msgdata_attribute", 0, "converting from USC-2 to %s", octstr_get_cstr(privdata->alt_charset));
2821  ret = charset_convert(data, "UCS-2BE", octstr_get_cstr(privdata->alt_charset));
2822  if (ret == -1) {
2823  error(0,"SOAP: soap_msgdata_attribute, charset_convert failed");
2824 
2825  octstr_dump(data, 0);
2826  O_DESTROY(data);
2827  return NULL;
2828  }
2829  return data;
2830  }
2831  else {
2832  error(0,"SOAP: soap_msgdata_attribute, unknown coding: %ld", msg->sms.coding);
2833  O_DESTROY(data);
2834  return NULL;
2835  }
2836 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define O_DESTROY(a)
Definition: smsc_soap.c:225
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
#define DC_8BIT
Definition: sms.h:111
void octstr_convert_to_html_entities(Octstr *input)
Definition: octstr.c:2736
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
Definition: octstr.c:463
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
int alt_charset
Definition: smsc_emi.c:134
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define DC_UNDEF
Definition: sms.h:109
#define DC_UCS2
Definition: sms.h:112
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
int soap_msgdata_deps ( int  key_func_index,
Msg msg,
PrivData privdata 
)

Definition at line 2581 of file smsc_soap.c.

References privdata::alt_charset, charset_convert(), debug(), error(), privdata::name, octstr_base64_to_binary(), octstr_case_compare(), octstr_create, octstr_dump, octstr_get_cstr, octstr_hex_to_binary(), and octstr_imm().

Referenced by soap_process_deps().

2582 {
2583  int ret = 0;
2584  /* {"set_iso","64_binary","hex_binary","unicode","default"} msgdata */
2585 
2586  /* ADD HERE: */
2587  switch (key_func_index)
2588  {
2589  case 0: /* "set_iso" */
2590  msg->sms.charset = octstr_create("ISO-8859-1");
2591  break;
2592  case 1: /* "64_binary" */
2593  octstr_base64_to_binary(msg->sms.msgdata);
2594  break;
2595  case 2: /* "hex_binary" */
2596  octstr_hex_to_binary(msg->sms.msgdata);
2597  break;
2598 
2599  case 3: /* "unicode" */
2600  case 4: /* "default" */
2601 
2602  if (!octstr_case_compare(privdata->alt_charset, octstr_imm("UCS-2"))) {
2603  debug("bb.soap.msgdata_deps",0,"SOAP[%s]: converting from %s to UCS-2BE",
2604  octstr_get_cstr(privdata->name), octstr_get_cstr(privdata->alt_charset));
2605  ret = charset_convert(msg->sms.msgdata, octstr_get_cstr(privdata->alt_charset), "UCS-2BE");
2606 
2607  if (ret == -1) {
2608 
2609  error(2,"SOAP[%s]: Error converting MO data from %s to unicode",
2610  octstr_get_cstr(privdata->name), octstr_get_cstr(privdata->alt_charset));
2611  }
2612  }
2613  else if (ret != 0) {
2614  debug("bb.soap.parse_mo",1,"SOAP[%s]: charset_convert made %d irreversable transformations",
2615  octstr_get_cstr(privdata->name), ret);
2616  }
2617  msg->sms.charset = octstr_create("UCS-2");
2618 
2619  debug("bb.soap.parse_mo",0,"SOAP[%s]: message decoded -", octstr_get_cstr(privdata->name));
2620  octstr_dump(msg->sms.msgdata, 0);
2621  break;
2622 
2623  default:
2624  /* out of range */
2625 
2626  error(0, "SOAP: soap_msgdata_deps, unknown index %d", key_func_index);
2627  return -1;
2628  }
2629  return 0;
2630 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
Definition: octstr.c:901
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
void octstr_base64_to_binary(Octstr *ostr)
Definition: octstr.c:661
int alt_charset
Definition: smsc_emi.c:134
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int octstr_hex_to_binary(Octstr *ostr)
Definition: octstr.c:492
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
int soap_msgtype_deps ( int  key_func_index,
Msg msg 
)

Definition at line 2555 of file smsc_soap.c.

References DC_7BIT, DC_8BIT, DC_UCS2, and error().

Referenced by soap_process_deps().

2556 {
2557  /* {"text","binary","unicode","default"} msgtype */
2558 
2559  /* ADD HERE: see order in funcs[][] */
2560  switch (key_func_index)
2561  {
2562  case 0: /* "text" */
2563  msg->sms.coding = DC_7BIT;
2564  break;
2565  case 1: /* "binary" */
2566  msg->sms.coding = DC_8BIT;
2567  break;
2568 
2569  case 2: /* "unicode" */
2570  case 3: /* "default" == unicode */
2571  msg->sms.coding = DC_UCS2;
2572  break;
2573  default:
2574  /* out of range */
2575  error(0, "SOAP: soap_msgtype_deps, unknown index %d", key_func_index);
2576  return -1;
2577  }
2578  return 0;
2579 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define DC_8BIT
Definition: sms.h:111
#define DC_UCS2
Definition: sms.h:112
#define DC_7BIT
Definition: sms.h:110
Octstr * soap_o2o_date_attribute ( Msg msg)

Definition at line 2856 of file smsc_soap.c.

References soap_write_date().

Referenced by soap_select_function().

2857 {
2858  return soap_write_date(msg->sms.time);
2859 }
static Octstr * soap_write_date(time_t date)
Definition: smsc_soap.c:1814
Octstr * soap_o2o_dlrmask_smsc_yn_attribute ( Msg msg)

Definition at line 2874 of file smsc_soap.c.

References DLR_IS_ENABLED_SMSC, and octstr_create.

Referenced by soap_select_function().

2875 {
2876  return octstr_create(DLR_IS_ENABLED_SMSC(msg->sms.dlr_mask) ? "Y" : "N");
2877 }
#define DLR_IS_ENABLED_SMSC(dlr)
Definition: dlr.h:83
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * soap_o2o_dlrmask_success_01_attribute ( Msg msg)

Definition at line 2880 of file smsc_soap.c.

References DLR_IS_SUCCESS, and octstr_create.

Referenced by soap_select_function().

2881 {
2882  return octstr_create( DLR_IS_SUCCESS(msg->sms.dlr_mask) ? "0" : "1");
2883 }
#define DLR_IS_SUCCESS(dlr)
Definition: dlr.h:86
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * soap_o2o_msgdata_attribute ( Msg msg,
PrivData privdata 
)

Definition at line 2718 of file smsc_soap.c.

References privdata::alt_charset, charset_convert(), DC_7BIT, DC_8BIT, DC_UCS2, DC_UNDEF, debug(), error(), O_DESTROY, octstr_append(), octstr_binary_to_base64(), octstr_convert_to_html_entities(), octstr_create, octstr_dump, octstr_duplicate, octstr_format(), octstr_get_cstr, and octstr_len().

Referenced by soap_select_function().

2719 {
2720  Octstr *data, *res, *udhres;
2721  int ret;
2722 
2723  data = octstr_duplicate(msg->sms.msgdata);
2724 
2725  if (msg->sms.coding == DC_8BIT) {
2726  debug("bb.soap.o2o_msgdata_attribute",0,"SOAP: base 64 encoding");
2728  res = octstr_format("<Control_Data>%S</Control_Data>", data);
2729 
2730  if (octstr_len(msg->sms.udhdata) > 0) { /* add UDH */
2731  O_DESTROY(data);
2732  data = octstr_duplicate(msg->sms.udhdata);
2733  debug("bb.soap.o2o_msgdata_attribute",0,"SOAP: UDH base 64 encoding");
2735  udhres = octstr_format("<UDH>%S</UDH>", data);
2736  octstr_append(res, udhres);
2737  O_DESTROY(udhres);
2738  }
2739  else {
2740  error(0, "SOAP: o2o_msgdata_attribute, UDH not defined");
2741  udhres = octstr_create("<UDH></UDH>");
2742  octstr_append(res, udhres);
2743  O_DESTROY(udhres);
2744  }
2745  O_DESTROY(data);
2746  return res;
2747  }
2748  else if (msg->sms.coding == DC_7BIT || msg->sms.coding == DC_UNDEF) {
2749  /* convert message data to target encoding */
2750  debug("bb.soap.o2o_msgdata_attribute", 0, "SOAP: converting from UTF-8 to %s", octstr_get_cstr(privdata->alt_charset));
2751  ret = charset_convert(data, "UTF-8", octstr_get_cstr(privdata->alt_charset));
2752  if (ret == -1) {
2753  error(0,"SOAP: soap_o2o_msgdata_attribute, charset_convert failed");
2754  octstr_dump(msg->sms.msgdata, 0);
2755  O_DESTROY(data);
2756  return NULL;
2757  }
2758  debug("bb.soap.o2o_msgdata_attribute",0,"SOAP: converting to HTML entities");
2760  res = octstr_format("<Message_Text>%S</Message_Text>", data);
2761  O_DESTROY(data);
2762  return res;
2763  }
2764  else if (msg->sms.coding == DC_UCS2) {
2765  /* convert message data to target encoding */
2766  debug("bb.soap.o2o_msgdata_attribute", 0, "converting from USC-2 to %s", octstr_get_cstr(privdata->alt_charset));
2767  ret = charset_convert(msg->sms.msgdata, "UCS-2BE", octstr_get_cstr(privdata->alt_charset));
2768  if (ret == -1) {
2769  error(0,"SOAP: soap_o2o_msgdata_attribute, charset_convert failed");
2770 
2771  octstr_dump(msg->sms.msgdata, 0);
2772  O_DESTROY(data);
2773  return NULL;
2774  }
2775  res = octstr_format("<Message_Text>%s</Message_Text>", data);
2776  O_DESTROY(data);
2777  return res;
2778  }
2779 
2780  else {
2781  error(0,"SOAP: soap_o2o_msgdata_attribute, unknown coding: %ld", msg->sms.coding);
2782  O_DESTROY(data);
2783  return NULL;
2784 
2785  }
2786 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define O_DESTROY(a)
Definition: smsc_soap.c:225
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
void octstr_binary_to_base64(Octstr *ostr)
Definition: octstr.c:540
#define DC_8BIT
Definition: sms.h:111
void octstr_convert_to_html_entities(Octstr *input)
Definition: octstr.c:2736
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int alt_charset
Definition: smsc_emi.c:134
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define DC_UNDEF
Definition: sms.h:109
#define DC_UCS2
Definition: sms.h:112
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589
#define DC_7BIT
Definition: sms.h:110
Octstr * soap_o2o_validity30_attribute ( Msg msg)

Definition at line 2839 of file smsc_soap.c.

References octstr_format(), SMS_PARAM_UNDEFINED, and SOAP_DEFAULT_VALIDITY.

Referenced by soap_select_function().

2840 {
2841  return octstr_format("%ld",(msg->sms.validity != SMS_PARAM_UNDEFINED ? (msg->sms.validity - time(NULL))/60 : SOAP_DEFAULT_VALIDITY) / 30);
2842 }
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
#define SMS_PARAM_UNDEFINED
Definition: sms.h:91
#define SOAP_DEFAULT_VALIDITY
Definition: smsc_soap.c:138
static long soap_parse_dlr ( SMSCConn conn,
Octstr request,
Octstr **  response 
)
static

Definition at line 1512 of file smsc_soap.c.

References bb_smscconn_receive(), smscconn::data, debug(), DLR_BUFFERED, DLR_FAIL, dlr_find(), privdata::dlr_spec_file, DLR_SUCCESS, privdata::dlr_xml_file, error(), gwlist_destroy(), smscconn::id, keywords, privdata::name, octstr_create, octstr_delete(), octstr_destroy(), octstr_get_cstr, octstr_imm(), octstr_search_char(), octstr_url_decode(), soap_create_map(), soap_destroy_map(), SOAP_ERROR_MALFORMED_DATA_CODE, SOAP_ERROR_MALFORMED_DATA_MESSAGE, SOAP_ERROR_NO_DATA_CODE, SOAP_ERROR_NO_DATA_MESSAGE, SOAP_ERROR_NO_DLR_CODE, SOAP_ERROR_NO_DLR_MESSAGE, soap_format_xml(), soap_map_xml_data(), and SOAP_QUERY_OK.

Referenced by soap_server().

1513 {
1514  PrivData *privdata = conn->data;
1515  xmlDocPtr requestDoc;
1516  xmlNodePtr root;
1517  Msg* dlrmsg = NULL;
1518  long dlrtype;
1519  int pos;
1520 
1521  List* maps;
1522  char receiver[30], soapdate[30], msgid[30];
1523  long result = -1;
1524  char* keywords[] = { "receiver", "soapdate", "id", "result" };
1525 
1526  char* sscans[] = { "%s", "%s", "%s", "%ld" };
1527  void* pointers[] = { &receiver, &soapdate, &msgid, &result };
1528 
1529  receiver[0] = soapdate[0] = msgid[0] = '\0';
1530 
1531  if (!response) /* how am I supposed to return a response now ? */
1532  return -1;
1533 
1534  if (!request) {
1536  return SOAP_ERROR_NO_DATA_CODE;
1537  }
1538 
1539  /* find the POST parameter name */
1540  if ( (pos = octstr_search_char(request,'=',0)) < 0) {
1541  /* didn't find it - */
1544  }
1545 
1546  /* cut of the parameter name - I'm not really interested in it */
1547  octstr_delete(request,0,pos+1);
1548 
1549  /* decode the URL encoded data */
1550  if (octstr_url_decode(request) < 0) {
1551  /* probably not URL encoded */
1554  }
1555 
1556  debug("bb.soap.parse_dlr",0,"SOAP[%s]: parse_dlr - DLR request dump <%s>", octstr_get_cstr(privdata->name),octstr_get_cstr(request));
1557 
1558  /* parse XML */
1559 
1560  if ( !(requestDoc = xmlParseDoc((xmlChar *)octstr_get_cstr(request))) ) {
1561  error(0,"SOAP[%s]: parse_dlr couldn't parse XML response", octstr_get_cstr(privdata->name));
1562  return -1;
1563  }
1564 
1565  /* get root element */
1566  if ( ! (root = xmlDocGetRootElement(requestDoc)) ) {
1567 
1568  error(0,"SOAP[%s]: parse_dlr couldn't get XML root element for request", octstr_get_cstr(privdata->name));
1569  xmlFreeDoc(requestDoc);
1570  return -1;
1571  }
1572 
1573  /* create the argument map */
1574 
1575  maps = soap_create_map(privdata->dlr_spec_file, 4, keywords, sscans, pointers);
1576 
1577  /* run the map and the xml through the parser */
1578  if (soap_map_xml_data(root, maps) < 4) {
1579  error(0,"SOAP[%s]: parse_dlr failed to map all the arguments from the XML data",
1580 
1581  octstr_get_cstr(privdata->name));
1582  }
1583 
1585 
1586  /* done with the document */
1587  xmlFreeDoc(requestDoc);
1588 
1589  if (strlen(msgid) == 0) {
1590  error(0,"SOAP: parse_dlr - failed to get message ID");
1593  }
1594 
1595  if (result == -1) {
1596 
1597  error(0,"SOAP: parse_dlr - failed to get delivery code");
1600  }
1601 
1602  /* we not need it because receiver now is constant string "receiver"
1603  if (strlen(receiver) == 0) {
1604  error(0,"SOAP: parse_dlr - failed to get receiver");
1605  *response = octstr_create(SOAP_ERROR_MALFORMED_DATA_MESSAGE);
1606  return SOAP_ERROR_MALFORMED_DATA_CODE;
1607  }
1608  */
1609  /* log the delivery code - this could be used to determine dlrtype (or so I hope) */
1610  debug("bb.soap.parse_dlr",0,"SOAP[%s]: parse_dlr DELIVERY_CODE : %ld", octstr_get_cstr(privdata->name),result);
1611  if (result == 0)
1612  dlrtype = DLR_SUCCESS;
1613  else
1614  dlrtype = DLR_FAIL;
1615 
1616  /* fetch the DLR */
1617 
1618  dlrmsg = dlr_find(conn->id, octstr_imm(msgid), octstr_imm("receiver"), /* destination */
1619  dlrtype, 0);
1620 
1621  if (!dlrmsg) {
1622  error(0,"SOAP[%s]: parse_dlr invoked (%ld), but no DLR found for MsgID %s", octstr_get_cstr(privdata->name),dlrtype,msgid);
1624  return SOAP_ERROR_NO_DLR_CODE;
1625  }
1626 
1627  debug("bb.soap.parse_dlr",0,"SOAP[%s]: parse_dlr found dlr", octstr_get_cstr(privdata->name));
1628  octstr_destroy(dlrmsg->sms.msgdata);
1629  switch (dlrtype) { /* change message according to DLR type */
1630  case DLR_SUCCESS:
1631  dlrmsg->sms.msgdata = octstr_create("Delivered");
1632  break;
1633  case DLR_BUFFERED:
1634  dlrmsg->sms.msgdata = octstr_create("Buffered");
1635  break;
1636  case DLR_FAIL:
1637  dlrmsg->sms.msgdata = octstr_create("Failed");
1638  break;
1639  default:
1640  break;
1641 
1642  }
1643 
1644  /*
1645  if (dlrmsg->sms.receiver) {
1646  octstr_destroy(dlrmsg->sms.sender);
1647  dlrmsg->sms.sender = dlrmsg->sms.receiver;
1648  }
1649  dlrmsg->sms.receiver = octstr_create(receiver);
1650  dlrmsg->sms.id = strtol(msgid, NULL, 10);
1651  */
1652 
1653  debug("bb.soap.parse_dlr",0,"SOAP[%s]: parse_dlr sent dlr <%s>", octstr_get_cstr(privdata->name),octstr_get_cstr(dlrmsg->sms.msgdata));
1654 
1655 
1656  *response = soap_format_xml(privdata->dlr_xml_file, dlrmsg, privdata);
1657  if (*response)
1658  debug("bb.soap.response_dlr",0,"SOAP[%s]: data dump: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(*response));
1659 
1660  /* send to bearerbox */
1661  bb_smscconn_receive(conn, dlrmsg);
1662 
1663  return SOAP_QUERY_OK;
1664 
1665 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define SOAP_ERROR_NO_DLR_MESSAGE
Definition: smsc_soap.c:146
#define SOAP_ERROR_NO_DATA_CODE
Definition: smsc_soap.c:157
Octstr * id
Definition: smscconn_p.h:174
void * data
Definition: smscconn_p.h:249
#define SOAP_QUERY_OK
Definition: smsc_soap.c:159
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
Msg * dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ, int use_dst)
Definition: dlr.c:387
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
static struct @117 keywords[]
#define DLR_SUCCESS
Definition: dlr.h:72
#define SOAP_ERROR_MALFORMED_DATA_MESSAGE
Definition: smsc_soap.c:150
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
Definition: msg.h:79
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:478
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define SOAP_ERROR_MALFORMED_DATA_CODE
Definition: smsc_soap.c:158
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
void soap_destroy_map(void *item)
Definition: smsc_soap.c:2143
Octstr * dlr_spec_file
Definition: smsc_soap.c:203
static Octstr * soap_format_xml(Octstr *xml_file, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:1014
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
#define SOAP_ERROR_NO_DLR_CODE
Definition: smsc_soap.c:153
#define SOAP_ERROR_NO_DATA_MESSAGE
Definition: smsc_soap.c:149
#define DLR_BUFFERED
Definition: dlr.h:74
int soap_map_xml_data(xmlNodePtr xml, List *maps)
Definition: smsc_soap.c:2282
Octstr * dlr_xml_file
Definition: smsc_soap.c:202
List * soap_create_map(Octstr *spec, long count, char *keywords[], char *types[], void *storage[])
Definition: smsc_soap.c:2088
Definition: list.c:102
#define DLR_FAIL
Definition: dlr.h:73
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static long soap_parse_mo ( SMSCConn conn,
Octstr request,
Octstr **  response 
)
static

Definition at line 1275 of file smsc_soap.c.

References bb_smscconn_receive(), smscconn::data, date(), date_convert_universal(), date_parse_iso(), debug(), error(), gwlist_destroy(), gwlist_len(), smscconn::id, keywords, privdata::mo_deps_file, privdata::mo_spec_file, privdata::mo_xml_file, msg, msg_create, privdata::name, octstr_create, octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_search_char(), octstr_url_decode(), soap_create_map(), SOAP_DEFAULT_SENDER_STRING, soap_destroy_map(), SOAP_ERROR_MALFORMED_DATA_CODE, SOAP_ERROR_MALFORMED_DATA_MESSAGE, SOAP_ERROR_NO_DATA_CODE, SOAP_ERROR_NO_DATA_MESSAGE, soap_format_xml(), soap_map_xml_data(), SOAP_QUERY_OK, and soap_release_dependences().

Referenced by soap_server().

1276 {
1277  PrivData *privdata = conn->data;
1278  xmlDocPtr requestDoc;
1279  xmlNodePtr root;
1280 
1281  Msg* msg;
1282  int pos = 0;
1283 
1284  long res = -1;
1285 
1286  List* maps;
1287  char receiver[30], sender[30], msgtype[30], msgdata[255], date[30];
1288  long long msgid = -1;
1289  char* keywords[] = { "receiver", "sender", "msgtype", "msgdata", "date", "id" };
1290  char* sscans[] = { "%s", "%s", "%s", "%s", "%s", "%lld" };
1291  void* pointers[] = { &receiver, &sender, &msgtype, &msgdata, &date, &msgid };
1292 
1293  receiver[0] = sender[0] = msgtype[0] = msgdata[0] = date[0] = '\0';
1294 
1295  if (!response) /* how am I supposed to return a response now ? */
1296  return -1;
1297 
1298  if (!request) {
1300  return SOAP_ERROR_NO_DATA_CODE;
1301  }
1302 
1303  /* find the POST parameter name */
1304  if ( (pos = octstr_search_char(request,'=',0)) < 0) {
1305  /* didn't find it - */
1308  }
1309 
1310  /* cut of the parameter name - I'm not really interested in it */
1311  octstr_delete(request,0,pos+1);
1312 
1313  /* decode the URL encoded data */
1314  if (octstr_url_decode(request) < 0) {
1315  /* probably not URL encoded */
1316 
1319  }
1320 
1321  debug("bb.soap.parse_mo",0,"SOAP[%s]: parse_mo - MO request dump <%s>", octstr_get_cstr(privdata->name),octstr_get_cstr(request));
1322 
1323  /* parse XML */
1324  if ( !(requestDoc = xmlParseDoc((xmlChar *)octstr_get_cstr(request))) ) {
1325  error(0,"SOAP[%s]: parse_mo couldn't parse XML response", octstr_get_cstr(privdata->name));
1326  return -1;
1327  }
1328 
1329  /* get root element */
1330  if ( ! (root = xmlDocGetRootElement(requestDoc)) ) {
1331  error(0,"SOAP[%s]: parse_mo couldn't get XML root element for request", octstr_get_cstr(privdata->name));
1332  xmlFreeDoc(requestDoc);
1333  return -1;
1334  }
1335 
1336  /* create the argument map */
1337  maps = soap_create_map(privdata->mo_spec_file, 6, keywords, sscans, pointers);
1338 
1339 
1340  /* run the map and the xml through the parser */
1341  if (soap_map_xml_data(root, maps) < gwlist_len(maps)) {
1342  error(0,"SOAP[%s]: parse_mo failed to map all the arguments from the XML data",
1343  octstr_get_cstr(privdata->name));
1344  }
1345 
1346  /* done with the document */
1347  xmlFreeDoc(requestDoc);
1348 
1349  if (strlen(receiver) == 0) {
1350  error(0,"SOAP: parse_mo - failed to get receiver");
1353  }
1354 
1355  if (strlen(sender) == 0) {
1356  error(0,"SOAP: parse_mo - failed to get sender");
1359  }
1360 
1361  if (strlen(msgdata) == 0) {
1362  error(0,"SOAP: parse_mo - failed to get message content");
1364 
1366  }
1367 
1368  /* create me a message to store data in it */
1369 
1370  msg = msg_create(sms);
1371 
1372  /*
1373  * XXX UUID is used, fix this.
1374 
1375  if (msgid == -1) {
1376  error(0,"SOAP: parse_mo - failed to get message ID, generate by itself");
1377  msg->sms.id = gw_generate_id();
1378  }
1379  */
1380 
1381  /* fill in the fields from the parsed arguments */
1382  msg->sms.sender = octstr_create(sender);
1383  msg->sms.receiver = octstr_create(receiver);
1384  /*
1385  * XXX UUID is used, fix this.
1386  msg->sms.id = msgid;
1387  */
1388  msg->sms.msgdata = octstr_create(msgdata);
1389 
1390  /* special processing and refill appropriate fields */
1391  if (privdata->mo_deps_file) {
1392  if ((res = soap_release_dependences(privdata->mo_deps_file, maps, msg, privdata))!=0)
1393  error(0,"SOAP: parse_mo - failed to release all dependences");
1394  }
1396 
1397  /* fill in the date */
1398  if (strlen(date)) {
1399  struct universaltime tm;
1400  Octstr* temp = octstr_create(date);
1401  if (date_parse_iso(&tm, temp))
1402  /* failed to parse the date */
1403  msg->sms.time = time(NULL);
1404  else
1405  msg->sms.time = date_convert_universal(&tm);
1406  octstr_destroy(temp);
1407  } else
1408  msg->sms.time = time(NULL);
1409 
1410  /*
1411  / * check message data type - B stands for "base 64 encoded" in Team Mobile * /
1412  if (!strcmp(msgtype, "B")) {
1413  octstr_base64_to_binary(msg->sms.msgdata);
1414  msg->sms.coding = DC_8BIT;
1415 
1416  } else if (!strcmp(msgtype, "binary")) {
1417  octstr_hex_to_binary(msg->sms.msgdata);
1418  msg->sms.coding = DC_8BIT;
1419  } else {
1420  */
1421 
1422  /* not gonna play this game - just convert from whatever alt_charset is set to, to UCS-2
1423  / * scan message for unicode chars (UTF-8 encoded) * /
1424  pos = 0;
1425  while (pos < octstr_len(msg->sms.msgdata)) {
1426  if (octstr_get_char(msg->sms.msgdata,pos) & 128)
1427  break;
1428  ++pos;
1429  }
1430 
1431  if (pos < octstr_len(msg->sms.msgdata)) {
1432  / * message has some unicode - we need to convert to UCS-2 first * /
1433  Octstr* temp = msg->sms.msgdata;
1434 
1435  msg->sms.coding = DC_UCS2;
1436  if (charset_from_utf8(temp, &(msg->sms.msgdata), octstr_imm("UCS-2")) < 0) {
1437  error(0,"SOAP[%s]: parse_mo couldn't convert msg text from UTF-8 to UCS-2. leaving as is.", octstr_get_cstr(privdata->name));
1438  O_DESTROY(msg->sms.msgdata);
1439  msg->sms.msgdata = octstr_duplicate(temp);
1440  / * set coding to 8bit and hope for the best * /
1441  msg->sms.coding = DC_8BIT;
1442 
1443  }
1444  octstr_destroy(temp);
1445  } else
1446  / * not unicode : 7bit * /
1447  msg->sms.coding = DC_7BIT;
1448  */
1449 
1450  /* if it's not binary, then assume unicode and convert from alt_charset to UCS-2 */
1451  /* msg->sms.coding = DC_UCS2;
1452 
1453 
1454 
1455  if (!octstr_case_compare(privdata->alt_charset, octstr_imm("UCS-2"))) {
1456  int ret = 0;
1457  debug("bb.soap.parse_mo",0,"SOAP[%s]: converting from %s to UCS-2BE",
1458  octstr_get_cstr(privdata->name), octstr_get_cstr(privdata->alt_charset));
1459  ret = charset_convert(msg->sms.msgdata, octstr_get_cstr(privdata->alt_charset), "UCS-2BE");
1460 
1461 
1462  if (ret == -1) {
1463  error(2,"SOAP[%s]: Error converting MO data from %s to unicode",
1464  octstr_get_cstr(privdata->name), octstr_get_cstr(privdata->alt_charset));
1465  } else if (ret != 0) {
1466  debug("bb.soap.parse_mo",1,"SOAP[%s]: charset_convert made %d irreversable transformations",
1467  octstr_get_cstr(privdata->name), ret);
1468  }
1469  }
1470  msg->sms.charset = octstr_create("UCS-2");
1471  }
1472  debug("bb.soap.parse_mo",0,"SOAP[%s]: message decoded -", octstr_get_cstr(privdata->name));
1473  octstr_dump(msg->sms.msgdata,0);
1474  */
1475 
1476  /* check that we have all the fields necessary */
1477  if (!(msg->sms.sender)
1478  ||
1479  !(msg->sms.msgdata)) {
1480  /* generate error message */
1483  }
1484 
1485  /* setup defaults */
1486  if (msg->sms.time <= 0)
1487  msg->sms.time = time(NULL);
1488 
1489  if (!msg->sms.receiver)
1490  msg->sms.receiver = octstr_create(SOAP_DEFAULT_SENDER_STRING);
1491 
1492  if (!msg->sms.smsc_id)
1493  msg->sms.smsc_id = octstr_duplicate(conn->id);
1494 
1495  *response = soap_format_xml(privdata->mo_xml_file,msg,privdata);
1496  if (*response)
1497  debug("bb.soap.response_dlr",0,"SOAP[%s]: data dump: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(*response));
1498 
1499  bb_smscconn_receive(conn,msg);
1500 
1501  return SOAP_QUERY_OK;
1502 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define SOAP_ERROR_NO_DATA_CODE
Definition: smsc_soap.c:157
Octstr * id
Definition: smscconn_p.h:174
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
long soap_release_dependences(Octstr *deps, List *lstmaps, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2404
#define SOAP_QUERY_OK
Definition: smsc_soap.c:159
int octstr_url_decode(Octstr *ostr)
Definition: octstr.c:1744
#define msg_create(type)
Definition: msg.h:136
Octstr * mo_spec_file
Definition: smsc_soap.c:201
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
static struct @117 keywords[]
#define SOAP_ERROR_MALFORMED_DATA_MESSAGE
Definition: smsc_soap.c:150
Definition: msg.h:79
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
long bb_smscconn_receive(SMSCConn *conn, Msg *sms)
Definition: bb_smscconn.c:478
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define SOAP_ERROR_MALFORMED_DATA_CODE
Definition: smsc_soap.c:158
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
void soap_destroy_map(void *item)
Definition: smsc_soap.c:2143
int date_parse_iso(struct universaltime *ut, Octstr *os)
Definition: date.c:227
static Octstr * soap_format_xml(Octstr *xml_file, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:1014
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * mo_xml_file
Definition: smsc_soap.c:200
Octstr * mo_deps_file
Definition: smsc_soap.c:204
#define SOAP_ERROR_NO_DATA_MESSAGE
Definition: smsc_soap.c:149
static int date(int hex)
int soap_map_xml_data(xmlNodePtr xml, List *maps)
Definition: smsc_soap.c:2282
long date_convert_universal(struct universaltime *t)
Definition: date.c:118
List * soap_create_map(Octstr *spec, long count, char *keywords[], char *types[], void *storage[])
Definition: smsc_soap.c:2088
Definition: list.c:102
#define SOAP_DEFAULT_SENDER_STRING
Definition: smsc_soap.c:137
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
static long long soap_parse_response ( PrivData privdata,
Octstr xmlResponse 
)
static

Definition at line 1205 of file smsc_soap.c.

References error(), gwlist_destroy(), keywords, privdata::mt_spec_file, privdata::name, octstr_get_cstr, soap_create_map(), soap_destroy_map(), soap_map_xml_data(), and warning().

Referenced by soap_read_response().

1206 {
1207  long long msgID = -1;
1208  long responseStatus = -1;
1209  xmlDocPtr responseDoc;
1210  xmlNodePtr root;
1211  List* maps;
1212  char* keywords[] = { "id", "result" };
1213  char* sscans[] = { "%lld", "%ld" };
1214  void* pointers[] = { &msgID, &responseStatus };
1215 
1216  if (!xmlResponse)
1217  return -1;
1218  /* FIXME: do something here */
1219 
1220  /* parse XML */
1221  if ( !(responseDoc = xmlParseDoc((xmlChar *)octstr_get_cstr(xmlResponse))) ) {
1222  error(0,"SOAP[%s]: couldn't parse XML response [ %s ] in MT parsing",
1223  octstr_get_cstr(privdata->name), octstr_get_cstr(xmlResponse));
1224  return -1;
1225  }
1226 
1227  /* get root element */
1228  if ( ! (root = xmlDocGetRootElement(responseDoc)) ) {
1229  error(0,"SOAP[%s]: couldn't get XML root element in MT parsing",
1230  octstr_get_cstr(privdata->name));
1231  xmlFreeDoc(responseDoc);
1232  return -1;
1233  }
1234 
1235  /* create the argument map */
1236  maps = soap_create_map(privdata->mt_spec_file, 2, keywords, sscans, pointers);
1237 
1238  /* run the map and the xml through the parser */
1239  if (soap_map_xml_data(root, maps) < 2) {
1240  error(0,"SOAP[%s]: failed to map all the arguments from the XML data",
1241  octstr_get_cstr(privdata->name));
1242  }
1243 
1245 
1246  /* done with the document */
1247  xmlFreeDoc(responseDoc);
1248 
1249  if (msgID == -1) {
1250  if (responseStatus == 0) { /* success without msg ID */
1251  warning(0, "SOAP[%s]: parse_response - the protocol does not support message ID",
1252  octstr_get_cstr(privdata->name));
1253  return 0;
1254  }
1255  else {
1256  error(0,"SOAP[%s]: parse_response - response code isn't 0 ! (%ld)",
1257  octstr_get_cstr(privdata->name), responseStatus);
1258  return -1; /* Nack */
1259  }
1260  }
1261  else
1262  return msgID; /* success with msg ID */
1263 
1264 }
void error(int err, const char *fmt,...)
Definition: log.c:612
Octstr * mt_spec_file
Definition: smsc_soap.c:199
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static struct @117 keywords[]
void warning(int err, const char *fmt,...)
Definition: log.c:624
Octstr * name
Definition: smsc_emi.c:96
void soap_destroy_map(void *item)
Definition: smsc_soap.c:2143
int soap_map_xml_data(xmlNodePtr xml, List *maps)
Definition: smsc_soap.c:2282
List * soap_create_map(Octstr *spec, long count, char *keywords[], char *types[], void *storage[])
Definition: smsc_soap.c:2088
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
int soap_process_deps ( int  key_index,
int  key_func_ind,
Msg msg,
PrivData privdata 
)

Definition at line 2536 of file smsc_soap.c.

References soap_msgdata_deps(), and soap_msgtype_deps().

Referenced by soap_release_dependences().

2537 {
2538  /* ADD HERE: MO 'key' functions */
2539  switch (key_index)
2540  {
2541  case 0:
2542  return soap_msgtype_deps(key_func_ind, msg);
2543  case 1:
2544  return soap_msgdata_deps(key_func_ind, msg, privdata);
2545  default:
2546  return -1;
2547  }
2548  return -1;
2549 }
int soap_msgdata_deps(int key_func_index, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2581
int soap_msgtype_deps(int key_func_index, Msg *msg)
Definition: smsc_soap.c:2555
static long soap_queued_cb ( SMSCConn conn)
static

Definition at line 688 of file smsc_soap.c.

References smscconn::data, gwlist_len(), smscconn::load, privdata::outgoing_queue, SMSCCONN_DEAD, and smscconn::status.

Referenced by smsc_soap_create().

689 {
690  PrivData *privdata = conn->data;
691  long ret;
692 
693  /* I'm dead, so I have no queues - well there ! */
694  if (conn->status == SMSCCONN_DEAD)
695  return -1;
696 
697  ret = gwlist_len(privdata->outgoing_queue);
698  /* + gwlist_len(privdata->pending_ack_queue); */
699 
700  /* use internal queue as load, maybe something else later */
701  conn->load = ret;
702 
703  return ret;
704 }
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
List * outgoing_queue
Definition: smsc_cgw.c:153
smscconn_status_t status
Definition: smscconn_p.h:151
int load
Definition: smscconn_p.h:152
Octstr * soap_rand_attribute ( Msg msg)

Definition at line 2868 of file smsc_soap.c.

References gw_rand(), and octstr_format().

Referenced by soap_select_function().

2869 {
2870  return octstr_format("%d",gw_rand());
2871 }
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
int gw_rand(void)
Definition: protected.c:174
time_t soap_read_date ( Octstr dateString)

Definition at line 1777 of file smsc_soap.c.

References date_convert_universal(), universaltime::day, debug(), universaltime::hour, universaltime::minute, universaltime::month, octstr_get_cstr, octstr_len(), octstr_parse_long(), universaltime::second, and universaltime::year.

1778 {
1779  int pos, count;
1780  struct universaltime stTime;
1781  long arTime[5];
1782 
1783 
1784  if (!dateString) /* sanity check */
1785  return -1;
1786 
1787  pos = count = 0;
1788  /* tricky control structures are my favourite among complicated expressions ;-) */
1789  while (count < 5 && pos < octstr_len(dateString) &&
1790  (pos = octstr_parse_long(&(arTime[count++]),dateString, pos,10)) && pos != -1)
1791  ++pos;
1792 
1793  if (count < 5) {
1794  /* error parsing the date */
1795  debug("bb.soap.read_date",0,"read_date failed parsing the date value <%s>", octstr_get_cstr(dateString));
1796  return -1;
1797  }
1798 
1799  stTime.day = arTime[0];
1800  stTime.month = arTime[1];
1801  stTime.year = arTime[2];
1802  stTime.hour = arTime[3];
1803  stTime.minute = arTime[4];
1804  stTime.second = 0;
1805  return date_convert_universal(&stTime);
1806 }
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
Definition: octstr.c:747
long date_convert_universal(struct universaltime *t)
Definition: date.c:118
static void soap_read_response ( SMSCConn conn)
static

Definition at line 1118 of file smsc_soap.c.

References bb_smscconn_send_failed(), bb_smscconn_sent(), client_data::caller, smscconn::data, debug(), dlr_add(), gwlist_len(), http_destroy_headers(), http_receive_result, smscconn::id, msg, privdata::name, O_DESTROY, octstr_create, octstr_get_cstr, octstr_imm(), client_data::requests, SMSCCONN_FAILED_MALFORMED, privdata::soap_client, soap_client_have_response(), and soap_parse_response().

Referenced by soap_listener().

1119 {
1120  PrivData *privdata = conn->data;
1121  Msg* msg;
1122  Octstr *responseBody, *responseURL;
1123  List* responseHeaders;
1124  int responseStatus;
1125  long long msgID;
1126  ClientData* cd;
1127 
1128  /* don't get in here unless I have some callers */
1129  /* (I shouldn't have one before I start sending messages) */
1130  if (!gwlist_len(privdata->soap_client))
1131  return;
1132 
1133 
1134  /* see if we have any responses pending */
1135  if (!(cd = soap_client_have_response(privdata->soap_client)))
1136  return;
1137 
1138  cd->requests--;
1139  msg = http_receive_result(cd->caller, &responseStatus, &responseURL, &responseHeaders, &responseBody);
1140 
1141  if (!msg) /* no responses here */
1142  {
1143  debug("bb.soap.read_response",0,"SOAP[%s]: sorry, no response", octstr_get_cstr(privdata->name));
1144  return;
1145  }
1146 
1147  if (responseStatus == -1) {
1148  debug("bb.soap.read_response",0,"SOAP[%s]: HTTP connection failed - blame the server (requeing msg)",
1149  octstr_get_cstr(privdata->name));
1150  bb_smscconn_send_failed(conn, msg,
1152  /* bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY); */
1153  /* gwlist_append(privdata->outgoing_queue, msg); */
1154  return;
1155  }
1156 
1157  debug("bb.soap.read_response",0,"SOAP[%s]: got a response %d= %s",
1158  octstr_get_cstr(privdata->name), responseStatus, responseBody?octstr_get_cstr(responseBody):octstr_get_cstr(octstr_imm("NULL")));
1159 
1160 
1161  /* got a message from HTTP, parse it */
1162  if ( (msgID = soap_parse_response(privdata, responseBody)) >= 0)
1163  { /* ack with msg ID */
1164  char tmpid[30];
1165 
1166  /*
1167  * XXX UUID is used, fix this.
1168 
1169  if (msgID == 0)
1170  msgID = msg->sms.id;
1171  */
1172 
1173  sprintf(tmpid,"%lld",msgID);
1174  debug("bb.soap.read_response",0,"SOAP[%s]: ACK - id: %lld", octstr_get_cstr(privdata->name), msgID);
1175 
1176  dlr_add(conn->id, octstr_imm(tmpid), msg, 0);
1177 
1178  /* send msg back to bearerbox for recycling */
1179  bb_smscconn_sent(conn, msg, NULL);
1180  }
1181 
1182  else { /* nack */
1183  debug("bb.soap.read_response",0,"SOAP[%s]: NACK", octstr_get_cstr(privdata->name));
1184 
1185  /* send msg back to bearerbox for recycling */
1186  bb_smscconn_send_failed(conn, msg,
1188  }
1189 
1190  http_destroy_headers(responseHeaders);
1191  O_DESTROY(responseBody);
1192  O_DESTROY(responseURL);
1193 }
static ClientData * soap_client_have_response(List *client_list)
Definition: smsc_soap.c:2009
#define O_DESTROY(a)
Definition: smsc_soap.c:225
Octstr * id
Definition: smscconn_p.h:174
long gwlist_len(List *list)
Definition: list.c:166
void * data
Definition: smscconn_p.h:249
HTTPCaller * caller
Definition: smsc_soap.c:211
void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg, int use_dst)
Definition: dlr.c:330
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
static long long soap_parse_response(PrivData *privdata, Octstr *xmlResponse)
Definition: smsc_soap.c:1205
Definition: msg.h:79
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
#define http_receive_result(caller, status, final_url, headers, body)
Definition: http.h:383
Definition: octstr.c:118
void bb_smscconn_sent(SMSCConn *conn, Msg *sms, Octstr *reply)
Definition: bb_smscconn.c:279
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
unsigned long requests
Definition: smsc_soap.c:210
List * soap_client
Definition: smsc_soap.c:189
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long soap_release_dependences ( Octstr deps,
List lstmaps,
Msg msg,
PrivData privdata 
)

Definition at line 2404 of file smsc_soap.c.

References error(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), O_DESTROY, octstr_create, octstr_destroy_item(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_split(), octstr_split_words(), octstr_str_compare(), octstr_strip_blanks(), octstr_strip_crlfs(), soap_get_index(), soap_process_deps(), SPEC_DEFAULT, and argument_map::store.

Referenced by soap_parse_mo().

2405 {
2406  List *issues;
2407  long i, j, key_index, key_deps_index, map_index;
2408  int res, k;
2409  List *issue_items, *header_item;
2410  int key_func_index;
2411  ArgumentMap* map;
2412  Octstr *header, *key, *key_deps;
2413  Octstr *func_alias = NULL, *block;
2414 
2415  /* follows keys and funcs identifiers must be
2416  * the same as in a 'deps' file
2417  **/
2418 
2419 
2420  /* structure of file_deps;
2421  *
2422  * <key> <key_deps>
2423  * <key_deps_value> <function_alias>
2424  * <key_deps_value> <function_alias>
2425  * ;
2426  */
2427 
2428  /* ADD HERE: */
2429 
2430  char* funcs[][5] = { /* functions aliasis used in mo.deps file */
2431  {"text","binary","unicode","default"}, /* msgtype */
2432  {"set_iso","64_binary","hex_binary","unicode","default"} /* msgdata */
2433  };
2434 
2435 
2436  issues = octstr_split(file_deps, octstr_imm(";")); /* get paragraphs */
2437 
2438  if (gwlist_len(issues) == 0) {
2439  error(0, "SOAP: soap_release_dependences, empty or broken 'deps' file");
2440  return -1;
2441  }
2442 
2443  for (i=0; i<gwlist_len(issues); ++i) /* loop paragraphs */
2444  {
2445  block = gwlist_get(issues, i);
2446  octstr_strip_crlfs(block);
2447  octstr_strip_blanks(block);
2448 
2449  issue_items = octstr_split(block, octstr_imm("\n"));
2450  if (gwlist_len(issue_items) < 2) {
2451  error(0, "SOAP: soap_release_dependences, broken file 'deps' can't find any definition for <key>");
2452  gwlist_destroy(issue_items, octstr_destroy_item);
2454  return -1;
2455  }
2456 
2457 
2458  header = gwlist_extract_first(issue_items);
2459  header_item = octstr_split_words(header); /* header content */
2460  O_DESTROY(header);
2461 
2462  if (gwlist_len(header_item) < 2) {
2463  error(0, "SOAP: soap_release_dependences, broken 'deps' file in <key> <key_deps> part");
2464  gwlist_destroy(header_item, octstr_destroy_item);
2465  gwlist_destroy(issue_items, octstr_destroy_item);
2467  return -1;
2468  }
2469 
2470  key = gwlist_get(header_item, 0);
2471  key_deps = gwlist_get(header_item, 1);
2472  key_index = soap_get_index(lstmaps, key, 0); /* search key_index */
2473  key_deps_index = soap_get_index(lstmaps, key_deps, 0); /* search key_deps_index, from what depends */
2474 
2475  if (key_index == -1 || key_deps_index == -1) {
2476  gwlist_destroy(header_item, octstr_destroy_item);
2477  gwlist_destroy(issue_items, octstr_destroy_item);
2479  return -1;
2480  }
2481 
2482  map_index = soap_get_index(lstmaps, key_deps, 1); /* get index for map->name==key_deps */
2483  map = gwlist_get(lstmaps, map_index);
2484 
2485  /* search <function_identifier> and if not found try to set default */
2486  for (j=0; j < gwlist_len(issue_items); ++j) {
2487 
2488  Octstr *tmp = gwlist_get(issue_items, j);
2489  List *row = octstr_split_words(tmp);
2490 
2491  if (!octstr_str_compare(gwlist_get(row, 0), map->store)) {
2492  func_alias = octstr_duplicate(gwlist_get(row, 1));
2494  break;
2495  }
2496 
2497  if (j==gwlist_len(issue_items)-1) {
2498  error(0, "SOAP: soap_release_dependences, \
2499  can't find function_alias for <%s> in 'deps' file, set default", (char*)map->store);
2500  func_alias = octstr_create(SPEC_DEFAULT);
2501  }
2503  }
2504 
2505  key_func_index = -1;
2506  /* searching index of function by its alias */
2507  for (k=0; k < sizeof(funcs[key_index])/sizeof(funcs[key_index][0]); ++k)
2508  {
2509  if (!octstr_str_compare(func_alias, funcs[key_index][k])) {
2510  key_func_index = k;
2511  break;
2512  }
2513  }
2514  if (key_func_index==-1)
2515  error(0, "SOAP: soap_release_dependences, can't find function for alias <%s>", octstr_get_cstr(func_alias));
2516 
2517  O_DESTROY(func_alias);
2518 
2519  gwlist_destroy(header_item, octstr_destroy_item);
2520  gwlist_destroy(issue_items, octstr_destroy_item);
2521 
2522  /* which field has deps, which func need be called, msg need be changed */
2523  if ((res=soap_process_deps(key_index, key_func_index, msg, privdata)) < 0)
2524  error(0, "SOAP: soap_release_dependences, error processing dependent value");
2525  }
2527 
2528 
2529  return 0; /* OK */
2530 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define O_DESTROY(a)
Definition: smsc_soap.c:225
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1344
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void * gwlist_extract_first(List *list)
Definition: list.c:305
#define octstr_duplicate(ostr)
Definition: octstr.h:187
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1600
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
#define SPEC_DEFAULT
Definition: smsc_soap.c:170
void octstr_strip_crlfs(Octstr *text)
Definition: octstr.c:1376
Definition: octstr.c:118
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:971
void * store
Definition: smsc_soap.c:220
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
int soap_get_index(List *where, Octstr *key, int map_index)
Definition: smsc_soap.c:2889
int soap_process_deps(int key_index, int key_func_ind, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2536
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
Octstr * soap_select_function ( int  index,
Msg msg,
PrivData privdata 
)

Definition at line 2663 of file smsc_soap.c.

References error(), soap_bouyg_content_attribute(), soap_bouyg_validity_attribute(), soap_mobitai_content_attribute(), soap_mobitai_date_attribute(), soap_mobitai_validity_date_attribute(), soap_msgdata_attribute(), soap_o2o_date_attribute(), soap_o2o_dlrmask_smsc_yn_attribute(), soap_o2o_dlrmask_success_01_attribute(), soap_o2o_msgdata_attribute(), soap_o2o_validity30_attribute(), and soap_rand_attribute().

Referenced by soap_convert_token().

2664 {
2665  /* ADD HERE: XML functions */
2666  switch (index)
2667  {
2668  case 0:
2669  return soap_bouyg_content_attribute(msg);
2670  case 1:
2671  return soap_mobitai_content_attribute(msg);
2672  case 2:
2673  return soap_o2o_msgdata_attribute(msg, privdata);
2674  case 3:
2675  return soap_msgdata_attribute(msg, privdata); /* mobitai/bouyg */
2676  case 4:
2677  return soap_o2o_validity30_attribute(msg);
2678  case 5:
2680  case 6:
2681  return soap_bouyg_validity_attribute(msg);
2682  case 7:
2683  return soap_o2o_date_attribute(msg);
2684  case 8:
2685  return soap_mobitai_date_attribute(msg);
2686  case 9:
2687  return soap_rand_attribute(msg);
2688  case 10:
2690  case 11:
2692  default:
2693  error(0,"SOAP: soap_select_function can't find function");
2694  return NULL;
2695  }
2696 }
void error(int err, const char *fmt,...)
Definition: log.c:612
Octstr * soap_rand_attribute(Msg *msg)
Definition: smsc_soap.c:2868
Octstr * soap_mobitai_date_attribute(Msg *msg)
Definition: smsc_soap.c:2863
Octstr * soap_o2o_validity30_attribute(Msg *msg)
Definition: smsc_soap.c:2839
Octstr * soap_bouyg_validity_attribute(Msg *msg)
Definition: smsc_soap.c:2851
Octstr * soap_mobitai_content_attribute(Msg *msg)
Definition: smsc_soap.c:2709
Octstr * soap_o2o_dlrmask_smsc_yn_attribute(Msg *msg)
Definition: smsc_soap.c:2874
Octstr * soap_o2o_date_attribute(Msg *msg)
Definition: smsc_soap.c:2856
Octstr * soap_bouyg_content_attribute(Msg *msg)
Definition: smsc_soap.c:2700
Octstr * soap_mobitai_validity_date_attribute(Msg *msg)
Definition: smsc_soap.c:2845
Octstr * soap_o2o_msgdata_attribute(Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2718
Octstr * soap_o2o_dlrmask_success_01_attribute(Msg *msg)
Definition: smsc_soap.c:2880
Octstr * soap_msgdata_attribute(Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:2789
static void soap_send ( PrivData privdata,
Octstr xmlbuffer,
Msg msgid 
)
static

Definition at line 1080 of file smsc_soap.c.

References privdata::form_urlencoded, privdata::form_variable, http_create_empty_headers(), http_destroy_headers(), http_header_add(), O_DESTROY, octstr_format(), and soap_client_init_query().

Referenced by soap_send_loop().

1081 {
1082  List *requestHeaders;
1083  Octstr* postdata;
1084 
1085  /* create request headers */
1086  requestHeaders = http_create_empty_headers();
1087  http_header_add(requestHeaders, "User-Agent", "Kannel " GW_VERSION);
1088 
1089  if (privdata->form_urlencoded) {
1090  http_header_add(requestHeaders, "Content-Type", "application/x-www-form-urlencoded");
1091  postdata = octstr_format("%S=%E", privdata->form_variable, xmlbuffer);
1092  } else {
1093  http_header_add(requestHeaders, "Content-Type", "multipart/form-data, boundary=AaB03x");
1094  postdata = octstr_format("--AaB03x\r\n"
1095  "content-disposition: form-data; name=\"%S\"\r\n\r\n%S",
1096  privdata->form_variable, xmlbuffer);
1097  }
1098 
1099  /* send the request along */
1100  soap_client_init_query(privdata, requestHeaders, postdata, msg);
1101 
1102  O_DESTROY(postdata);
1103 
1104  /* done with that */
1105  http_destroy_headers(requestHeaders);
1106 
1107  return;
1108 
1109 }
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define O_DESTROY(a)
Definition: smsc_soap.c:225
int form_urlencoded
Definition: smsc_soap.c:195
void http_destroy_headers(List *headers)
Definition: http.c:2856
List * http_create_empty_headers(void)
Definition: http.c:2849
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
Octstr * form_variable
Definition: smsc_soap.c:194
static void soap_client_init_query(PrivData *privdata, List *headers, Octstr *data, Msg *msg)
Definition: smsc_soap.c:1933
Definition: octstr.c:118
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void soap_send_loop ( SMSCConn conn)
static

Definition at line 963 of file smsc_soap.c.

References bb_smscconn_send_failed(), counter, smscconn::data, debug(), gwlist_extract_first(), msg, privdata::mt_xml_file, privdata::name, O_DESTROY, octstr_create, octstr_get_cstr, privdata::outgoing_queue, SMSCCONN_FAILED_MALFORMED, soap_format_xml(), SOAP_MAX_MESSAGE_PER_ROUND, soap_send(), uuid_generate(), and uuid_is_null().

Referenced by soap_listener().

964 {
965  PrivData* privdata = conn->data;
966  Msg *msg;
967  Octstr* xmldata = NULL;
968  int counter = 0;
969 
970  debug("bb.soap.client",0,"SOAP[%s]: client - entering",
971  octstr_get_cstr(privdata->name));
972 
973  while ((counter < SOAP_MAX_MESSAGE_PER_ROUND) &&
974  (msg = gwlist_extract_first(privdata->outgoing_queue))) {
975  /* as long as we have some messages */
976  ++counter;
977 
978  if (uuid_is_null(msg->sms.id)) /* generate a message id */
979  uuid_generate(msg->sms.id);
980 
981  /* format the messages as a character buffer to send */
982  if (!(xmldata = soap_format_xml(privdata->mt_xml_file, msg, privdata))) {
983  debug("bb.soap.client",0,"SOAP[%s]: client - failed to format message for sending",
984  octstr_get_cstr(privdata->name));
985  bb_smscconn_send_failed(conn, msg,
987  continue;
988  }
989 
990  debug("bb.soap.client",0,"SOAP[%s]: client - Sending message <%s>",
991  octstr_get_cstr(privdata->name), octstr_get_cstr(msg->sms.msgdata));
992  if (xmldata)
993  debug("bb.soap.client",0,"SOAP[%s]: data dump: %s",
994  octstr_get_cstr(privdata->name), octstr_get_cstr(xmldata));
995 
996  /* send to the server */
997  soap_send(privdata, xmldata, msg);
998 
999  /* store in the second queue so that soap_read_response will know what to do */
1000  /* gwlist_append(privdata->pending_ack_queue,msg); */
1001 
1002  /* don't need this anymore */
1003  O_DESTROY(xmldata);
1004  }
1005 }
#define O_DESTROY(a)
Definition: smsc_soap.c:225
#define SOAP_MAX_MESSAGE_PER_ROUND
Definition: smsc_soap.c:136
void * data
Definition: smscconn_p.h:249
List * outgoing_queue
Definition: smsc_cgw.c:153
void uuid_generate(uuid_t out)
Definition: gw_uuid.c:392
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * mt_xml_file
Definition: smsc_soap.c:198
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
int uuid_is_null(const uuid_t uu)
Definition: gw_uuid.c:412
static void soap_send(PrivData *privdata, Octstr *xmlbuffer, Msg *msgid)
Definition: smsc_soap.c:1080
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
static Octstr * soap_format_xml(Octstr *xml_file, Msg *msg, PrivData *privdata)
Definition: smsc_soap.c:1014
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static Counter * counter
static void soap_server ( void *  arg)
static

Definition at line 850 of file smsc_soap.c.

References smscconn::data, date_format_http(), debug(), error(), gwlist_destroy(), gwthread_sleep(), http_accept_request(), http_create_empty_headers(), http_destroy_headers(), http_header_add(), http_send_reply(), privdata::name, O_DESTROY, octstr_compare(), octstr_create, octstr_get_cstr, octstr_imm(), privdata::port, SOAP_DEFAULT_CODE, SOAP_DEFAULT_MESSAGE, SOAP_DLR_URI, SOAP_ERROR_DLR_CODE, SOAP_ERROR_DLR_MESSAGE, SOAP_ERROR_MO_CODE, SOAP_ERROR_MO_MESSAGE, SOAP_MO_URI, soap_parse_dlr(), soap_parse_mo(), privdata::soap_server, and SOAP_SLEEP_TIME.

Referenced by soap_server_start().

851 {
852  SMSCConn* conn = (SMSCConn*)arg;
853  PrivData* privdata = conn->data;
854  /* PrivData* privdata = (PrivData*)arg; */
855 
856  HTTPClient* remote_client = NULL;
857  List *request_headers = NULL, *response_headers = NULL;
858  List *cgivars = NULL;
859  Octstr *client_ip = NULL, *request_uri = NULL, *request_body = NULL;
860  Octstr *response_body = NULL;
861  Octstr *timebuf = NULL;
862  int http_response_status;
863 
864  debug("bb.soap.server",0,"SOAP[%s]: Server starting",
865  octstr_get_cstr(privdata->name));
866 
867  /* create basic headers */
868  response_headers = http_create_empty_headers();
869  http_header_add(response_headers, "Content-type","text/xml");
870  /* http_header_add(response_headers, "Content-type","application/x-www-form-urlencoded"); */
871  /* http_header_add(response_headers,"Connection", "Close"); */
872  http_header_add(response_headers, "Server","Kannel");
873 
874  while (privdata->soap_server) {
875  if ((remote_client = http_accept_request(privdata->port,
876  &client_ip, &request_uri, &request_headers,
877  &request_body, &cgivars))) {
878 
879  debug("bb.soap.server",0,"SOAP[%s]: server got a request for "
880  "%s from %s, with body <%s>", octstr_get_cstr(privdata->name),
881  octstr_get_cstr(request_uri),octstr_get_cstr(client_ip),
882  request_body ? octstr_get_cstr(request_body) : "<null>");
883 
884  /* parse request */
885  if (!octstr_compare(request_uri,octstr_imm(SOAP_MO_URI))) {
886  /* this is an incoming MO */
887  if ((http_response_status =
888  soap_parse_mo(conn,request_body, &response_body)) == -1) {
889  /* fatal error parsing MO */
890  error(0,"SOAP[%s]: fatal error parsing MO",
891  octstr_get_cstr(privdata->name));
892  response_body = octstr_create(SOAP_ERROR_MO_MESSAGE);
893  http_response_status = SOAP_ERROR_MO_CODE;
894  }
895  } else if (!octstr_compare(request_uri,octstr_imm(SOAP_DLR_URI))) {
896  /* a delivery report */
897  if ((http_response_status =
898  soap_parse_dlr(conn,request_body, &response_body)) == -1) {
899  /* fatal error parsing MO */
900  error(0,"SOAP[%s]: fatal error parsing DLR",
901  octstr_get_cstr(privdata->name));
902  response_body = octstr_create(SOAP_ERROR_DLR_MESSAGE);
903  http_response_status = SOAP_ERROR_DLR_CODE;
904  }
905  } else {
906  /* unknown command send default message */
907  response_body = octstr_create(SOAP_DEFAULT_MESSAGE);
908  http_response_status = SOAP_DEFAULT_CODE;
909  }
910 
911  /* create response */
912  /*
913  response_body = octstr_create("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
914  "<!DOCTYPE SMSCACCESS_REPLY SYSTEM \"http://superion/~oded/smsc_reply-1_0.dtd\">\n"
915  "<SMSCACCESS_REPLY>\n"
916  " <SUBSCRIBER>447951718145</SUBSCRIBER>\n"
917  " <DATE_RECEIVED>22/01/2002:15:12</DATE_RECEIVED>\n"
918  " <RETURN_CODE>00</RETURN_CODE>\n"
919  "</SMSCACCESS_REPLY>\n");
920  */
921 
922  /* encode date in headers */
923 
924  timebuf = date_format_http(time(NULL));
925  /* http_header_add(response_headers, "Date", octstr_get_cstr(timebuf)); */
926  O_DESTROY(timebuf);
927  /* http_header_dump(response_headers); */
928 
929  /* send response back to client */
930  http_send_reply(remote_client,http_response_status,response_headers, response_body);
931 
932  /* destroy response data */
933  /* http_destroy_headers(response_headers); */
934  O_DESTROY(response_body);
935 
936  /* destroy request data */
937  O_DESTROY(request_uri);
938  O_DESTROY(request_body);
939  O_DESTROY(client_ip);
940 
941  http_destroy_headers(request_headers);
942  gwlist_destroy(cgivars, NULL);
943  }
944 
946  }
947 
948  debug("bb.soap.server",0,"SOAP[%s]: server going down",
949  octstr_get_cstr(privdata->name));
950  /* privdata->server_thread = 0; */
951 }
int port
Definition: smsc_cgw.c:159
static long soap_parse_mo(SMSCConn *conn, Octstr *request, Octstr **response)
Definition: smsc_soap.c:1275
void error(int err, const char *fmt,...)
Definition: log.c:612
void http_header_add(List *headers, char *name, char *contents)
Definition: http.c:2863
#define O_DESTROY(a)
Definition: smsc_soap.c:225
void * data
Definition: smscconn_p.h:249
#define SOAP_DEFAULT_MESSAGE
Definition: smsc_soap.c:145
#define SOAP_SLEEP_TIME
Definition: smsc_soap.c:135
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_destroy_headers(List *headers)
Definition: http.c:2856
void http_send_reply(HTTPClient *client, int status, List *headers, Octstr *body)
Definition: http.c:2671
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
#define SOAP_MO_URI
Definition: smsc_soap.c:141
HTTPClient * http_accept_request(int port, Octstr **client_ip, Octstr **url, List **headers, Octstr **body, List **cgivars)
Definition: http.c:2574
List * http_create_empty_headers(void)
Definition: http.c:2849
#define SOAP_ERROR_DLR_MESSAGE
Definition: smsc_soap.c:147
int soap_server
Definition: smsc_soap.c:180
#define SOAP_ERROR_MO_MESSAGE
Definition: smsc_soap.c:148
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * name
Definition: smsc_emi.c:96
void gwthread_sleep(double seconds)
#define SOAP_ERROR_DLR_CODE
Definition: smsc_soap.c:155
#define SOAP_DEFAULT_CODE
Definition: smsc_soap.c:154
Definition: octstr.c:118
#define SOAP_ERROR_MO_CODE
Definition: smsc_soap.c:156
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
Octstr * date_format_http(unsigned long unixtime)
Definition: date.c:89
#define SOAP_DLR_URI
Definition: smsc_soap.c:142
static long soap_parse_dlr(SMSCConn *conn, Octstr *request, Octstr **response)
Definition: smsc_soap.c:1512
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
int soap_server_start ( SMSCConn conn)

Definition at line 1845 of file smsc_soap.c.

References smscconn::data, debug(), error(), gwthread_create, http_close_port(), http_open_port(), privdata::name, octstr_get_cstr, privdata::port, privdata::server_thread, privdata::soap_server, soap_server(), and privdata::ssl.

Referenced by soap_listener().

1846 {
1847  PrivData* privdata = conn->data;
1848 
1849  debug("bb.soap.server_stop",0,"SOAP[%s]: Starting HTTP server", octstr_get_cstr(privdata->name));
1850  /* start the HTTP server */
1851  if (http_open_port(privdata->port,privdata->ssl)) {
1852  return -1;
1853  }
1854 
1855 
1856  /* raise server flag */
1857  privdata->soap_server = 1;
1858 
1859  if ( (privdata->server_thread = gwthread_create(soap_server, conn)) == -1)
1860  {
1861  error(0, "SOAP[%s]: server_start failed to create server thread!", octstr_get_cstr(privdata->name));
1862  http_close_port(privdata->port);
1863  return -1;
1864  }
1865 
1866 
1867  return 0;
1868 }
int port
Definition: smsc_cgw.c:159
void error(int err, const char *fmt,...)
Definition: log.c:612
static void soap_server(void *arg)
Definition: smsc_soap.c:850
void * data
Definition: smscconn_p.h:249
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_close_port(int port)
Definition: http.c:2504
int soap_server
Definition: smsc_soap.c:180
#define gwthread_create(func, arg)
Definition: gwthread.h:90
Octstr * name
Definition: smsc_emi.c:96
int http_open_port(int port, int ssl)
Definition: http.c:2498
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
int ssl
Definition: smsc_soap.c:183
long server_thread
Definition: smsc_soap.c:177
static void soap_server_stop ( PrivData privdata)
static

Definition at line 1875 of file smsc_soap.c.

References debug(), gwthread_join(), gwthread_wakeup(), http_close_port(), privdata::name, octstr_get_cstr, privdata::port, privdata::server_thread, and privdata::soap_server.

Referenced by soap_listener().

1876 {
1877  /* time_t start = time(NULL); */
1878 
1879  debug("bb.soap.server_stop",0,"SOAP[%s]: Stopping HTTP server", octstr_get_cstr(privdata->name));
1880  /* signal the server thread to stop */
1881  privdata->soap_server = 0;
1882 
1883  /* close the http server thread */
1884  http_close_port(privdata->port);
1885 
1886  if (privdata->server_thread) {
1887  gwthread_wakeup(privdata->server_thread);
1888  gwthread_join(privdata->server_thread);
1889  privdata->server_thread = 0;
1890  }
1891 
1892 
1893  /*
1894  / * wait upto 5 minutes for our server thread to shutdown * /
1895  while (privdata->server_thread && (start + 300 > time(NULL)))
1896  gwthread_sleep(SOAP_SLEEP_TIME);
1897 
1898 
1899  if (privdata->server_thread) {
1900  error(0,"SOAP[%s]: our server refuses to die!", octstr_get_cstr(privdata->name));
1901  privdata->server_thread = 0; / * dump it either way * /
1902 
1903  }*/
1904 
1905  debug("bb.soap.server_stop",0,"SOAP[%s]: Done stopping HTTP server", octstr_get_cstr(privdata->name));
1906 }
int port
Definition: smsc_cgw.c:159
void gwthread_join(long thread)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void http_close_port(int port)
Definition: http.c:2504
int soap_server
Definition: smsc_soap.c:180
Octstr * name
Definition: smsc_emi.c:96
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwthread_wakeup(long thread)
long server_thread
Definition: smsc_soap.c:177
static int soap_shutdown_cb ( SMSCConn conn,
int  finish_sending 
)
static

Definition at line 594 of file smsc_soap.c.

References bb_smscconn_send_failed(), smscconn::data, debug(), gwlist_extract_first(), gwthread_join(), gwthread_wakeup(), privdata::listener_thread, msg, privdata::name, octstr_get_cstr, privdata::outgoing_queue, privdata::shutdown, SMSCCONN_DEAD, SMSCCONN_FAILED_SHUTDOWN, SMSCCONN_KILLED_SHUTDOWN, smscconn::status, and smscconn::why_killed.

Referenced by smsc_soap_create().

595 {
596  PrivData *privdata = conn->data;
597  long thread;
598 
599  /* I'm dead, there's really no point in killing me again, is it ? */
600  if (conn->status == SMSCCONN_DEAD)
601  return -1;
602 
603  debug("bb.soap.cb", 0, "SOAP[%s]: Shutting down SMSCConn, %s",
604  octstr_get_cstr(privdata->name), finish_sending ? "slow" : "instant");
605 
606  /* Documentation claims this would have been done by smscconn.c,
607  * but isn't when this code is being written.*/
609  /* Separate from why_killed to avoid locking,
610  * as why_killed may be changed from outside? */
611  privdata->shutdown = 1;
612 
613  if (finish_sending == 0) {
614  Msg *msg;
615  while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL)
617  }
618 
619  thread = privdata->listener_thread;
620 
621  gwthread_wakeup(thread);
622  gwthread_join(thread);
623 
624  return 0;
625 }
void gwthread_join(long thread)
void * data
Definition: smscconn_p.h:249
List * outgoing_queue
Definition: smsc_cgw.c:153
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long listener_thread
Definition: smsc_soap.c:176
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
Octstr * name
Definition: smsc_emi.c:96
int shutdown
Definition: smsc_cgw.c:156
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
void gwthread_wakeup(long thread)
smscconn_status_t status
Definition: smscconn_p.h:151
void bb_smscconn_send_failed(SMSCConn *conn, Msg *sms, int reason, Octstr *reply)
Definition: bb_smscconn.c:328
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
static void soap_start_cb ( SMSCConn conn)
static

Definition at line 634 of file smsc_soap.c.

References smscconn::data, debug(), error(), gwthread_create, privdata::listener_thread, privdata::name, octstr_get_cstr, privdata::shutdown, SMSCCONN_CONNECTING, SMSCCONN_DEAD, SMSCCONN_KILLED_CANNOT_CONNECT, soap_listener(), smscconn::status, and smscconn::why_killed.

Referenced by smsc_soap_create().

635 {
636  PrivData *privdata = conn->data;
637 
638  debug("smsc.soap.start", 0, "SOAP[%s]: start called",
639  octstr_get_cstr(privdata->name));
640 
641  /* set the status so that connection_thread will know what to do */
642  conn->status = SMSCCONN_CONNECTING;
643 
644  /* start connection_thread, in case its not started. */
645  if ((!privdata->listener_thread) &&
646  ((privdata->listener_thread = gwthread_create(soap_listener, conn)) == -1)) {
647  error(0, "SOAP: soap_start, failed to spawn thread - aborting");
649  conn->status = SMSCCONN_DEAD;
650  privdata->shutdown = 1;
651  return;
652  }
653  /* gwthread_wakeup(privdata->listener_thread); */
654  debug("smsc.soap.start",0,"SOAP[%s]: starting OK",
655  octstr_get_cstr(privdata->name));
656 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void * data
Definition: smscconn_p.h:249
static void soap_listener(void *arg)
Definition: smsc_soap.c:718
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long listener_thread
Definition: smsc_soap.c:176
smscconn_killed_t why_killed
Definition: smscconn_p.h:153
#define gwthread_create(func, arg)
Definition: gwthread.h:90
Octstr * name
Definition: smsc_emi.c:96
int shutdown
Definition: smsc_cgw.c:156
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
smscconn_status_t status
Definition: smscconn_p.h:151
static void soap_stop_cb ( SMSCConn conn)
static

Definition at line 665 of file smsc_soap.c.

References smscconn::data, debug(), privdata::name, octstr_get_cstr, SMSCCONN_DEAD, SMSCCONN_DISCONNECTED, and smscconn::status.

Referenced by smsc_soap_create().

666 {
667  PrivData *privdata = conn->data;
668 
669  /* I'm dead, its really too late to take a break now */
670  if (conn->status == SMSCCONN_DEAD)
671  return;
672 
673  debug("smsc.soap.stop", 0, "SOAP[%s]: stop called",
674  octstr_get_cstr(privdata->name));
675 
676  /* make connection thread disconnect */
678 }
void * data
Definition: smscconn_p.h:249
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * name
Definition: smsc_emi.c:96
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
smscconn_status_t status
Definition: smscconn_p.h:151
static Octstr * soap_write_date ( time_t  date)
static

Definition at line 1814 of file smsc_soap.c.

References octstr_create, and octstr_format().

Referenced by soap_o2o_date_attribute().

1815 {
1816  struct tm date_parts;
1817  Octstr* out;
1818 
1819  if (date < 0)
1820  /* sanity check - I don't think it should ever happen, but I don't want to get
1821  support calls at 2am because some gateway in the UK went bananas. */
1822  return octstr_create("ERROR");
1823 
1824  /* split up epoch time to elements */
1825  gmtime_r(&date, &date_parts);
1826 
1827  out = octstr_format("%d/%02d/%02d:%02d:%02d",
1828  date_parts.tm_year + 1900, date_parts.tm_mon + 1, date_parts.tm_mday, date_parts.tm_hour, date_parts.tm_min);
1829 
1830  /* again */
1831  if (out)
1832  return out;
1833  else
1834  return octstr_create("ERROR");
1835  /* assuming octstr_create never fails, unlike octstr_format. this is not the case currently (both cannot fail), but it may change */
1836 }
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
static int date(int hex)
int soap_xmlnode_get_int64 ( xmlNodePtr  cur,
long long *  out 
)

Definition at line 1712 of file smsc_soap.c.

References error().

1713 {
1714  xmlChar* nodeContent;
1715  char* endPointer;
1716 
1717  if (!out) /* sanity check */
1718  return -1;
1719 
1720  /* get content of tag */
1721  if (!(nodeContent = xmlNodeGetContent(cur))) {
1722  error(0,"SOAP: get_long - xml Node has content !");
1723  return -1;
1724  }
1725 
1726 
1727  /* read the content into output */
1728  *out = strtoll((char *)nodeContent,&endPointer,10);
1729  xmlFree(nodeContent);
1730 
1731  if (endPointer == (char*)nodeContent) {
1732  error(0,"SOAP: get_long - node has non-numeric content <%s>", nodeContent);
1733  return -1;
1734  }
1735 
1736  return 0;
1737 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int soap_xmlnode_get_long ( xmlNodePtr  cur,
long *  out 
)

Definition at line 1679 of file smsc_soap.c.

References error().

1680 {
1681  xmlChar* nodeContent;
1682  char* endPointer;
1683 
1684  if (!out) /* sanity check */
1685  return -1;
1686 
1687  /* get content of tag */
1688  if (!(nodeContent = xmlNodeGetContent(cur))) {
1689  error(0,"SOAP: get_long - xml Node has content !");
1690  return -1;
1691  }
1692 
1693  /* read the content into output */
1694  *out = strtol((char *)nodeContent,&endPointer,10);
1695  xmlFree(nodeContent);
1696 
1697  if (endPointer == (char*)nodeContent) {
1698  error(0,"SOAP: get_long - node has non-numeric content <%s>", nodeContent);
1699  return -1;
1700  }
1701 
1702  return 0;
1703 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int soap_xmlnode_get_octstr ( xmlNodePtr  cur,
Octstr **  out 
)

Definition at line 1746 of file smsc_soap.c.

References error(), and octstr_create.

1747 {
1748  xmlChar* nodeContent;
1749 
1750  if (!out) /* sanity check */
1751  return -1;
1752 
1753  /* get content of tag */
1754  if (!(nodeContent = xmlNodeGetContent(cur))) {
1755  error(0,"SOAP: get_octstr - xml Node has content !");
1756  return -1;
1757  }
1758 
1759  /* store the content into output */
1760  *out = octstr_create((char *)nodeContent);
1761  xmlFree(nodeContent);
1762 
1763  if (*out)
1764  return 0;
1765  else
1766  return -1;
1767 
1768 
1769 }
void error(int err, const char *fmt,...)
Definition: log.c:612
#define octstr_create(cstr)
Definition: octstr.h:125
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.