1 /* ==================================================================== 
     2  * The Kannel Software License, Version 1.0 
     4  * Copyright (c) 2001-2018 Kannel Group  
     5  * Copyright (c) 1998-2001 WapIT Ltd.   
     8  * Redistribution and use in source and binary forms, with or without 
     9  * modification, are permitted provided that the following conditions 
    12  * 1. Redistributions of source code must retain the above copyright 
    13  *    notice, this list of conditions and the following disclaimer. 
    15  * 2. Redistributions in binary form must reproduce the above copyright 
    16  *    notice, this list of conditions and the following disclaimer in 
    17  *    the documentation and/or other materials provided with the 
    20  * 3. The end-user documentation included with the redistribution, 
    21  *    if any, must include the following acknowledgment: 
    22  *       "This product includes software developed by the 
    23  *        Kannel Group (http://www.kannel.org/)." 
    24  *    Alternately, this acknowledgment may appear in the software itself, 
    25  *    if and wherever such third-party acknowledgments normally appear. 
    27  * 4. The names "Kannel" and "Kannel Group" must not be used to 
    28  *    endorse or promote products derived from this software without 
    29  *    prior written permission. For written permission, please  
    30  *    contact org@kannel.org. 
    32  * 5. Products derived from this software may not be called "Kannel", 
    33  *    nor may "Kannel" appear in their name, without prior written 
    34  *    permission of the Kannel Group. 
    36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
    37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
    38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
    39  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
    40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
    41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
    42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
    43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
    44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
    45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
    46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    47  * ==================================================================== 
    49  * This software consists of voluntary contributions made by many 
    50  * individuals on behalf of the Kannel Group.  For more information on  
    51  * the Kannel Group, please see <http://www.kannel.org/>. 
    53  * Portions of this software are based upon software originally written at  
    54  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
    58  * wsp_server_session_states.def - states for WSP session state machines
    60  * Macro calls to generate rows of the state table. See the documentation for
    61  * guidance how to use and update these.
    63  * Note that `NULL' state is renamed to `NULL_SESSION' because NULL is
    69 STATE_NAME(NULL_SESSION)
    70 STATE_NAME(CONNECTING)
    71 STATE_NAME(TERMINATING)
    72 STATE_NAME(CONNECTING_2)
    76 STATE_NAME(RESUMING_2)
    80    e->tcl == 2 && pdu->type == Connect,
    85        /* Send TR-Invoke.res to WTP */
    86        wtp_event = wap_event_create(TR_Invoke_Res);
    87        wtp_event->u.TR_Invoke_Res.handle = e->handle;
    88        dispatch_to_wtp_resp(wtp_event);
    90        /* Assign a session ID for this session.  We do this
    91         * early, instead of in the CONNECTING state, because
    92         * we want to use the session id as a way for the
    93         * application layer to refer back to this machine. */
    94        sm->session_id = next_wsp_session_id();
    96        if (pdu->u.Connect.capabilities_len > 0) {
    98            sm->request_caps = wsp_cap_unpack_list(
    99                pdu->u.Connect.capabilities);
   100            if (wsp_cap_get_client_sdu(sm->request_caps,&sdu)) {
   101                sm->client_SDU_size = sdu;
   104            sm->request_caps = gwlist_create();
   107        if (pdu->u.Connect.headers_len > 0) {
   111             hdrs = wsp_headers_unpack(pdu->u.Connect.headers, 0);
   112             http_header_pack(hdrs);
   113             gw_assert(sm->http_headers == NULL);
   114             sm->http_headers = hdrs;
   117              * Get WSP encoding version if provided by device and remember in
   118              * session machine for later use in encoding tokenized values.
   120             encoding = http_header_value(sm->http_headers, octstr_imm("Encoding-Version"));
   121             if (encoding != NULL) {
   122                 debug("wsp",0,"WSP: Session machine: Encoding-Version: %s", 
   123                       octstr_get_cstr(encoding));
   124                 sm->encoding_version = wsp_encoding_string_to_version(encoding);
   126                 /* WAP-230-WSP-20010705-a, section 8.4.2.70, page 97 defines
   127                  * by a MUST argument that a non-present Encoding-Version header 
   128                  * should be interpreted as WSP 1.2 compliant.
   130                 sm->encoding_version = WSP_1_2; 
   132             octstr_destroy(encoding);
   135        /* Send S-Connect.ind to application layer */
   136        new_event = wap_event_create(S_Connect_Ind);
   137        new_event->u.S_Connect_Ind.addr_tuple =
   138            wap_addr_tuple_duplicate(e->addr_tuple);
   139        new_event->u.S_Connect_Ind.client_headers =
   140            http_header_duplicate(sm->http_headers);
   141        new_event->u.S_Connect_Ind.requested_capabilities =
   142            wsp_cap_duplicate_list(sm->request_caps);
   143        new_event->u.S_Connect_Ind.session_id = sm->session_id;
   144        dispatch_to_appl(new_event);
   156        sm->reply_caps = wsp_cap_duplicate_list(
   157                e->negotiated_capabilities);
   159        /* Send Disconnect event to existing sessions for client. */
   160        disconnect_other_sessions(sm);
   162        /* Assign a Session_ID for this session. */
   163        /* We've already done that in the NULL_STATE. */
   165        /* TR-Result.req(ConnectReply) */
   166        ospdu = make_connectreply_pdu(sm);
   168        wtp_event = wap_event_create(TR_Result_Req);
   169        wtp_event->u.TR_Result_Req.user_data = ospdu;
   170        wtp_event->u.TR_Result_Req.handle = sm->connect_handle;
   171        dispatch_to_wtp_resp(wtp_event);
   173        /* Release all method transactions in HOLDING state. */
   174        release_holding_methods(sm);
   178 /* MISSING: CONNECTING, S_Disconnect_Req, reason == 301 (moved permanently) or
   179  * 302 (moved temporarily). */
   181 /* MISSING: CONNECTING, S_Disconnect_Req, reason == anything else */
   187        /* TR-Abort.req(DISCONNECT) the Connect transaction */
   188        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   190        /* Abort(DISCONNECT) all method transactions */
   191        abort_methods(sm, WSP_ABORT_DISCONNECT);
   193        /* S-Disconnect.ind(DISCONNECT) */
   194        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   202        /* TR-Abort.req(DISCONNECT) the Connect transaction */
   203        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   205        /* Abort(DISCONNECT) all method transactions */
   206        abort_methods(sm, WSP_ABORT_DISCONNECT);
   208        /* S-Disconnect.ind(SUSPEND) */
   209        indicate_disconnect(sm, WSP_ABORT_SUSPEND);
   215    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
   217        WSPMethodMachine *msm;
   219        /* Start new method transaction */
   220        msm = method_machine_create(sm, e->handle);
   222        /* Hand off the event to the new method machine */
   223        handle_method_event(sm, msm, current_event, pdu);
   229    e->tcl == 2 && pdu->type == Resume,
   231        /* TR-Abort.req(DISCONNECT) the TR-Invoke */
   232        send_abort(WSP_ABORT_DISCONNECT, e->handle);
   238    e->handle == sm->connect_handle,
   240        /* Abort(DISCONNECT) all method transactions */
   241        abort_methods(sm, WSP_ABORT_DISCONNECT);
   243        /* S-Disconnect.ind(abort reason) */
   244        indicate_disconnect(sm, e->abort_code);
   250    e->handle != sm->connect_handle,
   252        WSPMethodMachine *msm;
   254        /* See method state table  */
   255        msm = find_method_machine(sm, e->handle);
   256        handle_method_event(sm, msm, current_event, pdu);
   264        /* TR-Abort.req(DISCONNECT) remaining transport transaction */
   265        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   273        /* TR-Abort.req(SUSPEND) remaining transport transaction */
   274        send_abort(WSP_ABORT_SUSPEND, sm->connect_handle);
   294 /* MISSING: CONNECTING_2, S-Disconnect.req */
   300        /* TR-Abort.req(DISCONNECT) the Connect transaction */
   301        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   303        /* Abort(DISCONNECT) all method and push transactions */
   304        abort_methods(sm, WSP_ABORT_DISCONNECT);
   306        /* S-Disconnect.ind(DISCONNECT) */
   307        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   315        WSPMethodMachine *msm;
   317        /* See method state table */
   318        msm = find_method_machine(sm, e->server_transaction_id);
   319        handle_method_event(sm, msm, current_event, pdu);
   327        WSPMethodMachine *msm;
   329        /* See method state table */
   330        msm = find_method_machine(sm, e->server_transaction_id);
   331        handle_method_event(sm, msm, current_event, pdu);
   341                 pdu = make_push_pdu(current_event);
   342                 send_invoke(sm, pdu, current_event, TRANSACTION_CLASS_0);
   350                 /* Start new push transaction*/
   353                 spm = push_machine_create(sm, e->server_push_id);
   354                 handle_push_event(sm, spm, current_event);   
   362        /* Session Resume facility disabled */
   364        /* TR-Abort.req(DISCONNECT) the Connect transaction */
   365        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   367        /* Abort(DISCONNECT) all method and push transactions */
   368        abort_methods(sm, WSP_ABORT_DISCONNECT);
   370        /* S-Disconnect.ind(SUSPEND) */
   371        indicate_disconnect(sm, WSP_ABORT_SUSPEND);
   379        /* Session Resume facility enabled */
   381        /* TR-Abort.req(SUSPEND) the Connect transaction */
   382        send_abort(WSP_ABORT_SUSPEND, sm->connect_handle);
   384        /* Abort(SUSPEND) all method and push transactions */
   385        abort_methods(sm, WSP_ABORT_SUSPEND);
   387        /* S-Suspend.ind(SUSPEND) */
   388        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   394    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
   396        WSPMethodMachine *msm;
   399        /* Start new method transaction */
   400        msm = method_machine_create(sm, e->handle);
   402        /* Hand off the event to the new method machine */
   403        handle_method_event(sm, msm, current_event, pdu);
   405        /* Release the new method transaction */
   406        new_event = wap_event_create(Release_Event);
   407        handle_method_event(sm, msm, new_event, NULL);
   408        wap_event_destroy(new_event);
   414    e->tcl == 2 && pdu->type == Resume && !resume_enabled,
   416        /* Resume facility disabled */
   418        /* TR-Abort.req(DISCONNECT) the TR-Invoke */
   419        send_abort(WSP_ABORT_DISCONNECT, e->handle);
   425    e->tcl == 2 && pdu->type == Resume && resume_enabled,
   427        /* Resume facility enabled */
   433        wtp_event = wap_event_create(TR_Invoke_Res);
   434        wtp_event->u.TR_Invoke_Res.handle = e->handle;
   435        dispatch_to_wtp_resp(wtp_event);
   437        /* TR-Abort.req(RESUME) the Connect transaction */
   438        send_abort(WSP_ABORT_RESUME, sm->connect_handle);
   440        /* Abort(RESUME) all method and push transactions */
   441        abort_methods(sm, WSP_ABORT_RESUME);
   443        /* S-Suspend.ind(RESUME) */
   444        indicate_suspend(sm, WSP_ABORT_RESUME);
   447        new_headers = unpack_new_headers(sm, pdu->u.Resume.headers);
   448        indicate_resume(sm, e->addr_tuple, new_headers);
   449        http_destroy_headers(new_headers);
   451        sm->resume_handle = e->handle;
   457    e->tcl == 0 && pdu->type == Disconnect,
   459        /* TR-Abort.req(DISCONNECT) the Connect transaction */
   460        send_abort(WSP_ABORT_DISCONNECT, sm->connect_handle);
   462        /* Abort(DISCONNECT) all method and push transactions */
   463        abort_methods(sm, WSP_ABORT_DISCONNECT);
   465        /* S-Disconnect.ind(DISCONNECT) */
   466        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   472    e->tcl == 0 && pdu->type == Suspend && resume_enabled,
   474        /* Resume facility enabled */
   476        /* TR-Abort.req(SUSPEND) the Connect transaction */
   477        send_abort(WSP_ABORT_SUSPEND, sm->connect_handle);
   479        /* Abort(SUSPEND) all method and push transactions */
   480        abort_methods(sm, WSP_ABORT_SUSPEND);
   482        /* S-Suspend.ind(SUSPEND) */
   483        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   491                 /* See push state table*/
   494                 spm = find_push_machine(sm, e->handle);
   495                 handle_push_event(sm, spm, current_event);
   501    e->handle == sm->connect_handle,
   508    e->handle != sm->connect_handle,
   510        WSPMethodMachine *msm;
   512        /* See method state table */
   513        msm = find_method_machine(sm, e->handle);
   514        handle_method_event(sm, msm, current_event, pdu);
   520    e->handle == sm->connect_handle,
   522        /* Abort(DISCONNECT) all method and push transactions */
   523        abort_methods(sm, WSP_ABORT_DISCONNECT);
   525        /* S-Disconnect.ind(abort reason) */
   526        indicate_disconnect(sm, e->abort_code);
   531  * A separate flag tells is the indicator the initiator or the responder.
   536    e->handle != sm->connect_handle && e->ir_flag == RESPONDER_INDICATION,
   538        WSPMethodMachine *msm;
   540        /* See method state table */
   541        msm = find_method_machine(sm, e->handle);
   542        handle_method_event(sm, msm, current_event, pdu);
   548    e->handle != sm->connect_handle && e->ir_flag == INITIATOR_INDICATION,
   552        /* See push state table */
   553        m = find_push_machine(sm, e->handle);
   554        handle_push_event(sm, m, current_event);
   558 /* MISSING: CONNECTED, S-Disconnect.req */
   564        /* Abort(DISCONNECT) all method and push transactions */
   565        abort_methods(sm, WSP_ABORT_DISCONNECT);
   567        /* S-Disconnect.ind(DISCONNECT) */
   568        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   576        WSPMethodMachine *msm;
   578        /* See method state table */
   579        msm = find_method_machine(sm, e->server_transaction_id);
   580        handle_method_event(sm, msm, current_event, pdu);
   588        WSPMethodMachine *msm;
   590        /* See method state table */
   591        msm = find_method_machine(sm, e->server_transaction_id);
   592        handle_method_event(sm, msm, current_event, pdu);
   602                pdu = make_push_pdu(current_event);
   603                send_invoke(sm, pdu, current_event, TRANSACTION_CLASS_0);
   611                /* Start new push transaction*/
   614                 spm = push_machine_create(sm, e->server_push_id);
   615                 handle_push_event(sm, spm, current_event);
   623        /* Session Resume facility disabled */
   625        /* Abort(SUSPEND) all method and push transactions */
   626        abort_methods(sm, WSP_ABORT_SUSPEND);
   628        /* S-Disconnect.ind(SUSPEND) */
   629        indicate_disconnect(sm, WSP_ABORT_SUSPEND);
   637        /* Session Resume facility enabled */
   639        /* Abort(SUSPEND) all method and push transactions */
   640        abort_methods(sm, WSP_ABORT_SUSPEND);
   642        /* S-Suspend.ind(SUSPEND) */
   643        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   649    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
   651        WSPMethodMachine *msm;
   654        /* Start new method transaction */
   655        msm = method_machine_create(sm, e->handle);
   657        /* Hand off the event to the new method machine */
   658        handle_method_event(sm, msm, current_event, pdu);
   660        /* Release the new method transaction */
   661        new_event = wap_event_create(Release_Event);
   662        handle_method_event(sm, msm, new_event, NULL);
   663        wap_event_destroy(new_event);
   669    e->tcl == 2 && pdu->type == Resume && !resume_enabled,
   671        /* Resume facility disabled */
   673        /* TR-Abort.req(DISCONNECT) the TR-Invoke */
   674        send_abort(WSP_ABORT_DISCONNECT, e->handle);
   680    e->tcl == 2 && pdu->type == Resume && resume_enabled,
   682        /* Resume facility enabled */
   688        wtp_event = wap_event_create(TR_Invoke_Res);
   689        wtp_event->u.TR_Invoke_Res.handle = e->handle;
   690        dispatch_to_wtp_resp(wtp_event);
   692        /* Abort(RESUME) all method and push transactions */
   693        abort_methods(sm, WSP_ABORT_RESUME);
   695        /* S-Suspend.ind(RESUME) */
   696        indicate_suspend(sm, WSP_ABORT_RESUME);
   699        new_headers = unpack_new_headers(sm, pdu->u.Resume.headers);
   700        indicate_resume(sm, e->addr_tuple, new_headers);
   701        http_destroy_headers(new_headers);
   703        sm->resume_handle = e->handle;
   709    e->tcl == 0 && pdu->type == Disconnect,
   711        /* Abort(DISCONNECT) all method and push transactions */
   712        abort_methods(sm, WSP_ABORT_DISCONNECT);
   714        /* S-Disconnect.ind(DISCONNECT) */
   715        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   721    e->tcl == 0 && pdu->type == Suspend && resume_enabled,
   723        /* Abort(SUSPEND) all method and push transactions */
   724        abort_methods(sm, WSP_ABORT_SUSPEND);
   726        /* S-Suspend.ind(SUSPEND) */
   727        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   735                 /* See push state table*/
   738                 spm = find_push_machine(sm, e->handle);
   739                 handle_push_event(sm, spm, current_event);
   745    e->handle != sm->connect_handle,
   747        WSPMethodMachine *msm;
   749        /* See method state table */
   750        msm = find_method_machine(sm, e->handle);
   751        handle_method_event(sm, msm, current_event, pdu);
   756  * Event TR-Abort.ind has a separate flag telling is the indicator the 
   757  * initiator or the responder.
   761    e->handle != sm->connect_handle  && e->ir_flag == RESPONDER_INDICATION,
   763        WSPMethodMachine *msm;
   765        /* See method state table */
   766        msm = find_method_machine(sm, e->handle);
   767        handle_method_event(sm, msm, current_event, pdu);
   773    e->handle != sm->connect_handle && e->ir_flag == INITIATOR_INDICATION,
   777        /* See push state table */
   778        m = find_push_machine(sm, e->handle);
   779        handle_push_event(sm, m, current_event);
   783 /* MISSING: SUSPENDED, S-Disconnect.req */
   789        /* S-Disconnect.ind(DISCONNECT) */
   790        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   796    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
   798        /* TR-Abort.req(SUSPEND) the TR-Invoke */
   799        send_abort(WSP_ABORT_SUSPEND, e->handle);
   805    e->tcl == 2 && pdu->type == Resume,
   811        wtp_event = wap_event_create(TR_Invoke_Res);
   812        wtp_event->u.TR_Invoke_Res.handle = e->handle;
   813        dispatch_to_wtp_resp(wtp_event);
   816        new_headers = unpack_new_headers(sm, pdu->u.Resume.headers);
   817        indicate_resume(sm, e->addr_tuple, new_headers);
   818        http_destroy_headers(new_headers);
   821        sm->resume_handle = e->handle;
   827    e->tcl == 0 && pdu->type == Disconnect,
   829        /* S-Disconnect.ind(DISCONNECT) */
   830        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   834 /* MISSING: RESUMING, S-Disconnect.req */
   840        /* TR-Abort.req(DISCONNECT) the Resume transaction */
   841        send_abort(WSP_ABORT_DISCONNECT, sm->resume_handle);
   843        /* Abort(DISCONNECT) all method transactions */
   844        abort_methods(sm, WSP_ABORT_DISCONNECT);
   846        /* S-Disconnect.ind(DISCONNECT) */
   847        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   858        /* Disconnect any other session for the peer address quadruplet */
   859        disconnect_other_sessions(sm);
   861        /* Bind session to new peer address quadruplet */
   862        /* this happens automatically XXX Not true */
   864        /* TR-Result.req(Reply) */
   865        if (e->server_headers == NULL)
   866            e->server_headers = http_create_empty_headers();
   868        ospdu = make_resume_reply_pdu(sm, e->server_headers);
   869        wtp_event = wap_event_create(TR_Result_Req);
   870        wtp_event->u.TR_Result_Req.user_data = ospdu;
   871        wtp_event->u.TR_Result_Req.handle = sm->resume_handle;
   872        dispatch_to_wtp_resp(wtp_event);
   874        /* Release all method transactions in HOLDING state */
   875        release_holding_methods(sm);
   883        /* TR-Abort.req(SUSPEND) the Resume transaction */
   884        send_abort(WSP_ABORT_SUSPEND, sm->resume_handle);
   886        /* Abort(SUSPEND) all method transactions */
   887        abort_methods(sm, WSP_ABORT_SUSPEND);
   889        /* S-Suspend.ind(SUSPEND) */
   890        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   896    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
   898        /* Start new method transaction (see method state table) */
   899        WSPMethodMachine *msm;
   900        msm = method_machine_create(sm, e->handle);
   901        handle_method_event(sm, msm, current_event, pdu);
   907    e->tcl == 2 && pdu->type == Resume,
   913        wtp_event = wap_event_create(TR_Invoke_Res);
   914        wtp_event->u.TR_Invoke_Res.handle = e->handle;
   915        dispatch_to_wtp_resp(wtp_event);
   917        /* TR-Abort.req(RESUME) the old Resume transaction */
   918        send_abort(WSP_ABORT_RESUME, sm->resume_handle);
   920        /* Abort(RESUME) all method transactions */
   921        abort_methods(sm, WSP_ABORT_RESUME);
   923        /* S-Suspend.ind(RESUME) */
   924        indicate_suspend(sm, WSP_ABORT_RESUME);
   927        new_headers = unpack_new_headers(sm, pdu->u.Resume.headers);
   928        indicate_resume(sm, e->addr_tuple, new_headers);
   929        http_destroy_headers(new_headers);
   932        sm->resume_handle = e->handle;
   938    e->tcl == 0 && pdu->type == Suspend,
   940        /* TR-Abort.req(SUSPEND) the Resume transaction */
   941        send_abort(WSP_ABORT_SUSPEND, sm->resume_handle);
   943        /* Abort(SUSPEND) all method transactions */
   944        abort_methods(sm, WSP_ABORT_SUSPEND);
   946        /* S-Suspend.ind(SUSPEND) */
   947        indicate_suspend(sm, WSP_ABORT_SUSPEND);
   953    e->tcl == 0 && pdu->type == Disconnect,
   955        /* TR-Abort.req(DISCONNECT) the Resume transaction */
   956        send_abort(WSP_ABORT_DISCONNECT, sm->resume_handle);
   958        /* Abort(DISCONNECT) all method transactions */
   959        abort_methods(sm, WSP_ABORT_DISCONNECT);
   961        /* S-Disconnect.ind(DISCONNECT) */
   962        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   968    e->handle == sm->resume_handle,
   970        /* Abort(SUSPEND) all method transactions */
   971        abort_methods(sm, WSP_ABORT_SUSPEND);
   973        /* S-Suspend.ind(abort reason) */
   974        indicate_suspend(sm, e->abort_code);
   978 /* MISSING: RESUMING_2, S-Disconnect.req */
   984        /* TR-Abort.req(DISCONNECT) the Resume */
   985        send_abort(WSP_ABORT_DISCONNECT, sm->resume_handle);
   987        /* Abort(DISCONNECT) all method and push transactions */
   988        abort_methods(sm, WSP_ABORT_DISCONNECT);
   990        /* S-Disconnect.ind(DISCONNECT) */
   991        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
   999        WSPMethodMachine *msm;
  1001        /* See method state table */
  1002        msm = find_method_machine(sm, e->server_transaction_id);
  1003        handle_method_event(sm, msm, current_event, pdu);
  1011        WSPMethodMachine *msm;
  1013        /* See method state table */
  1014        msm = find_method_machine(sm, e->server_transaction_id);
  1015        handle_method_event(sm, msm, current_event, pdu);
  1025                 pdu = make_push_pdu(current_event);
  1026                 send_invoke(sm, pdu, current_event, TRANSACTION_CLASS_0);
  1031         S_ConfirmedPush_Req,
  1034                 /* Start new push transaction*/
  1035                 WSPPushMachine *spm;
  1037                 spm = push_machine_create(sm, e->server_push_id);
  1038                 handle_push_event(sm, spm, current_event);
  1046        /* TR-Abort.req(SUSPEND) the Resume transaction */
  1047        send_abort(WSP_ABORT_SUSPEND, sm->resume_handle);
  1049        /* Abort(SUSPEND) all method and push transactions */
  1050        abort_methods(sm, WSP_ABORT_SUSPEND);
  1052        /* S-Suspend.ind(SUSPEND) */
  1053        indicate_suspend(sm, WSP_ABORT_SUSPEND);
  1059    e->tcl == 2 && (pdu->type == Get || pdu->type == Post),
  1061        WSPMethodMachine *msm;
  1062        WAPEvent *new_event;
  1064        /* Start new method transaction (see method state table) */
  1065        msm = method_machine_create(sm, e->handle);
  1066        handle_method_event(sm, msm, current_event, pdu);
  1068        /* Release the new method transaction */
  1069        new_event = wap_event_create(Release_Event);
  1070        handle_method_event(sm, msm, new_event, NULL);
  1071        wap_event_destroy(new_event);
  1077    e->tcl == 2 && pdu->type == Resume,
  1079        WAPEvent *wtp_event;
  1083        wtp_event = wap_event_create(TR_Invoke_Res);
  1084        wtp_event->u.TR_Invoke_Res.handle = e->handle;
  1085        dispatch_to_wtp_resp(wtp_event);
  1087        /* TR-Abort.req(RESUME) the old Resume transaction*/
  1088        send_abort(WSP_ABORT_RESUME, sm->resume_handle);
  1090        /* Abort(RESUME) all method and push transactions */
  1091        abort_methods(sm, WSP_ABORT_RESUME);
  1093        /* S-Suspend.ind(RESUME) */
  1094        indicate_suspend(sm, WSP_ABORT_RESUME);
  1097        new_headers = unpack_new_headers(sm, pdu->u.Resume.headers);
  1098        indicate_resume(sm, e->addr_tuple, new_headers);
  1099        http_destroy_headers(new_headers);
  1102        sm->resume_handle = e->handle;
  1108    e->tcl == 0 && pdu->type == Suspend,
  1110        /* TR-Abort.req(SUSPEND) the Resume transaction */
  1111        send_abort(WSP_ABORT_SUSPEND, sm->resume_handle);
  1113        /* Abort(SUSPEND) all method and push transactions */
  1114        abort_methods(sm, WSP_ABORT_SUSPEND);
  1116        /* S-Suspend.ind(SUSPEND) */
  1117        indicate_suspend(sm, WSP_ABORT_SUSPEND);
  1123    e->tcl == 0 && pdu->type == Disconnect,
  1125        /* TR-Abort.req(DISCONNECT) the Resume */
  1126        send_abort(WSP_ABORT_DISCONNECT, sm->resume_handle);
  1128        /* Abort(DISCONNECT) all method and push transactions */
  1129        abort_methods(sm, WSP_ABORT_DISCONNECT);
  1131        /* S-Disconnect.ind(DISCONNECT) */
  1132        indicate_disconnect(sm, WSP_ABORT_DISCONNECT);
  1140                 /* See push state table*/
  1141                 WSPPushMachine *spm;
  1143                 spm = find_push_machine(sm, e->handle);
  1144                 handle_push_event(sm, spm, current_event);
  1150    e->handle == sm->resume_handle,
  1157    e->handle != sm->resume_handle,
  1159        WSPMethodMachine *msm;
  1161        /* See method state table */
  1162        msm = find_method_machine(sm, e->handle);
  1163        handle_method_event(sm, msm, current_event, pdu);
  1169    e->handle == sm->resume_handle,
  1171        /* Abort(SUSPEND) all method and push transactions */
  1172        abort_methods(sm, WSP_ABORT_SUSPEND);
  1174        /* S-Suspend.ind(abort reason) */
  1175        indicate_suspend(sm, e->abort_code);
  1180  * A separate flag tells is the indicator the initiator or the responder
  1185    e->handle != sm->resume_handle && e->ir_flag == RESPONDER_INDICATION,
  1187        WSPMethodMachine *msm;
  1189        /* See method state table */
  1190        msm = find_method_machine(sm, e->handle);
  1191        handle_method_event(sm, msm, current_event, pdu);
  1197    e->handle != sm->connect_handle && e->ir_flag == INITIATOR_INDICATION,
  1201        /* See push state table */
  1202        m = find_push_machine(sm, e->handle);
  1203        handle_push_event(sm, m, current_event);