80     #define STATE_NAME(name) name,    81     #define ROW(state, event, condition, action, next_state)    84     #define STATE_NAME(name) name,    85     #define ROW(state, event, condition, action, next_state)    88         #define STATE_NAME(name) name,    89         #define ROW(state, event, condition, action, next_state)   162 static void send_abort(
long reason, 
long handle);
   166                             List *client_headers);
   219     debug(
"wap.wsp", 0, 
"WSP: %ld session machines left.",
   250                 warning(0, 
"WSP: Broken PDU ignored.");
   281     switch (event->
type) {
   284                 event->
u.TR_Invoke_Ind.addr_tuple);
   289                 event->
u.TR_Invoke_Cnf.addr_tuple);
   294                 event->
u.TR_Result_Cnf.addr_tuple);
   299                 event->
u.TR_Abort_Ind.addr_tuple);
   303         session_id = 
event->u.S_Connect_Res.session_id;
   307         session_id = 
event->u.S_Resume_Res.session_id;
   310     case Disconnect_Event:
   311         session_id = 
event->u.Disconnect_Event.session_handle;
   315         session_id = 
event->u.Suspend_Event.session_handle;
   318     case S_MethodInvoke_Res:
   319         session_id = 
event->u.S_MethodInvoke_Res.session_id;
   322     case S_MethodResult_Req:
   323         session_id = 
event->u.S_MethodResult_Req.session_id;
   326     case S_ConfirmedPush_Req:
   327                 session_id = 
event->u.S_ConfirmedPush_Req.session_id;
   331                 session_id = 
event->u.S_Push_Req.session_id;
   335         error(0, 
"WSP: Cannot find machine for %s event",
   339     gw_assert(tuple != NULL || session_id != -1);
   347     if (event->
type == TR_Invoke_Ind &&
   348         event->
u.TR_Invoke_Ind.tcl == 2 &&
   349         pdu->
type == Connect) {
   356             sm->connect_handle = 
event->u.TR_Invoke_Ind.handle;
   358     } 
else if (event->
type == TR_Invoke_Ind &&
   359            event->
u.TR_Invoke_Ind.tcl == 2 &&
   360            pdu->
type == Resume) {
   363         session_id = pdu->
u.Resume.sessionid;
   369                 event->
u.TR_Invoke_Ind.handle);
   375     } 
else if (event->
type == TR_Invoke_Ind) {
   378         if (sm == NULL && (event->
u.TR_Invoke_Ind.tcl == 1 ||
   379                 event->
u.TR_Invoke_Ind.tcl == 2)) {
   381                 event->
u.TR_Invoke_Ind.handle);
   386         if (session_id != -1) {
   398             error(0, 
"WSP: Cannot find session machine for event.");
   410     debug(
"wap.wsp", 0, 
"WSP: machine %p, state %s, event %s",
   415     #define STATE_NAME(name)   416     #define ROW(state_name, event, condition, action, next_state) \   419             e = ¤t_event->u.event; \   420             if (sm->state == state_name && \   421                current_event->type == event && \   424                 sm->state = next_state; \   425                 debug("wap.wsp", 0, "WSP %ld: New state %s", \   426                     sm->session_id, #next_state); \   437     if (sm->state == NULL_SESSION)
   446     if (event->
type == TR_Invoke_Ind &&
   447         (event->
u.TR_Invoke_Ind.tcl == 1 ||
   448          event->
u.TR_Invoke_Ind.tcl == 2)) {
   449         warning(0, 
"WSP: Can't handle TR-Invoke.ind, aborting transaction.");
   450         debug(
"wap.wsp", 0, 
"WSP: The unhandled event:");
   453             event->
u.TR_Invoke_Ind.handle);
   455     } 
else if (event->
type == TR_Invoke_Ind) {
   456         warning(0, 
"WSP: Can't handle TR-Invoke.ind, ignoring.");
   457         debug(
"wap.wsp", 0, 
"WSP: The ignored event:");
   461         error(0, 
"WSP: Can't handle event. Aborting session.");
   462         debug(
"wap.wsp", 0, 
"WSP: The unhandled event:");
   470         if (event->
type == TR_Result_Cnf) {
   472                 event->
u.TR_Result_Cnf.handle);
   487     debug(
"wap.wsp", 0, 
"WSP: Created WSPMachine %p", (
void *) p);
   489     #define INTEGER(name) p->name = 0;   490     #define OCTSTR(name) p->name = NULL;   491     #define HTTPHEADERS(name) p->name = NULL;   492     #define ADDRTUPLE(name) p->name = NULL;   493     #define MACHINESLIST(name) p->name = gwlist_create();   494     #define CAPABILITIES(name) p->name = NULL;   495     #define COOKIES(name) p->name = gwlist_create();   496     #define REFERER(name) p->name = NULL;   497     #define MACHINE(fields) fields   500     p->state = NULL_SESSION;
   504     p->client_SDU_size = 1400;
   519         warning(0, 
"Destroying WSP session with %ld active methods\n",
   528         warning(0, 
"Destroying WSP session with %ld active pushes\n",
   539     debug(
"wap.wsp", 0, 
"Destroying WSPMachine %p", pp);
   542     #define INTEGER(name) p->name = 0;   543     #define OCTSTR(name) octstr_destroy(p->name);   544     #define HTTPHEADERS(name) http_destroy_headers(p->name);   545     #define ADDRTUPLE(name) wap_addr_tuple_destroy(p->name);   546     #define MACHINESLIST(name) destroy_##name(p->name);   547     #define CAPABILITIES(name) wsp_cap_destroy_list(p->name);   548     #define COOKIES(name) cookies_destroy(p->name);   549     #define REFERER(name) octstr_destroy(p->name);   550     #define MACHINE(fields) fields   568         warning(0, 
"No method machine for event.");
   573     debug(
"wap.wsp", 0, 
"WSP: method %ld, state %s, event %s",
   577     gw_assert(sm->session_id == msm->session_id);
   579     #define STATE_NAME(name)   580     #define ROW(state_name, event, condition, action, next_state) \   583             e = ¤t_event->u.event; \   584             if (msm->state == state_name && \   585                current_event->type == event && \   588                 msm->state = next_state; \   589                 debug("wap.wsp", 0, "WSP %ld/%ld: New method state %s", \   590                     msm->session_id, msm->transaction_id, #next_state); \   599     if (msm->state == NULL_METHOD) {
   610     msm = gw_malloc(
sizeof(*msm));
   612     #define INTEGER(name) msm->name = 0;   613     #define ADDRTUPLE(name) msm->name = NULL;   614     #define EVENT(name) msm->name = NULL;   615     #define MACHINE(fields) fields   618     msm->transaction_id = wtp_handle;
   619     msm->state = NULL_METHOD;
   621     msm->session_id = sm->session_id;
   638     debug(
"wap.wsp", 0, 
"Destroying WSPMethodMachine %ld",
   639             msm->transaction_id);
   641     #define INTEGER(name)   642     #define ADDRTUPLE(name) wap_addr_tuple_destroy(msm->name);   643     #define EVENT(name) wap_event_destroy(msm->name);   644     #define MACHINE(fields) fields   654         warning(0, 
"No push machine for event.");
   659         debug(
"wap.wsp", 0, 
"WSP(tid/pid): push %ld/%ld, state %s, event %s",
   660         pm->transaction_id, pm->server_push_id, 
state_name(pm->state), 
   662     gw_assert(sm->session_id == pm->session_id);
   664         #define STATE_NAME(name)   665     #define ROW(state_name, event, condition, action, next_state) \   667             if (pm->state == state_name && \   668             current_event->type == event && \   671                  pm->state = next_state; \   672                  debug("wap.wsp", 0, "WSP %ld/%ld: New push state %s", \   673                        pm->session_id, pm->transaction_id, #next_state); \   681         if (pm->state == SERVER_PUSH_NULL_STATE) {
   694         #define INTEGER(name) m->name = 0;   695         #define ADDRTUPLE(name) m->name = NULL;   696         #define HTTPHEADER(name) m->name = http_create_empty_headers();   697         #define MACHINE(fields) fields   700         m->server_push_id = pid;
   701         m->transaction_id = pid;
   702     m->state = SERVER_PUSH_NULL_STATE;
   704     m->session_id = sm->session_id;
   718         debug(
"wap.wsp", 0, 
"Destroying WSPPushMachine %ld",
   720         #define INTEGER(name)    721         #define ADDRTUPLE(name) wap_addr_tuple_destroy(m->name);   722         #define HTTPHEADER(name) http_destroy_headers(m->name);   723         #define MACHINE(fields) fields   731     #define STATE_NAME(name) case name: return #name;   732     #define ROW(state, event, cond, stmt, next_state)   735     #define STATE_NAME(name) case name: return #name;   736     #define ROW(state, event, cond, stmt, next_state)   739         #define STATE_NAME(name) case name: return #name;   740         #define ROW(state, event, cond, stmt, next_state)   744         return "unknown wsp state";
   764         if (cap->
name != NULL)
   772             if (cap->
data != NULL &&
   776                 m->client_SDU_size = ui;
   781             if (cap->
data != NULL &&
   796                 warning(0, 
"WSP: Application layer tried to "   797                     "negotiate protocol options.");
   817         error(0, 
"WSP: Found illegal value in capabilities reply.");
   835             if ((ui >= 256 && ui < LONG_MAX) || ui == 0) {
   836                 m->client_SDU_size = ui;
   914     for (i = 0; i < len; i++) {
   934         return (cap->
data != NULL &&
  1012     Octstr *encoding_version;
  1039     List *reply_headers;
  1043     pdu->
u.ConnectReply.sessionid = m->session_id;
  1050     pdu->
u.ConnectReply.headers = 
  1070     if (headers == NULL) {
  1094         if (e->
u.S_ConfirmedPush_Req.push_headers == NULL) {
  1099             pdu->
u.ConfirmedPush.headers = 
  1102         if (e->
u.S_ConfirmedPush_Req.push_body == NULL)
  1105         pdu->
u.ConfirmedPush.data = 
  1120         if (e->
u.S_Push_Req.push_headers == NULL) {
  1125             pdu->
u.Push.headers = 
  1128         if (e->
u.S_Push_Req.push_body == NULL)
  1152     return wsp->session_id == *idp;
  1160     return msm->transaction_id == *idp;
  1167     return m->transaction_id == *idp;
  1195     if (old_sessions == NULL)
  1198     for (i = 0; i < 
gwlist_len(old_sessions); i++) {
  1215         if (sm->http_headers == NULL)
  1228         wtp_event->
u.TR_Abort_Req.abort_type = 0x01;
  1229         wtp_event->
u.TR_Abort_Req.abort_reason = reason;
  1230         wtp_event->
u.TR_Abort_Req.handle = handle;
  1259         wtp_event->
u.TR_Invoke_Req.addr_tuple = 
  1267         wtp_event->
u.TR_Invoke_Req.tcl = 
class;
  1268         if (e->
type == S_ConfirmedPush_Req)
  1269            wtp_event->
u.TR_Invoke_Req.handle = 
  1270                e->
u.S_ConfirmedPush_Req.server_push_id;
  1281     new_event->
u.S_Disconnect_Ind.reason_code = reason;
  1282     new_event->
u.S_Disconnect_Ind.redirect_security = 0;
  1283     new_event->
u.S_Disconnect_Ind.redirect_addresses = 0;
  1284     new_event->
u.S_Disconnect_Ind.error_headers = NULL;
  1285     new_event->
u.S_Disconnect_Ind.error_body = NULL;
  1286     new_event->
u.S_Disconnect_Ind.session_handle = sm->session_id;
  1295     new_event->
u.S_Suspend_Ind.reason = reason;
  1296     new_event->
u.S_Suspend_Ind.session_id = sm->session_id;
  1308     new_event->
u.S_Resume_Ind.session_id = sm->session_id;
  1317        ota_event->
u.S_PushAbort_Ind.push_id = spm->server_push_id;
  1318        ota_event->
u.S_PushAbort_Ind.reason = reason;
  1319        ota_event->
u.S_PushAbort_Ind.session_id = spm->session_id;
  1328        ota_event->
u.S_ConfirmedPush_Cnf.server_push_id = m->server_push_id;
  1329        ota_event->
u.S_ConfirmedPush_Cnf.session_id = m->session_id;
  1341         wtp_event->
u.TR_Abort_Req.abort_type = 0x00;
  1343         wtp_event->
u.TR_Abort_Req.abort_type = 0x01;
  1345     wtp_event->
u.TR_Abort_Req.abort_reason = reason;
  1346     wtp_event->
u.TR_Abort_Req.handle = msm->transaction_id;
  1357     new_event->
u.S_MethodAbort_Ind.transaction_id = msm->transaction_id;
  1358     new_event->
u.S_MethodAbort_Ind.reason = reason;
  1359     new_event->
u.S_MethodAbort_Ind.session_handle = msm->session_id;
  1367     return msm->state == HOLDING;
  1378     if (holding == NULL)
  1386     for (i = 0; i < len; i++) {
  1401     ab->
u.Abort_Event.reason = reason;
  1406     for (i = len - 1; i >= 0; i--) {
  1422     ab->
u.Abort_Event.reason = reason;
  1425     for (i = len - 1; i >= 0; i--) {
  1447     if (*
id == wsp->session_id) 
return 1;
 
long wsp_convert_http_status_to_wsp_status(long http_status)
 
void error(int err, const char *fmt,...)
 
int wsp_cap_get_push_mor(List *caps_list, unsigned long *mor)
 
void wsp_session_shutdown(void)
 
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
 
static void release_holding_methods(WSPMachine *sm)
 
static int find_by_session_id(void *session, void *idp)
 
void wsp_cap_destroy_list(List *caps_list)
 
void http_header_add(List *headers, char *name, char *contents)
 
gw_assert(wtls_machine->packet_to_send !=NULL)
 
int wsp_cap_get_server_sdu(List *caps_list, unsigned long *sdu)
 
void counter_destroy(Counter *counter)
 
static void handle_push_event(WSPMachine *session, WSPPushMachine *machine, WAPEvent *e)
 
void gwlist_append(List *list, void *item)
 
static void indicate_resume(WSPMachine *sm, WAPAddrTuple *tuple, List *client_headers)
 
static void indicate_disconnect(WSPMachine *sm, long reason)
 
static void abort_methods(WSPMachine *sm, long reason)
 
static void handle_session_event(WSPMachine *machine, WAPEvent *event, WSP_PDU *pdu)
 
static unsigned long next_wsp_session_id(void)
 
void gwlist_produce(List *list, void *item)
 
long gwlist_len(List *list)
 
static WSP_PDU * make_confirmedpush_pdu(WAPEvent *e)
 
void * gwlist_get(List *list, long pos)
 
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
 
void http_header_combine(List *old_headers, List *new_headers)
 
static void sanitize_capabilities(List *caps, WSPMachine *m)
 
void octstr_append_char(Octstr *ostr, int ch)
 
Capability * wsp_cap_create(int id, Octstr *name, Octstr *data)
 
static void strip_default_capabilities(List *caps, List *req)
 
static void push_machine_destroy(void *p)
 
void wsp_cap_dump(Capability *cap)
 
static WSPPushMachine * push_machine_create(WSPMachine *session, long id)
 
Octstr * wsp_pdu_pack(WSP_PDU *pdu)
 
WAPAddrTuple * addr_tuple
 
static WSP_PDU * make_push_pdu(WAPEvent *e)
 
static void abort_pushes(WSPMachine *sm, long reason)
 
List * wsp_cap_duplicate_list(List *caps_list)
 
static WSPMachine * machine_create(void)
 
static void confirm_push(WSPPushMachine *machine)
 
static int is_default_cap(Capability *cap)
 
#define octstr_get_cstr(ostr)
 
static int find_by_method_id(void *wspm_ptr, void *id_ptr)
 
void wap_event_dump(WAPEvent *event)
 
void gwthread_join_every(gwthread_func_t *func)
 
unsigned long counter_increase(Counter *counter)
 
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
 
void wsp_session_init(wap_dispatch_func_t *responder_dispatch, wap_dispatch_func_t *initiator_dispatch, wap_dispatch_func_t *application_dispatch, wap_dispatch_func_t *push_ota_dispatch)
 
static List * session_machines
 
List * gwlist_search_all(List *list, void *pattern, int(*cmp)(void *, void *))
 
static WSPPushMachine * find_push_machine(WSPMachine *m, long id)
 
void http_destroy_headers(List *headers)
 
WSP_PDU * wsp_pdu_create(int type)
 
int wsp_cap_get_client_sdu(List *caps_list, unsigned long *sdu)
 
static void method_abort(WSPMethodMachine *msm, long reason)
 
static int same_client(void *sm1, void *sm2)
 
static void send_invoke(WSPMachine *session, WSP_PDU *pdu, WAPEvent *e, long class)
 
Octstr * octstr_imm(const char *cstr)
 
Counter * counter_create(void)
 
static WSPMachine * find_session_machine(WAPEvent *event, WSP_PDU *pdu)
 
static Octstr * make_resume_reply_pdu(WSPMachine *m, List *headers)
 
void gwlist_delete(List *list, long pos, long count)
 
void wap_event_assert(WAPEvent *event)
 
void gwlist_remove_producer(List *list)
 
static void destroy_pushmachines(List *machines)
 
List * http_create_empty_headers(void)
 
void wap_event_destroy_item(void *event)
 
static WSPMethodMachine * find_method_machine(WSPMachine *, long id)
 
static void machine_destroy(void *p)
 
#define octstr_duplicate(ostr)
 
const char * wap_event_name(WAPEventName type)
 
int wsp_cap_get_method_mor(List *caps_list, unsigned long *mor)
 
static void main_thread(void *)
 
long gwlist_delete_equal(List *list, void *item)
 
static wap_dispatch_func_t * dispatch_to_appl
 
#define wap_event_create(type)
 
int wsp_cap_count(List *caps_list, int id, Octstr *name)
 
void warning(int err, const char *fmt,...)
 
static void refuse_unreplied_capabilities(List *caps, List *req)
 
static Octstr * make_connectreply_pdu(WSPMachine *m)
 
void octstr_destroy(Octstr *ostr)
 
void wap_addr_tuple_destroy(WAPAddrTuple *tuple)
 
static void destroy_methodmachines(List *machines)
 
#define gwthread_create(func, arg)
 
#define octstr_create(cstr)
 
static int find_by_push_id(void *m_ptr, void *id_ptr)
 
static WSPMethodMachine * method_machine_create(WSPMachine *, long)
 
void wsp_pdu_destroy(WSP_PDU *pdu)
 
static enum @91 run_status
 
static int wsp_encoding_string_to_version(Octstr *enc)
 
static void reply_known_capabilities(List *caps, List *req, WSPMachine *m)
 
void gwlist_insert(List *list, long pos, void *item)
 
static void indicate_method_abort(WSPMethodMachine *msm, long reason)
 
static void indicate_suspend(WSPMachine *sm, long reason)
 
static int id_belongs_to_session(void *, void *)
 
static void handle_method_event(WSPMachine *session, WSPMethodMachine *machine, WAPEvent *event, WSP_PDU *pdu)
 
static int transaction_belongs_to_session(void *session, void *tuple)
 
long octstr_len(const Octstr *ostr)
 
int wap_addr_tuple_same(WAPAddrTuple *a, WAPAddrTuple *b)
 
static Octstr * wsp_encoding_version_to_string(int version)
 
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
 
WSPMachine * find_session_machine_by_id(int id)
 
static List * unpack_new_headers(WSPMachine *sm, Octstr *hdrs)
 
void wsp_strings_shutdown(void)
 
void * gwlist_consume(List *list)
 
void wsp_strings_init(void)
 
static wap_dispatch_func_t * dispatch_to_wtp_resp
 
void debug(const char *place, int err, const char *fmt,...)
 
static void method_machine_destroy(void *msm)
 
static void send_abort_to_initiator(long reason, long handle)
 
static WAPEvent * make_abort(long reason, long handle)
 
static int resume_enabled
 
static List * make_reply_headers(WSPMachine *m)
 
static wap_dispatch_func_t * dispatch_to_wtp_init
 
static void cant_handle_event(WSPMachine *sm, WAPEvent *event)
 
List * http_header_duplicate(List *headers)
 
Octstr * wsp_cap_pack_list(List *caps_list)
 
void wsp_session_dispatch_event(WAPEvent *event)
 
static void indicate_pushabort(WSPPushMachine *machine, long reason)
 
static void disconnect_other_sessions(WSPMachine *sm)
 
long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos)
 
static List * make_capabilities_reply(WSPMachine *m)
 
static int method_is_holding(void *item, void *pattern)
 
void gwlist_add_producer(List *list)
 
int octstr_get_char(const Octstr *ostr, long pos)
 
static void send_abort(long reason, long handle)
 
static Counter * session_id_counter
 
void wsp_cap_destroy(Capability *cap)
 
WSP_PDU * wsp_pdu_unpack(Octstr *data)
 
static wap_dispatch_func_t * dispatch_to_ota
 
void wap_event_destroy(WAPEvent *event)
 
void wap_dispatch_func_t(WAPEvent *event)
 
static char * state_name(WSPState state)
 
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
 
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)