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  * wtp_init_state.h: Macro calls for implementing wtp initiator state tables
    59  * See documentation for guidance how to use and update these.
    61  * Only classes 0 and 1 are implemented. State NULL is called INITIATOR_NULL_
    62  * STATE. 1 in the action field means that action is unconditional.
    64  * Class 0 service is here a stateless invoke message (used for disconnection
    65  * or unconfirmed push).
    67  * Basic class 1 transaction, without timers, is following:
    68  *               - initiator sends an invoke message to the responder
    69  *               - responder acknowledges it, with an pdu with tid verification
    70  *                 off (if it is on, we have a tid verification transaction, 
    73  * Retransmission until acknowledgement is implemented using timers and 
    74  * retransmission counters. When the initiator sends an invoke it starts a 
    75  * timer. When it expires, it resends the packet (either ack or invoke), until
    76  * counter reaches the maximum value. Then the transaction is aborted.
    78  * If user acknowledgement is on, timers have different values.
    80  * When the initiator aborts the transaction, it sends an abort pdu. When the
    81  * responder does it, the initiator wtp user is indicated.
    83  * Tid verification in the initiator means answering the question posed by the
    84  * responder: "Have you an outstanding transaction having this tid". If we do
    85  * not have it, we have already, before feeding the event into the state 
    86  * machine, sent an abort with reason INVALIDTID. So here we answer to  an
    87  * ack pdu with tidve-flag set with an ack pdu with tidok-flag set. See WTP
    88  * 5.6, table 2; WTP 8.9; WTP 9.3.4.1.
    90  * By Aarno Syvänen for Wapit Ltd. 
    93 INIT_STATE_NAME(INITIATOR_NULL_STATE)
    94 INIT_STATE_NAME(INITIATOR_RESULT_WAIT)
    97  * We do not use transaction class 2 here: Server is initiator only when it is 
    98  * pushing (class 1 or class 0) or disconnecting (class 0). First and second 
    99  * rows are similar, with exception of timer period.
   101 ROW(INITIATOR_NULL_STATE,
   103     event->u.TR_Invoke_Req.tcl == 1,
   107  * A special counter is used for storing value used (1) for tidnew flag when
   108  * restarting (See WTP 8.8.3.2)
   110      init_machine->tidnew = tidnew;
   112      wap_event_destroy(init_machine->invoke);
   113      init_machine->rid = 0;
   114      init_machine->rcr = 0;
   116      invoke = wtp_pack_invoke(init_machine, event);
   117      init_machine->invoke = wap_event_duplicate(invoke);
   118      dispatch_to_wdp(invoke);
   119      init_machine->rid = 1;
   121  * Turn the tidnew-flag off if it was on. (This can happen when tid was 
   122  * wrapped or when we are restarting, see WTP 8.8.3.2) 
   124      if (init_machine->tidnew) {
   125          init_machine->tidnew = 0;
   128      init_machine->u_ack = event->u.TR_Invoke_Req.up_flag;
   129      init_machine->rcr = 0;
   130      start_initiator_timer_R(init_machine);
   132     INITIATOR_RESULT_WAIT)
   135  * No need to turn tidnew flag when sending class 0 message; tid validation is
   136  * not invoked in this case.
   138 ROW(INITIATOR_NULL_STATE,
   140     event->u.TR_Invoke_Req.tcl == 0,
   144      wap_event_destroy(init_machine->invoke);
   145      invoke = wtp_pack_invoke(init_machine, event);
   146      init_machine->invoke = wap_event_duplicate(invoke);
   147      dispatch_to_wdp(invoke);
   149     INITIATOR_NULL_STATE)
   151 ROW(INITIATOR_RESULT_WAIT,
   155      send_abort(init_machine, USER, event->u.TR_Abort_Req.abort_reason);
   157     INITIATOR_NULL_STATE)
   160  * Neither we check transaction class here: this can only be acknowledgement of
   161  * class 1 transaction.
   163 ROW(INITIATOR_RESULT_WAIT,
   165     event->u.RcvAck.tid_ok == 0,
   167      stop_initiator_timer(init_machine->timer);
   169      wsp_event = create_tr_invoke_cnf(init_machine);
   170      dispatch_to_wsp(wsp_event);     
   172     INITIATOR_NULL_STATE)
   175  * This is a positive answer to a tid verification (negative one being 
   176  * already sent by init_machine_find_or_create).
   178 ROW(INITIATOR_RESULT_WAIT,
   180     event->u.RcvAck.tid_ok == 1 && init_machine->rcr < MAX_RCR,
   182      send_ack(init_machine, TID_VERIFICATION, init_machine->rid);
   183      init_machine->tidok_sent = 1;
   187      start_initiator_timer_R(init_machine);
   189     INITIATOR_RESULT_WAIT)
   192  * RCR must not be greater than RCR_MAX. One of corrections from MOT_WTP_CR_01.
   194    ROW(INITIATOR_RESULT_WAIT,
   196        event->u.RcvAck.tid_ok,
   198        INITIATOR_RESULT_WAIT)
   200 ROW(INITIATOR_RESULT_WAIT,
   204      wsp_event = create_tr_abort_ind(init_machine, 
   205                  event->u.RcvAbort.abort_reason);
   206      dispatch_to_wsp(wsp_event);
   208     INITIATOR_NULL_STATE)
   210 ROW(INITIATOR_RESULT_WAIT,
   214      send_abort(init_machine, USER, PROTOERR);
   216      wsp_event = create_tr_abort_ind(init_machine, PROTOERR);
   217      dispatch_to_wsp(wsp_event);
   219     INITIATOR_NULL_STATE)
   221 ROW(INITIATOR_RESULT_WAIT,
   223     init_machine->rcr < MAX_RCR && !init_machine->tidok_sent,
   229      start_initiator_timer_R(init_machine);
   231      resend = wap_event_duplicate(init_machine->invoke);
   232      wtp_pack_set_rid(resend, init_machine->rid);
   233      dispatch_to_wdp(resend);
   235     INITIATOR_RESULT_WAIT)
   237 ROW(INITIATOR_RESULT_WAIT,
   239     init_machine->rcr < MAX_RCR && init_machine->tidok_sent,
   243      start_initiator_timer_R(init_machine);
   245      send_ack(init_machine, TID_VERIFICATION, init_machine->tidok_sent);
   247     INITIATOR_RESULT_WAIT)
   249 ROW(INITIATOR_RESULT_WAIT,
   251     init_machine->rcr == MAX_RCR, 
   253      wsp_event = create_tr_abort_ind(init_machine, NORESPONSE);
   254      dispatch_to_wsp(wsp_event);
   256     INITIATOR_NULL_STATE)
   259 #undef INIT_STATE_NAME