📄 wap_push_ppg.c
字号:
if (sm) remove_pushless_session(sm); wap_event_destroy(e); return 0;no_start: wap_addr_tuple_destroy(tuple); octstr_destroy(type); remove_push_data(sm, pm, cless); if (sm) remove_pushless_session(sm); wap_event_destroy(e); return 1;}/* * These events come from OTA layer */static void handle_internal_event(WAPEvent *e){ long sid, pid, reason, port; int http_status; PPGPushMachine *pm; PPGSessionMachine *sm; WAPAddrTuple *tuple; List *caps; http_status = HTTP_OK; switch (e->type) {/* * Pap, Chapter 11.1.3 states that if client is incapable, we should abort the * push and inform PI. We do this here. * In addition, we store session id used as an alias for address tuple and do * all pushes pending for this initiator (or abort them). */ case Pom_Connect_Ind: debug("wap.push.ppg", 0, "PPG: handle_internal_event: connect" " indication from OTA"); sid = e->u.Pom_Connect_Ind.session_id; tuple = e->u.Pom_Connect_Ind.addr_tuple; port = tuple->remote->port; caps = e->u.Pom_Connect_Ind.requested_capabilities; sm = wap_push_ppg_have_push_session_for(tuple); sm = update_session_data(sm, sid, port, caps); if (!response_push_connection(e, sm)) { pm = abort_delivery(sm, http_status); wap_event_destroy(e); return; }/* * hard-coded until we have bearer control implemented */ deliver_pending_pushes(sm, NOT_LAST); wap_event_destroy(e); break; case Pom_Disconnect_Ind: debug("wap.push.ppg", 0, "PPG: handle_internal_event: disconnect" " indication from OTA"); sm = wap_push_ppg_have_push_session_for_sid( e->u.Pom_Disconnect_Ind.session_handle); remove_session_data(sm, http_status); wap_event_destroy(e); break;/* * Only the client can close a session. So we leave session open, even when * there are no active pushes. Note that we do not store PAP attribute very * long time. Point is that result notification message, if asked, will rep- * ort this fact to PI, after which there is no need to store it any more. */ case Po_ConfirmedPush_Cnf: debug("wap.push.ppg", 0, "PPG: handle_internal_event: push" " confirmation from OTA"); sid = e->u.Po_ConfirmedPush_Cnf.session_handle; pid = e->u.Po_ConfirmedPush_Cnf.server_push_id; sm = wap_push_ppg_have_push_session_for_sid(sid); pm = find_ppg_push_machine_using_pid(sm, pid); pm = update_push_data_with_attribute(&sm, pm, PAP_CONFIRMED, PAP_DELIVERED2); wap_event_destroy(e); remove_push_data(sm, pm, 0); break;/* * Again, PAP attribute will be reported to PI by using result notification. */ case Po_PushAbort_Ind: debug("wap.push.ppg", 0, "PPG: handle_internal_event: abort" " indication from OTA"); sid = e->u.Po_PushAbort_Ind.session_handle; pid = e->u.Po_PushAbort_Ind.push_id; sm = wap_push_ppg_have_push_session_for_sid(sid); pm = find_ppg_push_machine_using_pid(sm, pid); session_machine_assert(sm); push_machine_assert(pm); reason = e->u.Po_PushAbort_Ind.reason; pm = update_push_data_with_attribute(&sm, pm, reason, PAP_ABORTED); remove_session_data(sm, http_status); wap_event_destroy(e); break;/* * FIXME TRU: Add timeout (a mandatory feature!) */ default: debug("wap.ppg", 0, "PPG: handle_internal_event: an unhandled event"); wap_event_dump(e); wap_event_destroy(e); break; }}/* * Functions related to various ppg machine types. * * We do not set session id here: it is told to us by wsp. */static PPGSessionMachine *session_machine_create(WAPAddrTuple *tuple, WAPEvent *e){ PPGSessionMachine *m; gw_assert(e->type = Push_Message); m = gw_malloc(sizeof(PPGSessionMachine)); #define INTEGER(name) m->name = 0; #define OCTSTR(name) m->name = NULL; #define ADDRTUPLE(name) m->name = NULL; #define PUSHMACHINES(name) m->name = list_create(); #define CAPABILITIES(name) m->name = NULL; #define MACHINE(fields) fields #include "wap_ppg_session_machine.def" m->pi_client_address = octstr_duplicate(e->u.Push_Message.address_value); m->addr_tuple = wap_addr_tuple_duplicate(tuple); m->assumed_capabilities = wsp_cap_duplicate_list(e->u.Push_Message.pi_capabilities); m->preferconfirmed_value = PAP_CONFIRMED; list_append(ppg_machines, m); debug("wap.push.ppg", 0, "PPG: Created PPGSessionMachine %ld", m->session_id); return m;}static void session_machine_destroy(void *p){ PPGSessionMachine *sm; if (p == NULL) return; sm = p; debug("wap.push.ppg", 0, "PPG: destroying PPGSEssionMachine %ld", sm->session_id); #define OCTSTR(name) octstr_destroy(sm->name); #define ADDRTUPLE(name) wap_addr_tuple_destroy(sm->name); #define INTEGER(name) sm->name = 0; #define PUSHMACHINES(name) push_machines_list_destroy(sm->name); #define CAPABILITIES(name) wsp_cap_destroy_list(sm->name); #define MACHINE(fields) fields #include "wap_ppg_session_machine.def" gw_free(sm);}/* * FIXME: PPG's trust policy (flags authenticated and trusted). * We return pointer to the created push machine and push id it uses. */static PPGPushMachine *push_machine_create(WAPEvent *e, WAPAddrTuple *tuple){ PPGPushMachine *m; m = gw_malloc(sizeof(PPGPushMachine)); #define INTEGER(name) m->name = 0; #define OCTSTR(name) m->name = NULL; #define OPTIONAL_OCTSTR(name) m->name = NULL; #define ADDRTUPLE(name) m->name = NULL; #define CAPABILITIES m->name = NULL; #define HTTPHEADER(name) m->name = NULL; #define MACHINE(fields) fields #include "wap_ppg_push_machine.def" m->addr_tuple = wap_addr_tuple_duplicate(tuple); m->pi_push_id = octstr_duplicate(e->u.Push_Message.pi_push_id); m->push_id = counter_increase(push_id_counter); m->delivery_method = e->u.Push_Message.delivery_method; m->deliver_after_timestamp = octstr_duplicate(e->u.Push_Message.deliver_after_timestamp); m->priority = e->u.Push_Message.priority; m->push_headers = http_header_duplicate(e->u.Push_Message.push_headers); m->push_data = octstr_duplicate(e->u.Push_Message.push_data); m->address_type = e->u.Push_Message.address_type; if (e->u.Push_Message.smsc_id != NULL) m->smsc_id = octstr_duplicate(e->u.Push_Message.smsc_id); else m->smsc_id = NULL; if (e->u.Push_Message.dlr_url != NULL) m->dlr_url = octstr_duplicate(e->u.Push_Message.dlr_url); else m->dlr_url = NULL; m->dlr_mask = e->u.Push_Message.dlr_mask; if (e->u.Push_Message.smsbox_id != NULL) m->smsbox_id = octstr_duplicate(e->u.Push_Message.smsbox_id); else m->smsbox_id = NULL; m->service_name = octstr_duplicate(e->u.Push_Message.service_name); m->progress_notes_requested = e->u.Push_Message.progress_notes_requested; if (e->u.Push_Message.progress_notes_requested) m->ppg_notify_requested_to = octstr_duplicate(e->u.Push_Message.ppg_notify_requested_to); debug("wap.push.ppg", 0, "PPG: push machine %ld created", m->push_id); return m;}/* * Contrary to the normal Kannel style, we do not remove from a list here. * That is because we now have two different push lists. */static void push_machine_destroy(void *p){ PPGPushMachine *pm; if (p == NULL) return; pm = p; debug("wap.push.ppg", 0, "PPG: destroying push machine %ld", pm->push_id); #define OCTSTR(name) octstr_destroy(pm->name); #define OPTIONAL_OCTSTR(name) octstr_destroy(pm->name); #define INTEGER(name) #define ADDRTUPLE(name) wap_addr_tuple_destroy(pm->name); #define CAPABILITIES(name) wap_cap_destroy_list(pm->name); #define HTTPHEADER(name) http_destroy_headers(pm->name); #define MACHINE(fields) fields #include "wap_ppg_push_machine.def" gw_free(p);}static void push_machines_list_destroy(List *machines){ if (machines == NULL) return; list_destroy(machines, push_machine_destroy);}static int session_has_addr(void *a, void *b){ Octstr *cliaddr; PPGSessionMachine *sm; cliaddr = b; sm = a; return octstr_compare(sm->addr_tuple->remote->address, cliaddr) == 0;}static int session_has_sid(void *a, void *b){ PPGSessionMachine *sm; long *sid; sid = b; sm = a; return *sid == sm->session_id;}/* * Here session machine address tuples have connection-oriented ports, because * these are used when establishing the connection an doing pushes. But session * creation request must be to the the connectionless push port of the client. * So we change ports here. */static void create_session(WAPEvent *e, PPGPushMachine *pm){ WAPEvent *ota_event; List *push_headers; Octstr *smsc_id; Octstr *dlr_url; Octstr *smsbox_id; Octstr *service_name; gw_assert(e->type == Push_Message); push_machine_assert(pm); push_headers = http_header_duplicate(e->u.Push_Message.push_headers); smsc_id = octstr_duplicate(e->u.Push_Message.smsc_id); dlr_url = octstr_duplicate(e->u.Push_Message.dlr_url); smsbox_id = octstr_duplicate(e->u.Push_Message.smsbox_id); service_name = octstr_duplicate(e->u.Push_Message.service_name); ota_event = wap_event_create(Pom_SessionRequest_Req); ota_event->u.Pom_SessionRequest_Req.addr_tuple = addr_tuple_change_cliport(pm->addr_tuple, CONNECTIONLESS_PUSH_CLIPORT); ota_event->u.Pom_SessionRequest_Req.push_headers = push_headers; ota_event->u.Pom_SessionRequest_Req.push_id = pm->push_id; ota_event->u.Pom_SessionRequest_Req.address_type = pm->address_type; if (smsc_id != NULL) ota_event->u.Pom_SessionRequest_Req.smsc_id = smsc_id; else ota_event->u.Pom_SessionRequest_Req.smsc_id = NULL; if (dlr_url != NULL) ota_event->u.Pom_SessionRequest_Req.dlr_url = dlr_url; else ota_event->u.Pom_SessionRequest_Req.dlr_url = NULL; ota_event->u.Pom_SessionRequest_Req.dlr_mask = e->u.Push_Message.dlr_mask; if (smsbox_id != NULL) ota_event->u.Pom_SessionRequest_Req.smsbox_id = smsbox_id; else ota_event->u.Pom_SessionRequest_Req.smsbox_id = NULL; ota_event->u.Pom_SessionRequest_Req.service_name = service_name; dispatch_to_ota(ota_event);}/* * We store data to push machine, because it is possible that we do not have * a session when push request happens. */static void request_confirmed_push(long last, PPGPushMachine *pm, PPGSessionMachine *sm){ WAPEvent *ota_event; List *push_headers; gw_assert(last == 0 || last == 1); push_machine_assert(pm); session_machine_assert(sm); push_headers = http_header_duplicate(pm->push_headers); ota_event = wap_event_create(Po_ConfirmedPush_Req); ota_event->u.Po_ConfirmedPush_Req.server_push_id = pm->push_id; ota_event->u.Po_ConfirmedPush_Req.push_headers = push_headers; ota_event->u.Po_ConfirmedPush_Req.authenticated = pm->authenticated; ota_event->u.Po_ConfirmedPush_Req.trusted = pm->trusted; ota_event->u.Po_ConfirmedPush_Req.last = last; if (pm->push_data != NULL) ota_event->u.Po_ConfirmedPush_Req.push_body = octstr_duplicate(pm->push_data); else ota_event->u.Po_ConfirmedPush_Req.push_body = NULL; ota_event->u.Po_ConfirmedPush_Req.session_handle = sm->session_id; debug("wap.push.ota", 0, "PPG: confirmed push request to OTA"); dispatch_to_ota(ota_event);}/* * There is to types of unit push requests: requesting ip services and sms * services. Address type tells the difference. */static void request_unit_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_Unit_Push_Req); ota_event->u.Po_Unit_Push_Req.addr_tuple = wap_addr_tuple_duplicate(pm->addr_tuple);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -