📄 wtp_init.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * wtp_init.c - WTP initiator implementation * * By Aarno Syv鋘en for Wapit Ltd */#include "gwlib/gwlib.h"#include "wtp_init.h"#include "wtp_pack.h"#include "wap.h"/***************************************************************************** * Internal data structures. * * List of initiator WTP machines */static List *init_machines = NULL;/* * Counter for initiator WTP machine id numbers, to make sure they are unique. */static Counter *init_machine_id_counter = NULL;/* * When we restart an iniator, we must set tidnew flag to avoid excessive tid * validations (WTP 8.8.3.2). Only an iniator uses this flag. */static int tidnew = 1;/* * Queue of events to be handled by WTP initiator. */static List *queue = NULL;/* * Give the status of the wtp initiator: * * limbo * not running at all * running * operating normally * terminating * waiting for operations to terminate, returning to limbo */static enum { limbo, running, terminating } initiator_run_status = limbo;static wap_dispatch_func_t *dispatch_to_wdp;static wap_dispatch_func_t *dispatch_to_wsp;/* * This is a timer 'tick'. All timer values multiplies of this value. */static long init_timer_freq = -1;/*************************************************************************** * * Prototypes for internal functions: */static void main_thread(void *arg); /* * Create and destroy an uniniatilised wtp initiator state machine */static WTPInitMachine *init_machine_create(WAPAddrTuple *tuple, unsigned short tid, int tidnew);static void init_machine_destroy(void *sm);static void handle_init_event(WTPInitMachine *machine, WAPEvent *event);/* * Checks whether wtp initiator machines data structure includes a specific * machine. * The machine in question is identified with with source and destination * address and port and tid. */static WTPInitMachine *init_machine_find_or_create(WAPEvent *event);/* * Creates TR-Abort.ind event. */static WAPEvent *create_tr_abort_ind(WTPInitMachine *sm, long abort_reason);/* * Creates TR-Invoke.cnf event */static WAPEvent *create_tr_invoke_cnf(WTPInitMachine *machine);static int tid_wrapped(unsigned short tid);/* * Create a datagram with an Abort PDU and send it to the WDP layer. */static void send_abort(WTPInitMachine *machine, long type, long reason);/* * Create a datagram with an Ack PDU and send it to the WDP layer. */static void send_ack(WTPInitMachine *machine, long ack_type, int rid_flag);/* * We use RcvTID consistently as a internal tid representation. So newly * created tids are converted. SendTID = RcvTID ^ 0x8000 (WTP 10.4.3) and for * an initiator, GenTID = SendTID (WTP 10.5). */static unsigned short rcv_tid(unsigned short tid);static void start_initiator_timer_R(WTPInitMachine *machine); static void stop_initiator_timer(Timer *timer);/************************************************************************** * * EXTERNAL FUNCTIONS */void wtp_initiator_init(wap_dispatch_func_t *datagram_dispatch, wap_dispatch_func_t *session_dispatch, long timer_freq) { init_machines = list_create(); init_machine_id_counter = counter_create(); queue = list_create(); list_add_producer(queue); dispatch_to_wdp = datagram_dispatch; dispatch_to_wsp = session_dispatch; timers_init(); init_timer_freq = timer_freq; gw_assert(initiator_run_status == limbo); initiator_run_status = running; gwthread_create(main_thread, NULL);}void wtp_initiator_shutdown(void) { gw_assert(initiator_run_status == running); initiator_run_status = terminating; list_remove_producer(queue); gwthread_join_every(main_thread); debug("wap.wtp", 0, "wtp_initiator_shutdown: %ld init_machines left", list_len(init_machines)); list_destroy(init_machines, init_machine_destroy); list_destroy(queue, wap_event_destroy_item); counter_destroy(init_machine_id_counter); timers_shutdown();}void wtp_initiator_dispatch_event(WAPEvent *event) { list_produce(queue, event);}/************************************************************************** * * INTERNAL FUNCTIONS: */static void main_thread(void *arg) { WTPInitMachine *sm; WAPEvent *e; while (initiator_run_status == running && (e = list_consume(queue)) != NULL) { sm = init_machine_find_or_create(e); if (sm == NULL) wap_event_destroy(e); else handle_init_event(sm, e); }}static WTPInitMachine *init_machine_create(WAPAddrTuple *tuple, unsigned short tid, int tidnew){ WTPInitMachine *init_machine; init_machine = gw_malloc(sizeof(WTPInitMachine)); #define ENUM(name) init_machine->name = INITIATOR_NULL_STATE; #define INTEGER(name) init_machine->name = 0; #define EVENT(name) init_machine->name = NULL; #define TIMER(name) init_machine->name = gwtimer_create(queue); #define ADDRTUPLE(name) init_machine->name = NULL; #define MACHINE(field) field #include "wtp_init_machine.def" list_append(init_machines, init_machine); init_machine->mid = counter_increase(init_machine_id_counter); init_machine->addr_tuple = wap_addr_tuple_duplicate(tuple); init_machine->tid = tid; init_machine->tidnew = tidnew; debug("wap.wtp", 0, "WTP: Created WTPInitMachine %p (%ld)", (void *) init_machine, init_machine->mid); return init_machine;}/* * Destroys a WTPInitMachine. Assumes it is safe to do so. Assumes it has * already been deleted from the machines list. */static void init_machine_destroy(void *p){ WTPInitMachine *init_machine; init_machine = p; debug("wap.wtp", 0, "WTP: Destroying WTPInitMachine %p (%ld)", (void *) init_machine, init_machine->mid); list_delete_equal(init_machines, init_machine); #define ENUM(name) init_machine->name = INITIATOR_NULL_STATE; #define INTEGER(name) init_machine->name = 0; #define EVENT(name) wap_event_destroy(init_machine->name); #define TIMER(name) gwtimer_destroy(init_machine->name); #define ADDRTUPLE(name) wap_addr_tuple_destroy(init_machine->name); #define MACHINE(field) field #include "wtp_init_machine.def" gw_free(init_machine);}/* * Give the name of an initiator state in a readable form. */static unsigned char *name_init_state(int s){ switch (s){ #define INIT_STATE_NAME(state) case state: return #state; #define ROW(state, event, condition, action, new_state) #include "wtp_init_states.def" default: return "unknown state"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -