📄 wsp_session.c
字号:
return caps;}static List *make_reply_headers(WSPMachine *m){ List *headers; Octstr *encoding_version; /* Add all server wsp level hop-by-hop headers. Currently only * Encoding-Version, as defined by wsp, chapter 8.4.2.70. * What headers belong to which version is defined in appendix A, * table 39.. encoding_version = request_version = NULL; * Essentially, if the client sends us an Encoding-Version * higher than ours (1.3) we send our version number to it, * if it is lower, we left version number intact. */ /* First the case that we have no Encoding-Version header at all. * This case we must assume that the client supports version 1.2 * or lower. */ headers = http_create_empty_headers(); encoding_version = wsp_encoding_version_to_string(m->encoding_version); http_header_add(headers, "Encoding-Version", octstr_get_cstr(encoding_version)); octstr_destroy(encoding_version); return headers;}static Octstr *make_connectreply_pdu(WSPMachine *m) { WSP_PDU *pdu; Octstr *os; List *caps; List *reply_headers; pdu = wsp_pdu_create(ConnectReply); pdu->u.ConnectReply.sessionid = m->session_id; caps = make_capabilities_reply(m); pdu->u.ConnectReply.capabilities = wsp_cap_pack_list(caps); wsp_cap_destroy_list(caps); reply_headers = make_reply_headers(m); pdu->u.ConnectReply.headers = wsp_headers_pack(reply_headers, 0, m->encoding_version); http_destroy_headers(reply_headers); os = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); return os;}static Octstr *make_resume_reply_pdu(WSPMachine *m, List *headers) { WSP_PDU *pdu; Octstr *os; pdu = wsp_pdu_create(Reply); /* Not specified for Resume replies */ pdu->u.Reply.status = wsp_convert_http_status_to_wsp_status(HTTP_OK); if (headers == NULL) { headers = http_create_empty_headers(); pdu->u.Reply.headers = wsp_headers_pack(headers, 1, m->encoding_version); http_destroy_headers(headers); } else { pdu->u.Reply.headers = wsp_headers_pack(headers, 1, m->encoding_version); } pdu->u.Reply.data = octstr_create(""); os = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); return os;}static WSP_PDU *make_confirmedpush_pdu(WAPEvent *e){ WSP_PDU *pdu; List *headers; pdu = wsp_pdu_create(ConfirmedPush);/* * Both push headers and push body are optional. */ if (e->u.S_ConfirmedPush_Req.push_headers == NULL) { headers = http_create_empty_headers(); pdu->u.ConfirmedPush.headers = wsp_headers_pack(headers, 1, WSP_1_2); http_destroy_headers(headers); } else pdu->u.ConfirmedPush.headers = wsp_headers_pack(e->u.S_ConfirmedPush_Req.push_headers, 1, WSP_1_2); if (e->u.S_ConfirmedPush_Req.push_body == NULL) pdu->u.ConfirmedPush.data = octstr_create(""); else pdu->u.ConfirmedPush.data = octstr_duplicate(e->u.S_ConfirmedPush_Req.push_body); return pdu;}static WSP_PDU *make_push_pdu(WAPEvent *e){ WSP_PDU *pdu; List *headers; pdu = wsp_pdu_create(Push);/* * Both push headers and push body are optional */ if (e->u.S_Push_Req.push_headers == NULL) { headers = http_create_empty_headers(); pdu->u.Push.headers = wsp_headers_pack(headers, 1, WSP_1_2); http_destroy_headers(headers); } else pdu->u.Push.headers = wsp_headers_pack(e->u.S_Push_Req.push_headers, 1, WSP_1_2); if (e->u.S_Push_Req.push_body == NULL) pdu->u.Push.data = octstr_create(""); else pdu->u.Push.data = octstr_duplicate(e->u.S_Push_Req.push_body); return pdu;}static int transaction_belongs_to_session(void *wsp_ptr, void *tuple_ptr) { WSPMachine *wsp; WAPAddrTuple *tuple; wsp = wsp_ptr; tuple = tuple_ptr; return wap_addr_tuple_same(wsp->addr_tuple, tuple);}static int find_by_session_id(void *wsp_ptr, void *id_ptr) { WSPMachine *wsp = wsp_ptr; long *idp = id_ptr; return wsp->session_id == *idp;}static int find_by_method_id(void *wspm_ptr, void *id_ptr) { WSPMethodMachine *msm = wspm_ptr; long *idp = id_ptr; return msm->transaction_id == *idp;}static int find_by_push_id(void *m_ptr, void *id_ptr) { WSPPushMachine *m = m_ptr; long *idp = id_ptr; return m->transaction_id == *idp;}static WSPMethodMachine *find_method_machine(WSPMachine *sm, long id) { return list_search(sm->methodmachines, &id, find_by_method_id);}static WSPPushMachine *find_push_machine(WSPMachine *m, long id){ return list_search(m->pushmachines, &id, find_by_push_id);}static int same_client(void *a, void *b) { WSPMachine *sm1, *sm2; sm1 = a; sm2 = b; return wap_addr_tuple_same(sm1->addr_tuple, sm2->addr_tuple);}static void disconnect_other_sessions(WSPMachine *sm) { List *old_sessions; WAPEvent *disconnect; WSPMachine *sm2; long i; old_sessions = list_search_all(session_machines, sm, same_client); if (old_sessions == NULL) return; for (i = 0; i < list_len(old_sessions); i++) { sm2 = list_get(old_sessions, i); if (sm2 != sm) { disconnect = wap_event_create(Disconnect_Event); handle_session_event(sm2, disconnect, NULL); } } list_destroy(old_sessions, NULL);}static List *unpack_new_headers(WSPMachine *sm, Octstr *hdrs) { List *new_headers; if (hdrs && octstr_len(hdrs) > 0) { new_headers = wsp_headers_unpack(hdrs, 0); if (sm->http_headers == NULL) sm->http_headers = http_create_empty_headers(); http_header_combine(sm->http_headers, new_headers); return new_headers; } return NULL;}static WAPEvent *make_abort(long reason, long handle){ WAPEvent *wtp_event; wtp_event = wap_event_create(TR_Abort_Req); wtp_event->u.TR_Abort_Req.abort_type = 0x01; wtp_event->u.TR_Abort_Req.abort_reason = reason; wtp_event->u.TR_Abort_Req.handle = handle; return wtp_event;}static void send_abort(long reason, long handle) { WAPEvent *wtp_event; wtp_event = make_abort(reason, handle); dispatch_to_wtp_resp(wtp_event);}static void send_abort_to_initiator(long reason, long handle){ WAPEvent *wtp_event; wtp_event = make_abort(reason, handle); dispatch_to_wtp_init(wtp_event);}/* * The server sends invoke (to be exact, makes TR-Invoke.req) only when it is * pushing. (Only the client disconnects sessions.) */ static void send_invoke(WSPMachine *m, WSP_PDU *pdu, WAPEvent *e, long class){ WAPEvent *wtp_event; wtp_event = wap_event_create(TR_Invoke_Req); wtp_event->u.TR_Invoke_Req.addr_tuple = wap_addr_tuple_duplicate(m->addr_tuple);/* * There is no mention of acknowledgement type in the specs.燘ut because * confirmed push is confirmed after response from OTA, provider acknowledge- * ments seem redundant. */ wtp_event->u.TR_Invoke_Req.up_flag = USER_ACKNOWLEDGEMENT; wtp_event->u.TR_Invoke_Req.tcl = class; if (e->type == S_ConfirmedPush_Req) wtp_event->u.TR_Invoke_Req.handle = e->u.S_ConfirmedPush_Req.server_push_id; wtp_event->u.TR_Invoke_Req.user_data = wsp_pdu_pack(pdu); wsp_pdu_destroy(pdu); dispatch_to_wtp_init(wtp_event);}static void indicate_disconnect(WSPMachine *sm, long reason) { WAPEvent *new_event; new_event = wap_event_create(S_Disconnect_Ind); new_event->u.S_Disconnect_Ind.reason_code = reason; new_event->u.S_Disconnect_Ind.redirect_security = 0; new_event->u.S_Disconnect_Ind.redirect_addresses = 0; new_event->u.S_Disconnect_Ind.error_headers = NULL; new_event->u.S_Disconnect_Ind.error_body = NULL; new_event->u.S_Disconnect_Ind.session_handle = sm->session_id; dispatch_to_appl(new_event);}static void indicate_suspend(WSPMachine *sm, long reason) { WAPEvent *new_event; new_event = wap_event_create(S_Suspend_Ind); new_event->u.S_Suspend_Ind.reason = reason; new_event->u.S_Suspend_Ind.session_id = sm->session_id; dispatch_to_appl(new_event);}static void indicate_resume(WSPMachine *sm, WAPAddrTuple *tuple, List *headers) { WAPEvent *new_event; new_event = wap_event_create(S_Resume_Ind); new_event->u.S_Resume_Ind.addr_tuple = wap_addr_tuple_duplicate(tuple); new_event->u.S_Resume_Ind.client_headers = http_header_duplicate(headers); new_event->u.S_Resume_Ind.session_id = sm->session_id; dispatch_to_appl(new_event);}static void indicate_pushabort(WSPPushMachine *spm, long reason){ WAPEvent *ota_event; ota_event = wap_event_create(S_PushAbort_Ind); ota_event->u.S_PushAbort_Ind.push_id = spm->server_push_id; ota_event->u.S_PushAbort_Ind.reason = reason; ota_event->u.S_PushAbort_Ind.session_id = spm->session_id; dispatch_to_appl(ota_event);}static void confirm_push(WSPPushMachine *m){ WAPEvent *ota_event; ota_event = wap_event_create(S_ConfirmedPush_Cnf); ota_event->u.S_ConfirmedPush_Cnf.server_push_id = m->server_push_id; ota_event->u.S_ConfirmedPush_Cnf.session_id = m->session_id; dispatch_to_appl(ota_event);}static void method_abort(WSPMethodMachine *msm, long reason) { WAPEvent *wtp_event; /* Send TR-Abort.req(reason) */ wtp_event = wap_event_create(TR_Abort_Req); /* FIXME: Specs are unclear about this; we may indeed have to * guess abort whether this is a WSP or WTP level abort code */ if (reason < WSP_ABORT_PROTOERR) { wtp_event->u.TR_Abort_Req.abort_type = 0x00; } else { wtp_event->u.TR_Abort_Req.abort_type = 0x01; } wtp_event->u.TR_Abort_Req.abort_reason = reason; wtp_event->u.TR_Abort_Req.handle = msm->transaction_id; dispatch_to_wtp_resp(wtp_event);}static void indicate_method_abort(WSPMethodMachine *msm, long reason) { WAPEvent *new_event; /* Send S-MethodAbort.ind(reason) */ new_event = wap_event_create(S_MethodAbort_Ind); new_event->u.S_MethodAbort_Ind.transaction_id = msm->transaction_id; new_event->u.S_MethodAbort_Ind.reason = reason; new_event->u.S_MethodAbort_Ind.session_handle = msm->session_id; dispatch_to_appl(new_event);} static int method_is_holding(void *item, void *pattern) { WSPMethodMachine *msm = item; return msm->state == HOLDING;}static void release_holding_methods(WSPMachine *sm) { WAPEvent *release; WSPMethodMachine *msm; List *holding; long i, len; holding = list_search_all(sm->methodmachines, NULL, method_is_holding); if (holding == NULL) return; /* We can re-use this because wsp_handle_method_event does not * destroy its event */ release = wap_event_create(Release_Event); len = list_len(holding); for (i = 0; i < len; i++) { msm = list_get(holding, i); handle_method_event(sm, msm, release, NULL); } list_destroy(holding, NULL); wap_event_destroy(release);}static void abort_methods(WSPMachine *sm, long reason) { WAPEvent *ab; WSPMethodMachine *msm; long i, len; ab = wap_event_create(Abort_Event); ab->u.Abort_Event.reason = reason; /* This loop goes backward because it has to deal with the * possibility of method machines disappearing after their event. */ len = list_len(sm->methodmachines); for (i = len - 1; i >= 0; i--) { msm = list_get(sm->methodmachines, i); handle_method_event(sm, msm, ab, NULL); } wap_event_destroy(ab);}static void abort_pushes(WSPMachine *sm, long reason){ WAPEvent *ab; WSPPushMachine *psm; long i, len; ab = wap_event_create(Abort_Event); ab->u.Abort_Event.reason = reason; len = list_len(sm->pushmachines); for (i = len - 1; i >= 0; i--) { psm = list_get(sm->pushmachines, i); handle_push_event(sm, psm, ab); } wap_event_destroy(ab);}WSPMachine *find_session_machine_by_id (int id) { return list_search(session_machines, &id, id_belongs_to_session);}static int id_belongs_to_session (void *wsp_ptr, void *pid) { WSPMachine *wsp; int *id; wsp = wsp_ptr; id = (int *) pid; if (*id == wsp->session_id) return 1; return 0;}static int wsp_encoding_string_to_version(Octstr *enc) { int v; /* default will be WSP 1.2, as defined by WAPWSP */ v = WSP_1_2; if (octstr_compare(enc, octstr_imm("1.1")) == 0) { v = WSP_1_1; } else if (octstr_compare(enc, octstr_imm("1.2")) == 0) { v = WSP_1_2; } else if (octstr_compare(enc, octstr_imm("1.3")) == 0) { v = WSP_1_3; } else if (octstr_compare(enc, octstr_imm("1.4")) == 0) { v = WSP_1_4; } else if (octstr_compare(enc, octstr_imm("1.5")) == 0) { v = WSP_1_5; } return v;}static Octstr *wsp_encoding_version_to_string(int version) { Octstr *os; switch (version) { case WSP_1_1: os = octstr_create("1.1"); break; case WSP_1_2: os = octstr_create("1.2"); break; case WSP_1_3: os = octstr_create("1.3"); break; case WSP_1_4: os = octstr_create("1.4"); break; case WSP_1_5: os = octstr_create("1.5"); break; default: os = octstr_create("1.2"); break; } return os;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -