📄 wap_push_ppg.c
字号:
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 + -