📄 wap-appl.c
字号:
/* Shut up WMLScript compiler status/trace messages. */static void dev_null(const char *data, size_t len, void *context) { /* nothing */}static Octstr *convert_wml_to_wmlc(struct content *content) { Octstr *wmlc; int ret; /* content->charset is passed from the HTTP header parsing */ ret = wml_compile(content->body, content->charset, &wmlc, content->version); /* wmlc is created implicitely in wml_compile() */ if (ret == 0) return wmlc; octstr_destroy(wmlc); warning(0, "WSP: WML compilation failed."); return NULL;}static Octstr *convert_wmlscript_to_wmlscriptc(struct content *content) { WsCompilerParams params; WsCompilerPtr compiler; WsResult result; unsigned char *result_data; size_t result_size; Octstr *wmlscriptc; memset(¶ms, 0, sizeof(params)); params.use_latin1_strings = 0; params.print_symbolic_assembler = 0; params.print_assembler = 0; params.meta_name_cb = NULL; params.meta_name_cb_context = NULL; params.meta_http_equiv_cb = NULL; params.meta_http_equiv_cb_context = NULL; params.stdout_cb = dev_null; params.stderr_cb = dev_null; compiler = ws_create(¶ms); if (compiler == NULL) { panic(0, "WSP: could not create WMLScript compiler"); } result = ws_compile_data(compiler, octstr_get_cstr(content->url), octstr_get_cstr(content->body), octstr_len(content->body), &result_data, &result_size); if (result != WS_OK) { warning(0, "WSP: WMLScript compilation failed: %s", ws_result_to_string(result)); wmlscriptc = NULL; } else { wmlscriptc = octstr_create_from_data(result_data, result_size); } return wmlscriptc;}/* * XXX There's a big bug in http_get_content_type that * assumes that header parameter is charset without looking at * parameter key. Good!. I'll use its value to catch boundary * value for now * ie. "Content-Type: (foo/bar);something=(value)" it gets value * without caring about what is "something" *//* DAVI: To-Dostatic Octstr *convert_multipart_mixed(struct content *content){ Octstr *result = NULL; debug("wap.wsp.multipart.mixed", 0, "WSP.Multipart.Mixed, boundary=[%s]", octstr_get_cstr(content->charset)); result = octstr_duplicate(content->body); return result;}*/static Octstr *deconvert_multipart_formdata(struct content *content){ Octstr *mime; if ((mime_decompile(content->body, &mime)) == 0) return mime; return NULL;}/* DAVI: To-Dostatic Octstr *deconvert_mms_message(struct content *content){ Octstr *mime; if ((mms_decompile(content->body, &mime)) == 0) return mime; return NULL;}*//* The interface for capability negotiation is a bit different from * the negotiation at WSP level, to make it easier to program. * The application layer gets a list of requested capabilities, * basically a straight decoding of the WSP level capabilities. * It replies with a list of all capabilities it wants to set or * refuse. (Refuse by setting cap->data to NULL). Any capabilities * it leaves out are considered "unknown; don't care". The WSP layer * will either process those itself, or refuse them. * * At the WSP level, not sending a reply to a capability means accepting * what the client proposed. If the application layer wants this to * happen, it should set cap->data to NULL and cap->accept to 1. * (The WSP layer does not try to guess what kind of reply would be * identical to what the client proposed, because the format of the * reply is often different from the format of the request, and this * is likely to be true for unknown capabilities too.) */static List *negotiate_capabilities(List *req_caps) { /* Currently we don't know or care about any capabilities, * though it is likely that "Extended Methods" will be * the first. */ return list_create();}/* * Ota submodule implements indications, responses and confirmations part of * ota. *//* * If Accept-Application is empty, add header indicating default application * wml ua (see ota 6.4.1). Otherwise decode application id (see http://www. * wapforum.org/wina/push-app-id.htm). FIXME: capability negotiation (no- * thing means default, if so negotiated). * Function does not allocate memory neither for headers nor application_ * headers. * Returns encoded application headers and input header list without them. */static void check_application_headers(List **headers, List **application_headers){ List *inh; int i; Octstr *appid_name, *coded_octstr; char *appid_value, *coded_value; split_header_list(headers, &inh, "Accept-Application"); if (*headers == NULL || list_len(inh) == 0) { http_header_add(*application_headers, "Accept-Application", "wml ua"); debug("wap.appl.push", 0, "APPL: No push application, assuming wml" " ua"); if (*headers != NULL) http_destroy_headers(inh); return; } i = 0; coded_value = NULL; appid_value = NULL; while (list_len(inh) > 0) { http_header_get(inh, i, &appid_name, &coded_octstr); /* Greatest value reserved by WINA is 0xFF00 0000*/ coded_value = octstr_get_cstr(coded_octstr); if (coded_value != NULL) appid_value = wsp_application_id_to_cstr((long) coded_value); if (appid_value != NULL && coded_value != NULL) http_header_add(*application_headers, "Accept-Application", appid_value); else { error(0, "OTA: Unknown application is, skipping: "); octstr_dump(coded_octstr, 0); } i++; } debug("wap.appl.push", 0, "application headers were"); http_header_dump(*application_headers); http_destroy_headers(inh); octstr_destroy(appid_name); octstr_destroy(coded_octstr);}/* * Bearer-Indication field is defined in ota 6.4.1. * Skip the header, if it is malformed or if there is more than one bearer * indication. * Function does not allocate memory neither for headers nor bearer_headers. * Return encoded bearer indication header and input header list without it. */static void decode_bearer_indication(List **headers, List **bearer_headers){ List *inb; Octstr *name, *coded_octstr; char *value; unsigned char coded_value; if (*headers == NULL) { debug("wap.appl", 0, "APPL: no client headers, continuing"); return; } split_header_list(headers, &inb, "Bearer-Indication"); if (list_len(inb) == 0) { debug("wap.appl.push", 0, "APPL: No bearer indication headers," " continuing"); http_destroy_headers(inb); return; } if (list_len(inb) > 1) { error(0, "APPL: To many bearer indication header(s), skipping" " them"); http_destroy_headers(inb); return; } http_header_get(inb, 0, &name, &coded_octstr); http_destroy_headers(inb); /* Greatest assigned number for a bearer type is 0xff, see wdp, appendix C */ coded_value = octstr_get_char(coded_octstr, 0); value = wsp_bearer_indication_to_cstr(coded_value); if (value != NULL && coded_value != 0) { http_header_add(*bearer_headers, "Bearer-Indication", value); debug("wap.appl.push", 0, "bearer indication header was"); http_header_dump(*bearer_headers); return; } else { error(0, "APPL: Illegal bearer indication value, skipping"); octstr_dump(coded_octstr, 0); http_destroy_headers(*bearer_headers); return; }}/* * Separate headers into two lists, one having all headers named "name" and * the other rest of them. */static void split_header_list(List **headers, List **new_headers, char *name){ if (*headers == NULL) return; *new_headers = http_header_find_all(*headers, name); http_header_remove_all(*headers, name); }/* * Find headers Accept-Application and Bearer-Indication amongst push headers, * decode them and add them to their proper field. */static void indicate_push_connection(WAPEvent *e){ WAPEvent *ppg_event; List *push_headers, *application_headers, *bearer_headers; push_headers = http_header_duplicate(e->u.S_Connect_Ind.client_headers); application_headers = http_create_empty_headers(); bearer_headers = http_create_empty_headers(); ppg_event = wap_event_create(Pom_Connect_Ind); ppg_event->u.Pom_Connect_Ind.addr_tuple = wap_addr_tuple_duplicate(e->u.S_Connect_Ind.addr_tuple); ppg_event->u.Pom_Connect_Ind.requested_capabilities = wsp_cap_duplicate_list(e->u.S_Connect_Ind.requested_capabilities); check_application_headers(&push_headers, &application_headers); ppg_event->u.Pom_Connect_Ind.accept_application = application_headers; decode_bearer_indication(&push_headers, &bearer_headers); if (list_len(bearer_headers) == 0) { http_destroy_headers(bearer_headers); ppg_event->u.Pom_Connect_Ind.bearer_indication = NULL; } else ppg_event->u.Pom_Connect_Ind.bearer_indication = bearer_headers; ppg_event->u.Pom_Connect_Ind.push_headers = push_headers; ppg_event->u.Pom_Connect_Ind.session_id = e->u.S_Connect_Ind.session_id; debug("wap.appl", 0, "APPL: making OTA connection indication to PPG"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_disconnect(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Pom_Disconnect_Ind); ppg_event->u.Pom_Disconnect_Ind.reason_code = e->u.S_Disconnect_Ind.reason_code; ppg_event->u.Pom_Disconnect_Ind.error_headers = octstr_duplicate(e->u.S_Disconnect_Ind.error_headers); ppg_event->u.Pom_Disconnect_Ind.error_body = octstr_duplicate(e->u.S_Disconnect_Ind.error_body); ppg_event->u.Pom_Disconnect_Ind.session_handle = e->u.S_Disconnect_Ind.session_handle; wap_push_ppg_dispatch_event(ppg_event);}/* * We do not implement acknowledgement headers */static void confirm_push(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Po_ConfirmedPush_Cnf); ppg_event->u.Po_ConfirmedPush_Cnf.server_push_id = e->u.S_ConfirmedPush_Cnf.server_push_id; ppg_event->u.Po_ConfirmedPush_Cnf.session_handle = e->u.S_ConfirmedPush_Cnf.session_id; debug("wap.appl", 0, "OTA: confirming push for ppg"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_abort(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Po_PushAbort_Ind); ppg_event->u.Po_PushAbort_Ind.push_id = e->u.S_PushAbort_Ind.push_id; ppg_event->u.Po_PushAbort_Ind.reason = e->u.S_PushAbort_Ind.reason; ppg_event->u.Po_PushAbort_Ind.session_handle = e->u.S_PushAbort_Ind.session_id; debug("wap.push.ota", 0, "OTA: making push abort indication for ppg"); wap_push_ppg_dispatch_event(ppg_event);}static void indicate_push_suspend(WAPEvent *e){ WAPEvent *ppg_event; ppg_event = wap_event_create(Pom_Suspend_Ind); ppg_event->u.Pom_Suspend_Ind.reason = e->u.S_Suspend_Ind.reason; ppg_event->u.Pom_Suspend_Ind.session_id = e->u.S_Suspend_Ind.session_id; wap_push_ppg_dispatch_event(ppg_event);}/* * Find Bearer-Indication amongst client headers, decode it and assign it to * a separate field in the event structure. */static void indicate_push_resume(WAPEvent *e){ WAPEvent *ppg_event; List *push_headers, *bearer_headers; push_headers = http_header_duplicate(e->u.S_Resume_Ind.client_headers); bearer_headers = http_create_empty_headers(); ppg_event = wap_event_create(Pom_Resume_Ind); ppg_event->u.Pom_Resume_Ind.addr_tuple = wap_addr_tuple_duplicate( e->u.S_Resume_Ind.addr_tuple); decode_bearer_indication(&push_headers, &bearer_headers); if (list_len(bearer_headers) == 0) { http_destroy_headers(bearer_headers); ppg_event->u.Pom_Resume_Ind.bearer_indication = NULL; } else ppg_event->u.Pom_Resume_Ind.bearer_indication = bearer_headers; ppg_event->u.Pom_Resume_Ind.client_headers = push_headers; ppg_event->u.Pom_Resume_Ind.session_id = e->u.S_Resume_Ind.session_id; wap_push_ppg_dispatch_event(ppg_event);}/* * Server headers are mentioned in table in ota 6.4.1, but none of the primit- * ives use them. They are optional in S_Connect_Res, so we do not use them. */static void response_push_connection(WAPEvent *e){ WAPEvent *wsp_event; gw_assert(e->type = Pom_Connect_Res); wsp_event = wap_event_create(S_Connect_Res); wsp_event->u.S_Connect_Res.session_id = e->u.Pom_Connect_Res.session_id; wsp_event->u.S_Connect_Res.negotiated_capabilities = wsp_cap_duplicate_list(e->u.Pom_Connect_Res.negotiated_capabilities); debug("wap.appl", 0, "APPL: making push connect response"); wsp_session_dispatch_event(wsp_event);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -