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_method_states.def
    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 the `NULL' state has been renamed to `NULL_METHOD' because
    64  * NULL is reserved by C.
    67 STATE_NAME(NULL_METHOD)
    69 STATE_NAME(REQUESTING)
    70 STATE_NAME(PROCESSING)
    73 /* MISSING: TR_Invoke.ind, N_Methods == MOM */
    77    e->tcl == 2 && pdu->type == Get,
    84        /* Prepare the MethodInvoke here, because we have all
    85         * the information nicely available. */
    87        if (octstr_len(pdu->u.Get.headers) > 0)
    88            headers = wsp_headers_unpack(pdu->u.Get.headers, 0);
    92        invoke = wap_event_create(S_MethodInvoke_Ind);
    93        invoke->u.S_MethodInvoke_Ind.server_transaction_id =
    95        method = GET_METHODS + pdu->u.Get.subtype;
    96        method_name = wsp_method_to_string(method);
    97        if (method_name == NULL)
    98            method_name = octstr_format("UNKNOWN%02X", method);
    99        invoke->u.S_MethodInvoke_Ind.method = method_name;
   100        invoke->u.S_MethodInvoke_Ind.request_uri =
   101            octstr_duplicate(pdu->u.Get.uri);
   102        invoke->u.S_MethodInvoke_Ind.request_headers = headers;
   103        invoke->u.S_MethodInvoke_Ind.request_body = NULL;
   104        invoke->u.S_MethodInvoke_Ind.session_headers =
   105            http_header_duplicate(sm->http_headers);
   106        invoke->u.S_MethodInvoke_Ind.addr_tuple =
   107            wap_addr_tuple_duplicate(sm->addr_tuple);
   108        invoke->u.S_MethodInvoke_Ind.client_SDU_size =
   110        invoke->u.S_MethodInvoke_Ind.session_id =
   113        msm->invoke = invoke;
   119    e->tcl == 2 && pdu->type == Post,
   126        /* Prepare the MethodInvoke here, because we have all
   127         * the information nicely available. */
   129        if (octstr_len(pdu->u.Post.headers) > 0)
   130            headers = wsp_headers_unpack(pdu->u.Post.headers, 1);
   134        invoke = wap_event_create(S_MethodInvoke_Ind);
   135        invoke->u.S_MethodInvoke_Ind.server_transaction_id =
   137        method = POST_METHODS + pdu->u.Get.subtype;
   138        method_name = wsp_method_to_string(method);
   139        if (method_name == NULL)
   140            method_name = octstr_format("UNKNOWN%02X", method);
   141        invoke->u.S_MethodInvoke_Ind.method = method_name;
   142        invoke->u.S_MethodInvoke_Ind.request_uri =
   143            octstr_duplicate(pdu->u.Post.uri);
   144        invoke->u.S_MethodInvoke_Ind.request_headers = headers;
   146        invoke->u.S_MethodInvoke_Ind.request_body = 
   147            octstr_duplicate(pdu->u.Post.data);
   149        invoke->u.S_MethodInvoke_Ind.session_headers =
   150            http_header_duplicate(sm->http_headers);
   151        invoke->u.S_MethodInvoke_Ind.addr_tuple =
   152            wap_addr_tuple_duplicate(sm->addr_tuple);
   153        invoke->u.S_MethodInvoke_Ind.client_SDU_size =
   155        invoke->u.S_MethodInvoke_Ind.session_id =
   158        msm->invoke = invoke;
   166        /* S-MethodInvoke.ind */
   167        dispatch_to_appl(msm->invoke);
   176        /* Decrement N_Methods */
   177        /* we don't keep track of N_Methods because it's unlimited */
   179        /* Tr-Abort.req(abort reason) the method */
   180        method_abort(msm, e->reason);
   186    e->abort_code == WSP_ABORT_DISCONNECT,
   190        /* Disconnect the session */
   191        wsp_event = wap_event_create(Disconnect_Event);
   192        wsp_event->u.Disconnect_Event.session_handle = msm->session_id;
   193        /* We put this on the queue instead of doing it right away,
   194         * because the session machine is currently our caller and
   195         * we don't want to recurse.  We put it in the front of
   196         * the queue because the state machine definitions expect
   197         * an event to be handled completely before the next is
   199        gwlist_insert(queue, 0, wsp_event);
   205    e->abort_code == WSP_ABORT_SUSPEND,
   209        /* Suspend the session */
   210        wsp_event = wap_event_create(Suspend_Event);
   211        wsp_event->u.Suspend_Event.session_handle = msm->session_id;
   212        /* See story for Disconnect, above */
   213        gwlist_insert(queue, 0, wsp_event);
   219    e->abort_code != WSP_ABORT_DISCONNECT
   220    && e->abort_code != WSP_ABORT_SUSPEND,
   222        /* Decrement N_Methods */
   223        /* we don't keep track of N_Methods because it's unlimited */
   233        /* Send TR-Invoke.res to WTP */
   234        wtp_event = wap_event_create(TR_Invoke_Res);
   235        wtp_event->u.TR_Invoke_Res.handle = msm->transaction_id;
   236        dispatch_to_wtp_resp(wtp_event);
   240 /* MISSING: REQUESTING, S-MethodAbort.req */
   246        /* Decrement N_Methods */
   247        /* we don't keep track of N_Methods because it's unlimited */
   249        /* TR-Abort.req(abort reason) the method */
   250        method_abort(msm, e->reason);
   252        /* S-MethodAbort.ind(abort reason) */
   253        indicate_method_abort(msm, e->reason);
   259    e->abort_code == WSP_ABORT_DISCONNECT,
   263        /* Disconnect the session */
   264        wsp_event = wap_event_create(Disconnect_Event);
   265        wsp_event->u.Disconnect_Event.session_handle = msm->session_id;
   266        gwlist_insert(queue, 0, wsp_event);
   272    e->abort_code == WSP_ABORT_SUSPEND,
   276        /* Suspend the session */
   277        wsp_event = wap_event_create(Suspend_Event);
   278        wsp_event->u.Suspend_Event.session_handle = msm->session_id;
   279        gwlist_insert(queue, 0, wsp_event);
   285    e->abort_code != WSP_ABORT_DISCONNECT
   286    && e->abort_code != WSP_ABORT_SUSPEND,
   288        /* Decrement N_Methods */
   289        /* we don't keep track of N_Methods because it's unlimited */
   291        /* S-MethodAbort.ind(abort reason) */
   292        indicate_method_abort(msm, e->abort_code);
   304        new_pdu = wsp_pdu_create(Reply);
   305        new_pdu->u.Reply.status = 
   306            wsp_convert_http_status_to_wsp_status(e->status);
   307        new_pdu->u.Reply.headers = 
   308            wsp_headers_pack(e->response_headers, 1, sm->encoding_version);
   309        new_pdu->u.Reply.data = octstr_duplicate(e->response_body);
   311        /* Send TR-Result.req to WTP */
   312        wtp_event = wap_event_create(TR_Result_Req);
   313        wtp_event->u.TR_Result_Req.user_data = wsp_pdu_pack(new_pdu);
   314        wtp_event->u.TR_Result_Req.handle = msm->transaction_id;
   315        dispatch_to_wtp_resp(wtp_event);
   316        wsp_pdu_destroy(new_pdu);
   320 /* MISSING: PROCESSING, S-MethodAbort.req */
   326        /* Decrement N_Methods */
   327        /* we don't keep track of N_Methods because it's unlimited */
   329        /* TR-Abort.req(abort reason) the method */
   330        method_abort(msm, e->reason);
   332        /* S-MethodAbort.ind(abort reason) */
   333        indicate_method_abort(msm, e->reason);
   339    e->abort_code == WSP_ABORT_DISCONNECT,
   343        /* Disconnect the session */
   344        wsp_event = wap_event_create(Disconnect_Event);
   345        wsp_event->u.Disconnect_Event.session_handle = msm->session_id;
   346        gwlist_insert(queue, 0, wsp_event);
   352    e->abort_code == WSP_ABORT_SUSPEND,
   356        /* Suspend the session */
   357        wsp_event = wap_event_create(Suspend_Event);
   358        wsp_event->u.Suspend_Event.session_handle = msm->session_id;
   359        gwlist_insert(queue, 0, wsp_event);
   365    e->abort_code != WSP_ABORT_DISCONNECT
   366    && e->abort_code != WSP_ABORT_SUSPEND,
   368        /* Decrement N_Methods */
   369        /* we don't keep track of N_Methods because it's unlimited */
   371        /* S-MethodAbort.ind(abort reason) */
   372        indicate_method_abort(msm, e->abort_code);
   376 /* MISSING: REPLYING, S-MethodAbort.req */
   382        /* Decrement N_Methods */
   383        /* we don't keep track of N_Methods because it's unlimited */
   385        /* TR-Abort.req(abort reason) the method */
   386        method_abort(msm, e->reason);
   388        /* S-MethodAbort.ind(abort reason) */
   389        indicate_method_abort(msm, e->reason);
   399        /* Decrement N_Methods */
   400        /* we don't keep track of N_Methods because it's unlimited */
   402        /* S-MethodResult.cnf */
   403        /* we don't do acknowledgement headers */
   404        new_event = wap_event_create(S_MethodResult_Cnf);
   405        new_event->u.S_MethodResult_Cnf.server_transaction_id =
   407        new_event->u.S_MethodResult_Cnf.session_id = msm->session_id;
   408        dispatch_to_appl(new_event);
   414    e->abort_code == WSP_ABORT_DISCONNECT,
   418        /* Disconnect the session */
   419        wsp_event = wap_event_create(Disconnect_Event);
   420        wsp_event->u.Disconnect_Event.session_handle = msm->session_id;
   421        gwlist_insert(queue, 0, wsp_event);
   427    e->abort_code == WSP_ABORT_SUSPEND,
   431        /* Suspend the session */
   432        wsp_event = wap_event_create(Suspend_Event);
   433        wsp_event->u.Suspend_Event.session_handle = msm->session_id;
   434        gwlist_insert(queue, 0, wsp_event);
   440    e->abort_code != WSP_ABORT_DISCONNECT
   441    && e->abort_code != WSP_ABORT_SUSPEND,
   443        /* Decrement N_Methods */
   444        /* we don't keep track of N_Methods because it's unlimited */
   446        /* S-MethodAbort.ind(abort reason) */
   447        indicate_method_abort(msm, e->abort_code);