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

📄 wap_push_ppg.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 5 页
字号:
    ota_event->u.Po_Unit_Push_Req.push_id = pm->push_id;    ota_event->u.Po_Unit_Push_Req.push_headers = push_headers;    ota_event->u.Po_Unit_Push_Req.authenticated = pm->authenticated;    ota_event->u.Po_Unit_Push_Req.trusted = pm->trusted;    ota_event->u.Po_Unit_Push_Req.last = last;    ota_event->u.Po_Unit_Push_Req.address_type = pm->address_type;    if (pm->smsc_id != NULL)        ota_event->u.Po_Unit_Push_Req.smsc_id = octstr_duplicate(pm->smsc_id);    else        ota_event->u.Po_Unit_Push_Req.smsc_id = NULL;    if (pm->dlr_url != NULL)        ota_event->u.Po_Unit_Push_Req.dlr_url = octstr_duplicate(pm->dlr_url);    else        ota_event->u.Po_Unit_Push_Req.dlr_url = NULL;    ota_event->u.Po_Unit_Push_Req.dlr_mask = pm->dlr_mask;    if (pm->smsbox_id != NULL)           ota_event->u.Po_Unit_Push_Req.smsbox_id = octstr_duplicate(pm->smsbox_id);    else        ota_event->u.Po_Unit_Push_Req.smsbox_id = NULL;    if (pm->service_name != NULL)            ota_event->u.Po_Unit_Push_Req.service_name = octstr_duplicate(pm->service_name);    ota_event->u.Po_Unit_Push_Req.push_body = octstr_duplicate(pm->push_data);    dispatch_to_ota(ota_event);    debug("wap.push.ppg", 0, "PPG: OTA request for unit push");}static void request_push(long last, PPGPushMachine *pm){    WAPEvent *ota_event;    List *push_headers;    gw_assert(last == 0 || last == 1);    push_machine_assert(pm);        push_headers = http_header_duplicate(pm->push_headers);    ota_event = wap_event_create(Po_Push_Req);    ota_event->u.Po_Push_Req.push_headers = push_headers;    ota_event->u.Po_Push_Req.authenticated = pm->authenticated;    ota_event->u.Po_Push_Req.trusted = pm->trusted;    ota_event->u.Po_Push_Req.last = last;    if (pm->push_data != NULL)        ota_event->u.Po_Push_Req.push_body =             octstr_duplicate(pm->push_data);    else        ota_event->u.Po_Push_Req.push_body = NULL;            ota_event->u.Po_Push_Req.session_handle = pm->session_id;    debug("wap.push.ppg", 0, "PPG: OTA request for push");        dispatch_to_ota(ota_event);}/* * According to pap, Chapter 11, capabilities can be  *     *                a) queried by PI *                b) told to PI when a client is subscribing *                c) assumed * * In case c) we got capabilities from third part of the push message (other * cases PI knows what it is doing), and we check is the client capable to * handle the message. * Requested capabilities are client capabilities, assumed capabilities are * PI capabilities. If there is no assumed capabilities, PI knows client capab- * ilities by method a) or method b). * Returns 1, if the client is capable, 0 when it is not. */static int response_push_connection(WAPEvent *e, PPGSessionMachine *sm){    WAPEvent *appl_event;    gw_assert(e->type == Pom_Connect_Ind);    if (sm->assumed_capabilities != NULL && check_capabilities(            e->u.Pom_Connect_Ind.requested_capabilities,             sm->assumed_capabilities) == 0)       return 0;    appl_event = wap_event_create(Pom_Connect_Res);    appl_event->u.Pom_Connect_Res.negotiated_capabilities =         wsp_cap_duplicate_list(e->u.Pom_Connect_Ind.requested_capabilities);    appl_event->u.Pom_Connect_Res.session_id = e->u.Pom_Connect_Ind.session_id;    dispatch_to_appl(appl_event);    return 1;}/* * Push response, from pap, Chapter 9.3.  * Inputs error code, in PAP format. * Return the current value of HTTPClient. */static HTTPClient *response_push_message(PPGPushMachine *pm, long code, int status){    WAPEvent *e;    HTTPClient *c;    push_machine_assert(pm);    e = wap_event_create(Push_Response);    e->u.Push_Response.pi_push_id = octstr_duplicate(pm->pi_push_id);    e->u.Push_Response.sender_name = tell_ppg_name();    e->u.Push_Response.reply_time = set_time();    e->u.Push_Response.code = code;    e->u.Push_Response.desc = describe_code(code);    c = send_push_response(e, status);    return c;}static int check_capabilities(List *requested, List *assumed){    int is_capable;    is_capable = 1;    return is_capable;}/* * Time of creation of the response (pap, chapter 9.3). We convert UNIX time  * to ISO8601, it is, YYYY-MM-DDThh:mm:ssZ, T and Z being literal strings (we * use gw_gmtime to turn UNIX time to broken time). */static Octstr *set_time(void){    Octstr *current_time;    struct tm now;    now = gw_gmtime(time(NULL));    current_time = octstr_format("%04d-%02d-%02dT%02d:%02d:%02dZ",                                  now.tm_year + 1900, now.tm_mon + 1,                                  now.tm_mday, now.tm_hour, now.tm_min,                                  now.tm_sec);    return current_time;}static void session_machine_assert(PPGSessionMachine *sm){    gw_assert(sm);    gw_assert(sm->session_id >= 0);    gw_assert(sm->addr_tuple);    gw_assert(sm->pi_client_address);}static void push_machine_assert(PPGPushMachine *pm){    gw_assert(pm);    gw_assert(pm->pi_push_id);    gw_assert(pm->push_id >= 0);    gw_assert(pm->session_id >= 0);    gw_assert(pm->addr_tuple);    gw_assert(pm->trusted == 1 || pm->trusted == 0);    gw_assert(pm->authenticated  == 1 || pm->authenticated == 0);}/* * Message transformations performed by PPG are defined in ppg, 6.1.2.1. Ppg, * chapter 6.1.1, states that we MUST reject a push having an erroneous PAP * push message element. So we must validate it even when we do not compile * it. * If message content was not si or sl, we pass it without modifications. * We do not do any (formally optional, but phones may disagree) header  * conversions to the binary format here, these are responsibility of our OTA  * module (gw/wap_push_ota.c).  * FIXME: Remove all headers which default values are known to the client.  * * Return  *    a) message, either transformed or not (if there is no-transform cache  *       directive, wml code is erroneous or content was not si or sl.)  *    b) The transformed gw address. Use here global-sender, when the bearer *       is SMS (some SMS centers would require this). *    c) the transformed message content type * * Returned flag tells was the transformation (if any) successful or not. Error  * flag is returned when there is no push headers, there is no Content-Type header * or push content does not compile. We should have checked existence of push  * headers earlier, but let us be careful. */static int transform_message(WAPEvent **e, WAPAddrTuple **tuple,                              List *push_headers, int cless_accepted, Octstr **type){    int message_deliverable;    struct content content;    Octstr *cliaddr;    long cliport,         servport,         address_type;    gw_assert((**e).type == Push_Message);    if ((**e).u.Push_Message.push_headers == NULL)        goto herror;    cliaddr = (**e).u.Push_Message.address_value;    push_headers = (**e).u.Push_Message.push_headers;    if (!cless_accepted) {        cliport = CONNECTED_CLIPORT;        servport = CONNECTED_SERVPORT;    } else {        cliport = CONNECTIONLESS_PUSH_CLIPORT;        servport = CONNECTIONLESS_SERVPORT;    }        address_type = (**e).u.Push_Message.address_type;    *tuple = set_addr_tuple(cliaddr, cliport, servport, address_type);    if (!content_transformable(push_headers))         goto no_transform;    content.charset = NULL;    content.type = NULL;    content.body = (**e).u.Push_Message.push_data;     if (content.body == NULL)        goto no_transform;    content.type = http_header_find_first(push_headers, "Content-Transfer-Encoding");    if (content.type) {	octstr_strip_blanks(content.type);	debug("wap.push.ppg", 0, "PPG: Content-Transfer-Encoding is \"%s\"",	      octstr_get_cstr (content.type));	message_deliverable = pap_get_content(&content);	        if (message_deliverable) {	    change_header_value(&push_headers, "Content-Transfer-Encoding",                                 "binary");	} else {	    goto error;	}    }    octstr_destroy(content.type);    http_header_get_content_type(push_headers, &content.type, &content.charset);       message_deliverable = pap_convert_content(&content);    if (content.type == NULL)        goto error;    if (message_deliverable) {        *type = content.type;            } else {        goto error;    }    (**e).u.Push_Message.push_data = content.body;    octstr_destroy(content.charset);    debug("wap.push.ppg", 0, "PPG: transform_message: push message content"          " and headers valid");    return 1;herror:    warning(0, "PPG: transform_message: no push headers, cannot accept");    octstr_destroy(content.type);    return 0;error:    warning(0, "PPG: transform_message: push content erroneous, cannot"            " accept");    octstr_destroy(content.type);    octstr_destroy(content.charset);    return 0;no_transform:    warning(0, "PPG: transform_message: push content non transformable");    return 1;}/* * Transform X-WAP-Application headers as per ppg 6.1.2.1. Note that missing * header means that wml.ua is assumed. * Return coded value (starting with 0), when the id was not wml.ua *        -1, when id was wml.ua (or no application id was present) *        -2, when error */static long check_x_wap_application_id_header(List **push_headers){    Octstr *appid_content;    long coded_value;    Octstr *cos;        if (*push_headers == NULL)        return -2;    appid_content = http_header_find_first(*push_headers,         "X-WAP-Application-Id");        if (appid_content == NULL) {        octstr_destroy(appid_content);        return -1;    }    if ((coded_value = parse_appid_header(&appid_content)) < 0) {        octstr_destroy(appid_content);        return -2;    }            if (coded_value == 2) {        octstr_destroy(appid_content);        http_header_remove_all(*push_headers, "X-WAP-Application-Id");        return -1;    }    cos = octstr_format("%ld", coded_value);    http_header_remove_all(*push_headers, "X-WAP-Application-Id");    http_header_add(*push_headers, "X-WAP-Application-Id", octstr_get_cstr(cos));        octstr_destroy(appid_content);     octstr_destroy(cos);        return coded_value;  }/* * Check do we have a no-transform cache directive amongst the headers. */static int content_transformable(List *push_headers){    List *cache_directives;    long i;    Octstr *header_name,            *header_value;    gw_assert(push_headers);    cache_directives = http_header_find_all(push_headers, "Cache-Control");    if (list_len(cache_directives) == 0) {        http_destroy_headers(cache_directives);        return 1;    }    i = 0;    while (i < list_len(cache_directives)) {        http_header_get(cache_directives, i, &header_name, &header_value);        if (octstr_compare(header_value, octstr_imm("no-transform")) == 0) {            http_destroy_headers(cache_directives);            octstr_destroy(header_name);            octstr_destroy(header_value);	    return 0;        }        ++i;    }    http_destroy_headers(cache_directives);    octstr_destroy(header_name);    octstr_destroy(header_value);     return 1;}/* * Convert push content to compact binary format (this can be wmlc, sic, slc * or coc). Current status wml, sl and si compiled, others passed. */static Octstr *convert_wml_to_wmlc(struct content *content){    Octstr *wmlc;    if (wml_compile(content->body, content->charset, &wmlc, NULL) == 0)        return wmlc;    warning(0, "PPG: wml compilation failed");    return NULL;}static Octstr *convert_si_to_sic(struct content *content){    Octstr *sic;    if (si_compile(content->body, content->charset, &sic) == 0)        return sic;    warning(0, "PPG: si compilation failed");    return NULL;}static Octstr *convert_sl_to_slc(struct content *

⌨️ 快捷键说明

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