[PATCH] SOAP module for kannel

"Vincent CHAVANIS" <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <065e01c74ac3$5ed739f0$9600a8c0@vince>
Changes:
- Allow In smscconn.c the use of smsc_soap_create()
- Fixes segfault when having wrong config parameters
- Spliting definitions into new file <smsc_soap.h>
- Using global value SOAP_DEFAULT_SENDER_STRING as GW_NAME

regards

Vincent

--
Telemaque - 06560 SOPHIA-ANTIPOLIS - (FR)
Service Technique/Reseau - NOC 
Developpement SMS/MMS/Kiosques
http://www.telemaque.fr/
[email protected]
Tel : +33 4 92 90 99 84 (fax 9142)
smsc_soap.h (application/octet-stream, 11.2 KB)
/* ==================================================================== 
 * The Kannel Software License, Version 1.0 
 * 
 * Copyright (c) 2001-2007 Kannel Group  
 * Copyright (c) 1998-2001 WapIT Ltd.   
 * All rights reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in 
 *    the documentation and/or other materials provided with the 
 *    distribution. 
 * 
 * 3. The end-user documentation included with the redistribution, 
 *    if any, must include the following acknowledgment: 
 *       "This product includes software developed by the 
 *        Kannel Group (http://www.kannel.org/)." 
 *    Alternately, this acknowledgment may appear in the software itself, 
 *    if and wherever such third-party acknowledgments normally appear. 
 * 
 * 4. The names "Kannel" and "Kannel Group" must not be used to 
 *    endorse or promote products derived from this software without 
 *    prior written permission. For written permission, please  
 *    contact [email protected]. 
 * 
 * 5. Products derived from this software may not be called "Kannel", 
 *    nor may "Kannel" appear in their name, without prior written 
 *    permission of the Kannel Group. 
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 * ==================================================================== 
 * 
 * This software consists of voluntary contributions made by many 
 * individuals on behalf of the Kannel Group.  For more information on  
 * the Kannel Group, please see <http://www.kannel.org/>. 
 * 
 * Portions of this software are based upon software originally written at  
 * WapIT Ltd., Helsinki, Finland for the Kannel project.  
 */ 

#include "gwlib/gwlib.h"

/* libxml include */
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

/* Defines and defaults */
#define SOAP_SLEEP_TIME				0.01
#define SOAP_MAX_MESSAGE_PER_ROUND 		1
#define SOAP_DEFAULT_SENDER_STRING		GW_NAME
#define SOAP_DEFAULT_VALIDITY           60

/* URIs for MOs and delivery reports */
#define SOAP_MO_URI	        "/mo"
#define SOAP_DLR_URI		"/dlr"

/* default reponses to HTTP queries */
#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>"

/* map HTTP status codes to SOAP HTTP reply codes */
#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

/* compile time configuration defines */
#undef HUMAN_TIME

#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"

/* private data store for the SOAP module */
typedef struct privdata {
    List *outgoing_queue;	/* queue to hold unsent messages */

    long listener_thread;	/* SOAP HTTP client and module managment */
    long server_thread; 	/* SOAP HTTP server */

    int shutdown;		/* Internal signal to shut down */
    int soap_server;	/* internal signal to shut down the server */

    long port;    	        /* listener port */
    int ssl;		/* flag whether to use SSL for the server */

    Octstr *uri;		/* URI to send MTs on */

    Octstr *allow_ip, *deny_ip; /* connection allowed mask */

    List* soap_client;  /* list to hold callers */

    Octstr* name;		/* connection name for use in private functions that want to do logging */

    /* SOAP configurtion */
    Octstr* form_variable; /* variable name used in post */
    int form_urlencoded; /* whether to send the data urlencoded or multipart */
    Octstr* alt_charset;   /* alt-charset to use */

    Octstr* mt_xml_file;
    Octstr* mt_spec_file;
    Octstr* mo_xml_file;
    Octstr* mo_spec_file;
    Octstr* dlr_xml_file;
    Octstr* dlr_spec_file;
    Octstr* mo_deps_file;
} PrivData;

/* struct to hold one HTTP client connection (I hope) */
typedef struct client_data {
    time_t last_access;
    unsigned long requests;
    HTTPCaller* caller;
} ClientData;

/* struct useful for the XML mapping routines */
typedef struct argument_map {
    Octstr* name;
    Octstr* path;
    Octstr* attribute;
    Octstr* sscan_type;
    void* store;
} ArgumentMap;

/* useful macros go here (some of these were ripped of other modules,
   so maybe its better to put them in a shared file) */
#define	O_DESTROY(a)	{ if(a) octstr_destroy(a); a=NULL; }
typedef long long int64;
 
/*
 * SOAP module public API towards bearerbox
 */

/* module entry point - will also be defined in smscconn_p.h */
int smsc_soap_create(SMSCConn *conn, CfgGroup *cfg);
/* callback for bearerbox to add messages to our queue */
static int soap_add_msg_cb(SMSCConn *conn, Msg *sms);
/* callback for bearerbox to signal a shutdown */
static int soap_shutdown_cb(SMSCConn *conn, int finish_sending);
/* callback for bearerbox to signal us to start the connection */
static void soap_start_cb(SMSCConn *conn);
/* callback for bearerbox to signal us to drop the connection */
static void soap_stop_cb(SMSCConn *conn);
/* callback for bearerbox to query on the number of messages in our queue */
static long soap_queued_cb(SMSCConn *conn);
 
/*
 * SOAP module thread functions (created by smsc_soap_create())
 */

/* SOAP module thread for launching HTTP clients. */
static void soap_listener(void *arg);
/* SOAP HTTP server thread for incoming MO */
static void soap_server(void *arg);
 
/*
 * SOAP module internal protocol implementation functions
 */

/* start the loop to send all messages in the queue */
static void soap_send_loop(SMSCConn *conn);
/* function used to send a single MT message */
static void soap_send(PrivData *privdata, Octstr *xmlbuffer, Msg *msgid);
/* called to retrieve HTTP responses from the HTTP library */
static void soap_read_response(SMSCConn *conn);
/* format a messages structure as an XML buffer */
static Octstr *soap_format_xml(Octstr *xml_file, Msg *msg, PrivData *privdata);
/* parse a response from the SOAP server to get the message ID */

static int64 soap_parse_response(PrivData *privdata, Octstr *xmlResponse);
/* parse an incoming MO xml */
static long soap_parse_mo(SMSCConn *conn, Octstr *request, Octstr **response);
/* parse an incoming derlivery report */
static long soap_parse_dlr(SMSCConn *conn, Octstr *request, Octstr **response);

/*
 * SOAP internal utility functions
 */
/* parse an integer out of a XML node */
int soap_xmlnode_get_long(xmlNodePtr cur, long *out);
/* parse an int64 out of a XML node */
int soap_xmlnode_get_int64(xmlNodePtr cur, int64 *out);
/* parse a string out of a XML node */
int soap_xmlnode_get_octstr(xmlNodePtr cur, Octstr **out);
/* convert a one2one date format to epoch time */
time_t soap_read_date(Octstr *dateString);
/* convert a epoch time to one2one date format */
static Octstr *soap_write_date(time_t date);
/* start the SOAP server */
int soap_server_start(SMSCConn *conn);
/* stop the SOAP server */
static void soap_server_stop(PrivData *privdata);
/* create a new SOAP client caller */
static ClientData *soap_create_client_data();
/* destroy a SOAP client caller */
static void soap_destroy_client_data(void *data);
/* start an HTTP query */
static void soap_client_init_query(PrivData *privdata, List *headers, Octstr *data, Msg *msg);
/* return a caller from the pool that has responses waiting */
static ClientData *soap_client_have_response(List *client_list);
/* return data from a message according to its name */
static Octstr *soap_convert_token(Msg *msg, Octstr *name, PrivData *privdata);
/* convert a XML parsing spec file and a list of recognized keywords to an argument map */
List *soap_create_map(Octstr* spec, long count, char* keywords[], char* types[], void* storage[]);
/* destroy a map structure */
void soap_destroy_map(void *item);
/* map content in a XML structure to a list of variable using a spec file */
int soap_map_xml_data(xmlNodePtr xml, List* maps);
/* fetch content from the XML */
Octstr* soap_fetch_xml_data(xmlNodePtr xml, Octstr* path);

/* MO */
/* search and release dependences for keys */
long soap_release_dependences(Octstr* deps, List* lstmaps, Msg* msg, PrivData *privdata);
/* for appropriate <key> call function referenced by key_func_ind */
int soap_process_deps(int key_index, int key_func_ind, Msg* msg, PrivData *privdata);

/* <key>s specific functions */
int soap_msgtype_deps(int key_func_index, Msg* msg);
int soap_msgdata_deps(int key_func_index, Msg* msg, PrivData *privdata);
 
/* MT */
/* return index of functions alias in array of function aliases */
int soap_lookup_function(Octstr* funcname);

/* select function by index */
Octstr* soap_select_function(int index, Msg* msg, PrivData* privdata);

Octstr* soap_bouyg_content_attribute(Msg* msg);
Octstr* soap_mobitai_content_attribute(Msg* msg);
Octstr* soap_o2o_msgdata_attribute(Msg* msg, PrivData *privdata);
Octstr* soap_msgdata_attribute(Msg* msg, PrivData* privdata);
Octstr* soap_o2o_validity30_attribute(Msg* msg);
Octstr* soap_mobitai_validity_date_attribute(Msg* msg);
Octstr* soap_bouyg_validity_attribute(Msg* msg);
Octstr* soap_o2o_date_attribute(Msg* msg);
Octstr* soap_mobitai_date_attribute(Msg* msg);
Octstr* soap_rand_attribute(Msg* msg);
Octstr* soap_o2o_dlrmask_smsc_yn_attribute(Msg* msg);
Octstr* soap_o2o_dlrmask_success_01_attribute(Msg* msg);

/* searching 'key' in 'where' and return index of element or -1 */
int soap_get_index(List* where, Octstr* key, int map_index);
patch.soap (application/octet-stream, 11.9 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.