Example #1
0
/******************************************************************************
 *
 * EXTERNAL FUNCTIONS:
 *
 * Handles a possible concatenated message. Creates a list of wap events.
 */
List *wtp_unpack_wdp_datagram(WAPEvent *datagram)
{
     List *events = NULL;
     WAPEvent *event = NULL;
     WAPEvent *subdgram = NULL;
     Octstr *data = NULL;
     long pdu_len;

     gw_assert(datagram->type == T_DUnitdata_Ind);

     events = gwlist_create();
        
     if (concatenated_message(datagram->u.T_DUnitdata_Ind.user_data)) {
        data = octstr_duplicate(datagram->u.T_DUnitdata_Ind.user_data);
        octstr_delete(data, 0, 1);

        while (octstr_len(data) != 0) {

            if (octstr_get_bits(data, 0, 1) == 0) {
                pdu_len = octstr_get_char(data, 0);
                octstr_delete(data, 0, 1);
            } else {
                pdu_len = octstr_get_bits(data, 1, 15);
                octstr_delete(data, 0, 2);
            }
      
            subdgram = wap_event_duplicate(datagram);
            octstr_destroy(subdgram->u.T_DUnitdata_Ind.user_data);
            subdgram->u.T_DUnitdata_Ind.user_data = octstr_copy(data, 0, pdu_len);
            wap_event_assert(subdgram);
            if ((event = unpack_wdp_datagram_real(subdgram)) != NULL) {
                wap_event_assert(event);
                gwlist_append(events, event);
            }
            octstr_delete(data, 0, pdu_len);
            wap_event_destroy(subdgram);
        }

        octstr_destroy(data);

    } else if ((event = unpack_wdp_datagram_real(datagram)) != NULL) { 
        wap_event_assert(event);
        gwlist_append(events, event);
    } else {
        warning(0, "WTP: Dropping unhandled datagram data:");
        octstr_dump(datagram->u.T_DUnitdata_Ind.user_data, 0, GW_WARNING);
    }

    return events;
}
Example #2
0
static void main_thread(void *arg) {
	WAPEvent *e;
	WSPMachine *sm;
	WSP_PDU *pdu;
	
	while (run_status == running && (e = gwlist_consume(queue)) != NULL) {
		wap_event_assert(e);
		switch (e->type) {
		case TR_Invoke_Ind:
			pdu = wsp_pdu_unpack(e->u.TR_Invoke_Ind.user_data);
			if (pdu == NULL) {
				warning(0, "WSP: Broken PDU ignored.");
				wap_event_destroy(e);
				continue;
			}
			break;
	
		default:
			pdu = NULL;
			break;
		}
	
		sm = find_session_machine(e, pdu);
		if (sm == NULL) {
			wap_event_destroy(e);
		} else {
			handle_session_event(sm, e, pdu);
		}
		
		wsp_pdu_destroy(pdu);
	}
}
Example #3
0
void wap_event_destroy(WAPEvent *event) {
	if (event == NULL)
		return;

	wap_event_assert(event);

	switch (event->type) {
	#define WAPEVENT(name, prettyname, fields) \
		case name: \
			{ struct name *p = &event->u.name; fields; } \
			break;
	#define OCTSTR(name) octstr_destroy(p->name);
	#define OPTIONAL_OCTSTR(name) octstr_destroy(p->name);
	#define INTEGER(name) p->name = 0;
#ifdef HAVE_WTLS_OPENSSL
	#define WTLSPDUS(name) wtls_pldList_destroy(p->name);
#endif /* HAVE_WTLS_OPENSSL */
	#define HTTPHEADER(name) http_destroy_headers(p->name);
	#define ADDRTUPLE(name) wap_addr_tuple_destroy(p->name);
	#define CAPABILITIES(name) wsp_cap_destroy_list(p->name);
	#include "wap_events.def"
	default:
		panic(0, "Unknown WAPEvent type %d", (int) event->type);
	}
	gw_free(event);
}
Example #4
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);
}
Example #5
0
void wsp_session_dispatch_event(WAPEvent *event) {
	wap_event_assert(event);
	gwlist_produce(queue, event);
}
Example #6
0
WAPEvent *unpack_wdp_datagram_real(WAPEvent *datagram)
{
    WTP_PDU *pdu;
    WAPEvent *event;
    Octstr *data;

    gw_assert(datagram->type == T_DUnitdata_Ind);

    data = datagram->u.T_DUnitdata_Ind.user_data;

    if (truncated_datagram(datagram)) {
        warning(0, "WTP: got a truncated datagram, ignoring");
        return NULL;
    }

    pdu = wtp_pdu_unpack(data);

    /*
     * wtp_pdu_unpack returned NULL, we have send here a rcv error event,
     * but now we silently drop the packet. Because we can't figure out
     * in the pack_error() call if the TID value and hence the direction
     * inditation is really for initiator or responder. 
     */
    if (pdu == NULL) {
        error(0, "WTP: cannot unpack pdu, dropping packet.");
        return NULL;
    }   		

    event = NULL;

    switch (pdu->type) {

    case Invoke:
        event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        /* if an WTP initiator gets invoke, it would be an illegal pdu. */
        if (!wtp_event_is_for_responder(event)){
            debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was");
            wap_event_destroy(event);
            event = pack_error(datagram);
        }
        break;

    case Segmented_invoke:
        event = unpack_segmented_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        break;

    case Result:
        event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        /* if an WTP responder gets result, it would be an illegal pdu. */
        if (wtp_event_is_for_responder(event)){
            debug("wap.wtp", 0, "WTP: Result when responder. Message was");
            wap_event_destroy(event);
            event = pack_error(datagram);
        }
        break;

    case Ack:
	    event = unpack_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);    
        break;

    case Negative_ack:
        event = unpack_negative_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);    
        break;

	case Abort:
	    event = unpack_abort(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        break;         

	default:
	    event = pack_error(datagram);
	    debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was");
            wap_event_dump(datagram);
	    return event;
	}

    wtp_pdu_destroy(pdu);
	
    wap_event_assert(event);
    return event;
}
Example #7
0
File: wtp.c Project: armic/erpts
WAPEvent *unpack_wdp_datagram_real(WAPEvent *datagram)
{
    WTP_PDU *pdu;
    WAPEvent *event;
    Octstr *data;

    gw_assert(datagram->type == T_DUnitdata_Ind);

    data = datagram->u.T_DUnitdata_Ind.user_data;

    if (truncated_datagram(datagram)) {
        warning(0, "WTP: got a truncated datagram, ignoring");
	return NULL;
    }

    pdu = wtp_pdu_unpack(data);

/*
 * Wtp_pdu_unpack returned NULL, we build a rcv error event. 
 */
    if (pdu == NULL) {
        error(0, "WTP: cannot unpack pdu, creating an error pdu");
        event = pack_error(datagram);
        return event;
    }   		

    event = NULL;

    switch (pdu->type) {

    case Invoke:
        event = unpack_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        /* if an WTP initiator gets invoke, it would be an illegal pdu. */
        if (!wtp_event_is_for_responder(event)){
            debug("wap.wtp", 0, "WTP: Invoke when initiator. Message was");
            wap_event_destroy(event);
            event = pack_error(datagram);
        }
        break;

    case Segmented_invoke:
        event = unpack_segmented_invoke(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        break;

    case Result:
        event = unpack_result(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        /* if an WTP responder gets result, it would be an illegal pdu. */
        if (wtp_event_is_for_responder(event)){
            debug("wap.wtp", 0, "WTP: Result when responder. Message was");
            wap_event_destroy(event);
            event = pack_error(datagram);
        }
        break;

    case Ack:
	    event = unpack_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);    
        break;

    case Negative_ack:
        event = unpack_negative_ack(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);    
        break;

	case Abort:
	    event = unpack_abort(pdu, datagram->u.T_DUnitdata_Ind.addr_tuple);
        break;         

	default:
	    event = pack_error(datagram);
	    debug("wap.wtp", 0, "WTP: Unhandled PDU type. Message was");
            wap_event_dump(datagram);
	    return event;
	}

    wtp_pdu_destroy(pdu);
	
    wap_event_assert(event);
    return event;
}