コード例 #1
0
ファイル: wapproxy.c プロジェクト: gburiticato/kannel
static void wtp_event_dump(Msg *msg)
{
    WAPEvent *dgram;
    List *events;
    long i, n;

    dgram = wdp_msg2event(msg);
    if (dgram == NULL)
        error(0, "dgram is null");

    /*
    pdu = wtp_pdu_unpack(dgram->u.T_DUnitdata_Ind.user_data);
    if (pdu == NULL) {
        error(0, "WTP PDU unpacking failed, WAP event is:");
        wap_event_dump(dgram);
    } else {
        wtp_pdu_dump(pdu, 0);
        wtp_pdu_destroy(pdu);
    }
    */

    events = wtp_unpack_wdp_datagram(dgram);
    n = gwlist_len(events);
    debug("wap.proxy",0,"datagram contains %ld events", n);

    i = 1;
    while (gwlist_len(events) > 0) {
        WAPEvent *event;

	    event = gwlist_extract_first(events);
        
        info(0, "WTP: %ld/%ld event %s.", i, n, wap_event_name(event->type));

        if (wtp_event_is_for_responder(event))
            /* wtp_resp_dispatch_event(event); */
            debug("",0,"datagram is for WTP responder");
        else
            /* wtp_initiator_dispatch_event(event); */
            debug("",0,"datagram is for WTP initiator");
 
        wap_event_dump(event);
        /*
        switch (event->type) {
            RcvInvoke:
                debug("",0,"XXX invoke");
                break;
            RcvResult:
                debug("",0,"XXX result");
                break;
            default:
                error(0,"unkown WTP event type while unpacking");
                break;
        }
        */
        i++;
    }   		

    wap_event_destroy(dgram);
    gwlist_destroy(events, NULL);
}
コード例 #2
0
ファイル: wsp_session.c プロジェクト: gburiticato/kannel
static void handle_session_event(WSPMachine *sm, WAPEvent *current_event, 
WSP_PDU *pdu) {
	debug("wap.wsp", 0, "WSP: machine %p, state %s, event %s",
		(void *) sm,
		state_name(sm->state), 
		wap_event_name(current_event->type));

	#define STATE_NAME(name)
	#define ROW(state_name, event, condition, action, next_state) \
		{ \
			struct event *e; \
			e = &current_event->u.event; \
			if (sm->state == state_name && \
			   current_event->type == event && \
			   (condition)) { \
				action \
				sm->state = next_state; \
				debug("wap.wsp", 0, "WSP %ld: New state %s", \
					sm->session_id, #next_state); \
				goto end; \
			} \
		}
	#include "wsp_server_session_states.def"
	
	cant_handle_event(sm, current_event);

end:
	wap_event_destroy(current_event);

	if (sm->state == NULL_SESSION)
		machine_destroy(sm);
}
コード例 #3
0
/*
 * Feed an event to a WSP push client state machine. Do not report errors to
 * the caller.
 */
static void push_client_event_handle(WSPPushClientMachine *cpm, 
                                     WAPEvent *e)
{
    WAPEvent *wtp_event;
    WSP_PDU *pdu = NULL;

    wap_event_assert(e);
    gw_assert(cpm);
    
    if (e->type == TR_Invoke_Ind) {
        pdu = wsp_pdu_unpack(e->u.TR_Invoke_Ind.user_data);
/*
 * Class 1 tests here
 * Case 4, no session matching address quadruplet, handled by the session mach-
 * ine.
 * Tests from table WSP, page 45. Case 5, a PDU state tables cannot handle.
 */
        if (pdu == NULL || pdu->type != ConfirmedPush) {
	    wap_event_destroy(e);
            wtp_event = send_abort_to_responder(cpm, PROTOERR);
            wtp_resp_dispatch_event(wtp_event);
            return;
        }
    }

    debug("wap.wsp", 0, "WSP_PUSH: WSPPushClientMachine %ld, state %s,"
          " event %s", 
          cpm->client_push_id,
          name_push_client_state(cpm->state),
          wap_event_name(e->type));
    #define PUSH_CLIENT_STATE_NAME(state)
    #define ROW(push_state, event_type, condition, action, next_state) \
         if (cpm->state == push_state && \
             e->type == event_type && \
             (condition)) { \
             action \
             cpm->state = next_state; \
             debug("wap.wsp", 0, "WSP_PUSH %ld: new state %s", \
                   cpm->client_push_id, #next_state); \
         } else
    #include "wsp_push_client_states.def"
         {
             error(0, "WSP_PUSH: handle_event: unhandled event!");
             debug("wap.wsp", 0, "Unhandled event was:");
             wap_event_dump(e);
             wap_event_destroy(e);
             return;
         }

    wsp_pdu_destroy(pdu);
    wap_event_destroy(e);
    
    if (cpm->state == PUSH_CLIENT_NULL_STATE)
        push_client_machine_destroy(cpm);
}
コード例 #4
0
ファイル: timers.c プロジェクト: LeeVidor/kannel-mongodb
/*
 * This timer has elapsed.  Do the housekeeping.  We have its set locked.
 */
static void elapse_timer(Timer *timer)
{
    gw_assert(timer != NULL);
    gw_assert(timers != NULL);
    /* This must be true because abort_elapsed is always called
     * before a timer is activated. */
    gw_assert(timer->elapsed_event == NULL);

    debug("timers", 0, "%s elapsed.", wap_event_name(timer->event->type));

    timer->elapsed_event = wap_event_duplicate(timer->event);
    gwlist_produce(timer->output, timer->elapsed_event);
    timer->elapses = -1;
}
コード例 #5
0
ファイル: timers.c プロジェクト: LeeVidor/kannel-mongodb
/*
 * Go back and remove this timer's elapse event from the output list,
 * to pretend that it didn't elapse after all.  This is necessary
 * to deal with some races between the timer thread and the caller's
 * start/stop actions.
 */
static void abort_elapsed(Timer *timer)
{
    long count;

    if (timer->elapsed_event == NULL)
        return;

    count = gwlist_delete_equal(timer->output, timer->elapsed_event);
    if (count > 0) {
        debug("timers", 0, "Aborting %s timer.",
              wap_event_name(timer->elapsed_event->type));
        wap_event_destroy(timer->elapsed_event);
    }
    timer->elapsed_event = NULL;
}
コード例 #6
0
ファイル: wtls.c プロジェクト: Jayriq/kannel-gateway
/*
 * Feed an event to a WTP responder state machine. Handle all errors yourself,
 * do not report them to the caller. Note: Do not put {}s of the else block 
 * inside the macro definition. 
 */
static void wtls_event_handle(WTLSMachine * wtls_machine, WAPEvent * event)
{
     debug("wap.wtls", 0, "WTLS: wtls_machine %ld, state %s, event %s.", 
         wtls_machine->mid, stateName(wtls_machine->state),
	   wap_event_name(event->type));

	/* for T_Unitdata_Ind PDUs */
   if (event->type == T_Unitdata_Ind) {
		/* if encryption: decrypt all pdus in the list */
      if (wtls_machine->encrypted)
         wtls_decrypt_pdu_list(wtls_machine,
                     event->u.T_Unitdata_Ind.pdu_list);
		/* add all handshake data to wtls_machine->handshake_data */
		//add_all_handshake_data(wtls_machine, event->u.T_Unitdata_Ind.pdu_list);
	}
#define STATE_NAME(state)
#define ROW(wtls_state, event_type, condition, action, next_state) \
	     if (wtls_machine->state == wtls_state && \
		event->type == event_type && \
		(condition)) { \
		action \
		wtls_machine->state = next_state; \
		debug("wap.wtls", 0, "WTLS %ld: New state %s", wtls_machine->mid, #next_state); \
	     } else 
#include "wtls_state-decl.h"
	     {
		error(0, "WTLS: handle_event: unhandled event!");
      debug("wap.wtls", 0,
            "WTLS: handle_event: Unhandled event was:");
		wap_event_destroy(event);
		return;
	     }

   if (event)
	wap_event_destroy(event);  

   if (wtls_machine->state == NULL_STATE) {
     	wtls_machine_destroy(wtls_machine);
      wtls_machine = NULL;
   }
}
コード例 #7
0
ファイル: wsp_session.c プロジェクト: gburiticato/kannel
/* This function does NOT consume its event; it leaves that task up
 * to the parent session */
static void handle_method_event(WSPMachine *sm, WSPMethodMachine *msm, 
WAPEvent *current_event, WSP_PDU *pdu) {

	if (msm == NULL) {
		warning(0, "No method machine for event.");
		wap_event_dump(current_event);
		return;
	}
		
	debug("wap.wsp", 0, "WSP: method %ld, state %s, event %s",
		msm->transaction_id, state_name(msm->state), 
		wap_event_name(current_event->type));

	gw_assert(sm->session_id == msm->session_id);

	#define STATE_NAME(name)
	#define ROW(state_name, event, condition, action, next_state) \
		{ \
			struct event *e; \
			e = &current_event->u.event; \
			if (msm->state == state_name && \
			   current_event->type == event && \
			   (condition)) { \
				action \
				msm->state = next_state; \
				debug("wap.wsp", 0, "WSP %ld/%ld: New method state %s", \
					msm->session_id, msm->transaction_id, #next_state); \
				goto end; \
			} \
		}
	#include "wsp_server_method_states.def"
	
	cant_handle_event(sm, current_event);

end:
	if (msm->state == NULL_METHOD) {
		method_machine_destroy(msm);
		gwlist_delete_equal(sm->methodmachines, msm);
	}
}
コード例 #8
0
ファイル: wtp_init.c プロジェクト: markjeee/kannel
/*
 * Feed an event to a WTP initiator state machine. Handle all errors by do not
 * report them to the caller. WSP indication or conformation is handled by an
 * included state table. Note: Do not put {}s of the else block inside the 
 * macro definition . 
 */
static void handle_init_event(WTPInitMachine *init_machine, WAPEvent *event)
{
     WAPEvent *wsp_event = NULL;

     debug("wap.wtp", 0, "WTP_INIT: initiator machine %ld, state %s,"
           " event %s.", 
	   init_machine->mid, 
	   name_init_state(init_machine->state), 
	   wap_event_name(event->type));
       
     #define INIT_STATE_NAME(state)
     #define ROW(init_state, event_type, condition, action, next_state) \
	 if (init_machine->state == init_state && \
	     event->type == event_type && \
	     (condition)) { \
	     action \
	     init_machine->state = next_state; \
	     debug("wap.wtp", 0, "WTP_INIT %ld: New state %s", \
                   init_machine->mid, #next_state); \
	 } else 
      #include "wtp_init_states.def"
	 {
	     error(1, "WTP_INIT: handle_init_event: unhandled event!");
	     debug("wap.wtp.init", 0, "WTP_INIT: handle_init_event:"
                   "Unhandled event was:");
	     wap_event_dump(event);
             wap_event_destroy(event);
             return;
	 }

      if (event != NULL) {
	  wap_event_destroy(event);  
      }

      if (init_machine->state == INITIATOR_NULL_STATE)
     	  init_machine_destroy(init_machine);      
}
コード例 #9
0
ファイル: wsp_session.c プロジェクト: gburiticato/kannel
static void handle_push_event(WSPMachine *sm, WSPPushMachine *pm, 
                              WAPEvent *current_event)
{
        if (pm == NULL) {
		warning(0, "No push machine for event.");
		wap_event_dump(current_event);
		return;
	}

        debug("wap.wsp", 0, "WSP(tid/pid): push %ld/%ld, state %s, event %s",
		pm->transaction_id, pm->server_push_id, state_name(pm->state), 
		wap_event_name(current_event->type));
	gw_assert(sm->session_id == pm->session_id);

        #define STATE_NAME(name)
	#define ROW(state_name, event, condition, action, next_state) \
		{ \
		    if (pm->state == state_name && \
			current_event->type == event && \
			(condition)) { \
			     action \
			     pm->state = next_state; \
			     debug("wap.wsp", 0, "WSP %ld/%ld: New push state %s", \
			           pm->session_id, pm->transaction_id, #next_state); \
				goto end; \
			} \
		}
	#include "wsp_server_push_states.def"

        cant_handle_event(sm, current_event);
end:
        if (pm->state == SERVER_PUSH_NULL_STATE) {
		push_machine_destroy(pm);
		gwlist_delete_equal(sm->pushmachines, pm);
	}
}
コード例 #10
0
ファイル: wsp_session.c プロジェクト: gburiticato/kannel
static WSPMachine *find_session_machine(WAPEvent *event, WSP_PDU *pdu) {
	WSPMachine *sm;
	long session_id;
	WAPAddrTuple *tuple;
	
	tuple = NULL;
	session_id = -1;
	
	switch (event->type) {
	case TR_Invoke_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Ind.addr_tuple);
		break;

        case TR_Invoke_Cnf:
                tuple = wap_addr_tuple_duplicate(
				event->u.TR_Invoke_Cnf.addr_tuple);
	        break;

	case TR_Result_Cnf:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Result_Cnf.addr_tuple);
		break;

	case TR_Abort_Ind:
		tuple = wap_addr_tuple_duplicate(
				event->u.TR_Abort_Ind.addr_tuple);
		break;

	case S_Connect_Res:
		session_id = event->u.S_Connect_Res.session_id;
		break;

	case S_Resume_Res:
		session_id = event->u.S_Resume_Res.session_id;
		break;

	case Disconnect_Event:
		session_id = event->u.Disconnect_Event.session_handle;
		break;

	case Suspend_Event:
		session_id = event->u.Suspend_Event.session_handle;
		break;

	case S_MethodInvoke_Res:
		session_id = event->u.S_MethodInvoke_Res.session_id;
		break;

	case S_MethodResult_Req:
		session_id = event->u.S_MethodResult_Req.session_id;
		break;

	case S_ConfirmedPush_Req:
                session_id = event->u.S_ConfirmedPush_Req.session_id;
	        break;

        case S_Push_Req:
                session_id = event->u.S_Push_Req.session_id;
	        break;

	default:
		error(0, "WSP: Cannot find machine for %s event",
			wap_event_name(event->type));
	}
	
	gw_assert(tuple != NULL || session_id != -1);

	/* Pre-state-machine tests, according to 7.1.5.  After the tests,
	 * caller will pass the event to sm if sm is not NULL. */
	sm = NULL;
	/* First test is for MRUEXCEEDED, and we don't have a MRU */

	/* Second test is for class 2 TR-Invoke.ind with Connect PDU */
	if (event->type == TR_Invoke_Ind &&
	    event->u.TR_Invoke_Ind.tcl == 2 &&
	    pdu->type == Connect) {
			/* Create a new session, even if there is already
			 * a session open for this address.  The new session
			 * will take care of killing the old ones. */
			sm = machine_create();
			gw_assert(tuple != NULL);
			sm->addr_tuple = wap_addr_tuple_duplicate(tuple);
			sm->connect_handle = event->u.TR_Invoke_Ind.handle;
	/* Third test is for class 2 TR-Invoke.ind with Resume PDU */
	} else if (event->type == TR_Invoke_Ind &&
		   event->u.TR_Invoke_Ind.tcl == 2 &&
	  	   pdu->type == Resume) {
		/* Pass to session identified by session id, not
		 * the address tuple. */
		session_id = pdu->u.Resume.sessionid;
		sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		if (sm == NULL) {
			/* No session; TR-Abort.req(DISCONNECT) */
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Fourth test is for a class 1 or 2 TR-Invoke.Ind with no
	 * session for that address tuple.  We also handle class 0
	 * TR-Invoke.ind here by ignoring them; this seems to be
	 * an omission in the spec table. */
	} else if (event->type == TR_Invoke_Ind) {
		sm = gwlist_search(session_machines, tuple,
				 transaction_belongs_to_session);
		if (sm == NULL && (event->u.TR_Invoke_Ind.tcl == 1 ||
				event->u.TR_Invoke_Ind.tcl == 2)) {
			send_abort(WSP_ABORT_DISCONNECT,
				event->u.TR_Invoke_Ind.handle);
		}
	/* Other tests are for events not handled by the state tables;
	 * do those later, after we've tried to handle them. */
	} else {
		if (session_id != -1) {
			sm = gwlist_search(session_machines, &session_id,
				find_by_session_id);
		} else {
			sm = gwlist_search(session_machines, tuple,
				transaction_belongs_to_session);
		}
		/* The table doesn't really say what we should do with
		 * non-Invoke events for which there is no session.  But
		 * such a situation means there is an error _somewhere_
		 * in the gateway. */
		if (sm == NULL) {
			error(0, "WSP: Cannot find session machine for event.");
			wap_event_dump(event);
		}
	}

	wap_addr_tuple_destroy(tuple);
	return sm;
}
コード例 #11
0
/*
 * Checks client push machines list for a specific machine. Creates it, if the
 * event is TR-Invoke.ind.
 * Client push machine is identified (when searching) by transcation identifi-
 * er. 
 * Note that only WTP responder send its class 1 messages to client push state
 * machine. So, it is no need to specify WTP machine type. 
 */
static WSPPushClientMachine *push_client_machine_find_or_create(WAPEvent *e)
{
    WSPPushClientMachine *cpm;
    long transid;

    cpm = NULL;
    transid = -1;
   
    switch (e->type) {
    case TR_Invoke_Ind:
         transid = e->u.TR_Invoke_Ind.handle;
    break;

    case S_ConfirmedPush_Res:
         transid = e->u.S_ConfirmedPush_Res.client_push_id;
    break;

    case S_PushAbort_Req:
         transid = e->u.S_PushAbort_Req.push_id;
    break;

    case Abort_Event:
    break;

    case TR_Abort_Ind:
         transid = e->u.TR_Abort_Ind.handle;
    break;

    default:
        debug("wap.wsp", 0, "WSP PUSH: push_client_find_or_create: unhandled"
	      " event");
        wap_event_dump(e);
        wap_event_destroy(e);
        return NULL;
    }

    gw_assert(transid != -1);

    cpm = push_client_machine_find_using_transid(transid);
    
    if (cpm == NULL) {
        switch (e->type) {
        case TR_Invoke_Ind:
	    cpm = push_client_machine_create(transid);
	break;

        case S_ConfirmedPush_Res:
        case S_PushAbort_Req:
	    error(0, "WSP_PUSH_CLIENT: POT primitive to a nonexisting"
                  "  push client machine");
	break;

        case Abort_Event:
	    error(0, "WSP_PUSH_CLIENT: internal abort to a nonexisting"
                  " push client machine");
	break;

        case TR_Abort_Ind:
	    error(0, "WSP_PUSH_CLIENT: WTP abort to a nonexisting push client"
                  " machine");
	break;

	default:
	    error(0, "WSP_PUSH_CLIENT: Cannot handle event type %s",
		wap_event_name(e->type));
	break;
        }
    }

    return cpm;
}