wsp_unit.c

来自「mms client」· C语言 代码 · 共 276 行

C
276
字号
/* * 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 (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) {        wap_event_assert(e);        switch (e->type) {            case T_DUnitdata_Ind:                newevent = unpack_datagram(e);                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);                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. */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;    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);    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");    pdu = wsp_pdu_create(Push);    pdu->u.Push.headers = wsp_headers_pack(                                          event->u.S_Unit_Push_Req.push_headers, 1);    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;    datagram->u.T_DUnitdata_Req.user_data = ospdu;    debug("wap.wsp.unit", 0, "WSP_UNIT: delivering to wdp");    return datagram;}

⌨️ 快捷键说明

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