wsp_unit_client.c

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

C
231
字号
/* * wsp_unit_client.c - Implement client for 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 *unitclientqueue = 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_client_init(wap_dispatch_func_t *datagram_dispatch, wap_dispatch_func_t *application_dispatch) {    unitclientqueue = list_create();    list_add_producer(unitclientqueue);    dispatch_to_wdp = datagram_dispatch;    dispatch_to_appl = application_dispatch;    wsp_strings_init();    run_status = running;    gwthread_create(main_thread, NULL);}void wsp_unit_client_shutdown(void) {    gw_assert(run_status == running);    run_status = terminating;    list_remove_producer(unitclientqueue);    gwthread_join_every(main_thread);    list_destroy(unitclientqueue, wap_event_destroy_item);    wsp_strings_shutdown();}void wsp_unit_client_dispatch_event(WAPEvent *event) {    wap_event_assert(event);    list_produce(unitclientqueue, 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 CLIENT: Empty datagram.");        goto error;    }    octstr_dump(os, 0);    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 != Push) {        warning(0, "WSP UNIT CLIENT: Unsupported PDU type %d", pdu->type);        goto error;    }    event = wap_event_create(S_Unit_Push_Ind);    event->u.S_Unit_Push_Ind.addr_tuple = wap_addr_tuple_duplicate(datagram->u.T_DUnitdata_Ind.addr_tuple);    event->u.S_Unit_Push_Ind.push_id = tid_byte;    event->u.S_Unit_Push_Ind.push_headers = wsp_headers_unpack(pdu->u.Push.headers, 1);    event->u.S_Unit_Push_Ind.push_body = octstr_duplicate(pdu->u.Push.data);    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(unitclientqueue)) != NULL) {        wap_event_assert(e);        switch (e->type) {            case T_DUnitdata_Ind:                newevent = unpack_datagram(e);                dispatch_to_appl(newevent);                break;            default:                warning(0, "WSP UNIT CLIENT: 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 + -
显示快捷键?