⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsp_unit.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 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 org@kannel.org.  *  * 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.   */ /* * wsp_unit.c - Implement WSP Connectionless mode * * Lars Wirzenius */#include <string.h>#include "gwlib/gwlib.h"#include "wsp.h"#include "wsp_pdu.h"#include "wsp_headers.h"#include "wap_events.h"#include "wsp_strings.h"#include "wap.h"/* * Give the status the module: * *	limbo *		not running at all *	running *		operating normally *	terminating *		waiting for operations to terminate, returning to limbo */static enum { limbo, running, terminating } run_status = limbo;static wap_dispatch_func_t *dispatch_to_wdp;static wap_dispatch_func_t *dispatch_to_appl;static List *queue = NULL;static void main_thread(void *);static WAPEvent *pack_into_result_datagram(WAPEvent *event);static WAPEvent *pack_into_push_datagram(WAPEvent *event);/*********************************************************************** * Public functions */void wsp_unit_init(wap_dispatch_func_t *datagram_dispatch,                   wap_dispatch_func_t *application_dispatch) {	queue = list_create();	list_add_producer(queue);	dispatch_to_wdp = datagram_dispatch;	dispatch_to_appl = application_dispatch;        wsp_strings_init();	run_status = running;	gwthread_create(main_thread, NULL);}void wsp_unit_shutdown(void) {	gw_assert(run_status == running);	run_status = terminating;	list_remove_producer(queue);	gwthread_join_every(main_thread);	list_destroy(queue, wap_event_destroy_item);        wsp_strings_shutdown();}void wsp_unit_dispatch_event(WAPEvent *event) {	wap_event_assert(event);	list_produce(queue, event);}static WAPEvent *unpack_datagram(WAPEvent *datagram) {	WAPEvent *event;	Octstr *os;	WSP_PDU *pdu;	long tid_byte;	int method;	Octstr *method_name;	gw_assert(datagram->type == T_DUnitdata_Ind);		os = NULL;	pdu = NULL;	event = NULL;	os = octstr_duplicate(datagram->u.T_DUnitdata_Ind.user_data);	if (os && octstr_len(os) == 0) {		warning(0, "WSP UNIT: Empty datagram.");		goto error;	}		tid_byte = octstr_get_char(os, 0);	octstr_delete(os, 0, 1);		pdu = wsp_pdu_unpack(os);	if (pdu == NULL)		goto error;		if (pdu->type != Get && pdu->type != Post) {		warning(0, "WSP UNIT: Unsupported PDU type %d", pdu->type);		goto error;	}        	event = wap_event_create(S_Unit_MethodInvoke_Ind);	event->u.S_Unit_MethodInvoke_Ind.addr_tuple = wap_addr_tuple_duplicate(                datagram->u.T_DUnitdata_Ind.addr_tuple);	event->u.S_Unit_MethodInvoke_Ind.transaction_id = tid_byte;        	switch (pdu->type) {	case Get:		debug("wap.wsp", 0, "Connectionless Get request received.");		method = GET_METHODS + pdu->u.Get.subtype;		event->u.S_Unit_MethodInvoke_Ind.request_uri = 			octstr_duplicate(pdu->u.Get.uri);		event->u.S_Unit_MethodInvoke_Ind.request_headers = 			wsp_headers_unpack(pdu->u.Get.headers, 0);		event->u.S_Unit_MethodInvoke_Ind.request_body = NULL;		break;	case Post:		debug("wap.wsp", 0, "Connectionless Post request received.");                method = POST_METHODS + pdu->u.Post.subtype;		event->u.S_Unit_MethodInvoke_Ind.request_uri = 			octstr_duplicate(pdu->u.Post.uri);		event->u.S_Unit_MethodInvoke_Ind.request_headers = 			wsp_headers_unpack(pdu->u.Post.headers, 1);		event->u.S_Unit_MethodInvoke_Ind.request_body = 			octstr_duplicate(pdu->u.Post.data);		break;	default:		warning(0, "WSP UNIT: Unsupported PDU type %d", pdu->type);		goto error;	}	method_name = wsp_method_to_string(method);	if (method_name == NULL)		method_name = octstr_format("UNKNOWN%02X", method);	event->u.S_Unit_MethodInvoke_Ind.method = method_name;	octstr_destroy(os);	wsp_pdu_destroy(pdu);	return event;error:	octstr_destroy(os);	wsp_pdu_destroy(pdu);	wap_event_destroy(event);	return NULL;}/*********************************************************************** * Local functions */static void main_thread(void *arg) {    WAPEvent *e;    WAPEvent *newevent;	    while (run_status == running && (e = list_consume(queue)) != NULL) {        debug("wap.wsp.unit", 0, "WSP (UNIT): event arrived");        wap_event_assert(e);        switch (e->type) {            case T_DUnitdata_Ind:                newevent = unpack_datagram(e);                if (newevent != NULL)                    dispatch_to_appl(newevent);                break;            case S_Unit_MethodResult_Req:                newevent = pack_into_result_datagram(e);                if (newevent != NULL)                    dispatch_to_wdp(newevent);                break;            case S_Unit_Push_Req:                newevent = pack_into_push_datagram(e);                if (newevent != NULL)                     dispatch_to_wdp(newevent);                debug("wsp.unit", 0, "WSP (UNIT): delivering to wdp");                break;	            default:                warning(0, "WSP UNIT: Unknown event type %d", e->type);                break;        }        wap_event_destroy(e);    }}/* * We do not set TUnitData.ind's SMS-specific fields here, because we do not * support sending results to the phone over SMS. Wsp, chapter 8.4.1 states * that "that each peer entity is always associated with an encoding version.". * So we add Encoding-Version when we are sending something to the client. * (This includes push, which is not directly mentioned in chapter 8.4.2.70).  */static WAPEvent *pack_into_result_datagram(WAPEvent *event) {	WAPEvent *datagram;	struct S_Unit_MethodResult_Req *p;	WSP_PDU *pdu;	Octstr *ospdu;	unsigned char tid;		gw_assert(event->type == S_Unit_MethodResult_Req);	p = &event->u.S_Unit_MethodResult_Req;    http_header_add(p->response_headers, "Encoding-Version", "1.3");	pdu = wsp_pdu_create(Reply);	pdu->u.Reply.status = wsp_convert_http_status_to_wsp_status(p->status);	pdu->u.Reply.headers = wsp_headers_pack(p->response_headers, 1, WSP_1_3);	pdu->u.Reply.data = octstr_duplicate(p->response_body);	ospdu = wsp_pdu_pack(pdu);	wsp_pdu_destroy(pdu);	if (ospdu == NULL)		return NULL;	tid = p->transaction_id;	octstr_insert_data(ospdu, 0, &tid, 1);	datagram = wap_event_create(T_DUnitdata_Req);	datagram->u.T_DUnitdata_Req.addr_tuple =		wap_addr_tuple_duplicate(p->addr_tuple);	datagram->u.T_DUnitdata_Req.user_data = ospdu;	return datagram;}/* * According to WSP table 12, p. 63, push id and transaction id are stored  * into same field. T-UnitData.ind is different for IP and SMS bearer. */static WAPEvent *pack_into_push_datagram(WAPEvent *event) {        WAPEvent *datagram;        WSP_PDU *pdu;        Octstr *ospdu;	unsigned char push_id;        gw_assert(event->type == S_Unit_Push_Req);        debug("wap.wsp.unit", 0, "WSP_UNIT: Connectionless push accepted");        http_header_add(event->u.S_Unit_Push_Req.push_headers,                         "Encoding-Version", "1.3");        pdu = wsp_pdu_create(Push);	pdu->u.Push.headers = wsp_headers_pack(            event->u.S_Unit_Push_Req.push_headers, 1, WSP_1_3);	pdu->u.Push.data = octstr_duplicate(            event->u.S_Unit_Push_Req.push_body);        ospdu = wsp_pdu_pack(pdu);	wsp_pdu_destroy(pdu);	if (ospdu == NULL)	    return NULL;        push_id = event->u.S_Unit_Push_Req.push_id;	octstr_insert_data(ospdu, 0, &push_id, 1);        datagram = wap_event_create(T_DUnitdata_Req);        datagram->u.T_DUnitdata_Req.addr_tuple =	    wap_addr_tuple_duplicate(event->u.S_Unit_Push_Req.addr_tuple);        datagram->u.T_DUnitdata_Req.address_type = 	    event->u.S_Unit_Push_Req.address_type;        if (event->u.S_Unit_Push_Req.smsc_id != NULL)            datagram->u.T_DUnitdata_Req.smsc_id =                octstr_duplicate(event->u.S_Unit_Push_Req.smsc_id);        else            datagram->u.T_DUnitdata_Req.smsc_id = NULL;        if (event->u.S_Unit_Push_Req.dlr_url != NULL)            datagram->u.T_DUnitdata_Req.dlr_url =                octstr_duplicate(event->u.S_Unit_Push_Req.dlr_url);        else            datagram->u.T_DUnitdata_Req.dlr_url = NULL;        datagram->u.T_DUnitdata_Req.dlr_mask = event->u.S_Unit_Push_Req.dlr_mask;        if (event->u.S_Unit_Push_Req.smsbox_id != NULL)            datagram->u.T_DUnitdata_Req.smsbox_id =                octstr_duplicate(event->u.S_Unit_Push_Req.smsbox_id);        else                   datagram->u.T_DUnitdata_Req.smsbox_id = NULL;        datagram->u.T_DUnitdata_Req.service_name =            octstr_duplicate(event->u.S_Unit_Push_Req.service_name);	datagram->u.T_DUnitdata_Req.user_data = ospdu;                return datagram;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -