242 debug(
"wap.wtp", 0,
"wtp_resp_shutdown: %ld resp_machines left",
288 #define STATE_NAME(state) case state: return #state; 289 #define ROW(state, event, condition, action, new_state) 292 return "unknown state";
311 debug(
"wap.wtp", 0,
"SAR event received, wait for continue");
320 debug(
"wap.wtp", 0,
"WTP: resp_machine %ld, state %s, event %s.",
325 #define STATE_NAME(state) 326 #define ROW(wtp_state, event_type, condition, action, next_state) \ 327 if (resp_machine->state == wtp_state && \ 328 event->type == event_type && \ 331 resp_machine->state = next_state; \ 332 debug("wap.wtp", 0, "WTP %ld: New state %s", resp_machine->mid, #next_state); \ 336 error(0,
"WTP: handle_event: unhandled event!");
337 debug(
"wap.wtp", 0,
"WTP: handle_event: Unhandled event was:");
347 if (resp_machine->state == LISTEN)
355 if (event->
type == RcvInvoke) {
367 return event->type == RcvInvoke &&
event->u.RcvInvoke.version != 0;
376 if (event->
type == RcvInvoke) {
378 debug(
"wap.wtp_resp", 0,
"WTP_RESP: wrong version, aborting" 407 switch (event->
type) {
414 tid =
event->u.RcvInvoke.tid;
415 tuple =
event->u.RcvInvoke.addr_tuple;
420 tid =
event->u.RcvSegInvoke.tid;
421 tuple =
event->u.RcvSegInvoke.addr_tuple;
425 tid =
event->u.RcvAck.tid;
426 tuple =
event->u.RcvAck.addr_tuple;
430 tid =
event->u.RcvAck.tid;
431 tuple =
event->u.RcvAck.addr_tuple;
435 tid =
event->u.RcvAbort.tid;
436 tuple =
event->u.RcvAbort.addr_tuple;
440 tid =
event->u.RcvErrorPDU.tid;
441 tuple =
event->u.RcvErrorPDU.addr_tuple;
445 mid =
event->u.TR_Invoke_Res.handle;
449 mid =
event->u.TR_Result_Req.handle;
453 mid =
event->u.TR_Abort_Req.handle;
457 mid =
event->u.TimerTO_A.handle;
461 mid =
event->u.TimerTO_R.handle;
465 mid =
event->u.TimerTO_W.handle;
469 debug(
"wap.wtp", 0,
"WTP: resp_machine_find_or_create:" 478 if (resp_machine == NULL){
480 switch (event->
type) {
489 debug(
"wap.wtp_resp", 0,
"an erronous pdu received");
500 resp_machine->sar = gw_malloc(
sizeof(
WTPSARData));
501 resp_machine->sar->nsegm = 0;
502 resp_machine->sar->csegm = 0;
503 resp_machine->sar->lsegm = 0;
504 resp_machine->sar->data = NULL;
510 info(0,
"WTP_RESP: resp_machine_find_or_create:" 511 " segmented invoke received, yet having no machine");
518 info(0,
"WTP_RESP: resp_machine_find_or_create:" 519 " ack received, yet having no machine");
523 info(0,
"WTP_RESP: resp_machine_find_or_create:" 524 " negative ack received, yet having no machine");
528 info(0,
"WTP_RESP: resp_machine_find_or_create:" 529 " abort received, yet having no machine");
535 error(0,
"WTP_RESP: resp_machine_find_or_create: WSP primitive to" 536 " a wrong WTP machine");
542 error(0,
"WTP_RESP: resp_machine_find_or_create: timer event" 543 " without a corresponding machine");
547 error(0,
"WTP_RESP: resp_machine_find_or_create: unhandled event");
569 return m->tid == pat->
tid &&
596 #define ENUM(name) resp_machine->name = LISTEN; 597 #define EVENT(name) resp_machine->name = NULL; 598 #define INTEGER(name) resp_machine->name = 0; 599 #define TIMER(name) resp_machine->name = gwtimer_create(resp_queue); 600 #define ADDRTUPLE(name) resp_machine->name = NULL; 601 #define LIST(name) resp_machine->name = NULL; 602 #define SARDATA(name) resp_machine->name = NULL; 603 #define MACHINE(field) field 610 resp_machine->tid = tid;
611 resp_machine->tcl = tcl;
613 debug(
"wap.wtp", 0,
"WTP: Created WTPRespMachine %p (%ld)",
614 (
void *) resp_machine, resp_machine->
mid);
629 debug(
"wap.wtp", 0,
"WTP: Destroying WTPRespMachine %p (%ld)",
630 (
void *) resp_machine, resp_machine->
mid);
634 #define ENUM(name) resp_machine->name = LISTEN; 635 #define EVENT(name) wap_event_destroy(resp_machine->name); 636 #define INTEGER(name) resp_machine->name = 0; 637 #define TIMER(name) gwtimer_destroy(resp_machine->name); 638 #define ADDRTUPLE(name) wap_addr_tuple_destroy(resp_machine->name); 639 #define LIST(name) gwlist_destroy(resp_machine->name,sar_info_destroy); 640 #define SARDATA(name) sardata_destroy(resp_machine->name); 641 #define MACHINE(field) field 643 gw_free(resp_machine);
654 event->u.TR_Invoke_Ind.ack_type = sm->u_ack;
656 event->u.TR_Invoke_Ind.tcl = sm->tcl;
657 event->u.TR_Invoke_Ind.addr_tuple =
659 event->u.TR_Invoke_Ind.handle = sm->
mid;
672 event->u.TR_Result_Cnf.addr_tuple =
674 event->u.TR_Result_Cnf.handle = sm->
mid;
686 event->u.TR_Abort_Ind.abort_code = abort_reason;
687 event->u.TR_Abort_Ind.addr_tuple =
689 event->u.TR_Abort_Ind.handle = sm->
mid;
704 timer_event->
u.TimerTO_A.handle = machine->
mid;
717 timer_event->
u.TimerTO_R.handle = machine->
mid;
731 timer_event->
u.TimerTO_W.handle = machine->
mid;
748 e =
wtp_pack_ack(ack_type, rid_flag, machine->tid, machine->addr_tuple);
762 if (orig_event->
type == RcvInvoke) {
776 machine->addr_tuple, 0);
786 if (orig_event->
type == RcvSegInvoke) {
788 orig_event->
u.RcvSegInvoke.psn);
790 if (orig_event->
u.RcvSegInvoke.gtr == 1) {
792 orig_event->
u.RcvSegInvoke.psn);
796 if (orig_event->
u.RcvSegInvoke.ttr == 1) {
799 psn = orig_event->
u.RcvSegInvoke.psn;
837 if (machine->sar_info == NULL) {
848 debug(
"wap.wtp", 0,
"Duplicated psn found, ignore packet");
861 for (i = 1; i <= last_psn; i++) {
865 debug(
"wap.wtp", 0,
"Packet with psn %d not found", i);
902 sar = resp_machine->sar;
908 debug(
"wap.wtp", 0,
"WTP: begin_sar_result(): data len = %lu",
911 for (psn = 0; !sar->
tr; psn++) {
916 debug(
"wap.wtp", 0,
"WTP: dispath_to_wdp(): psn = %u", psn);
921 resp_machine->rid = 1;
930 gw_assert(resp_machine->sar != NULL && event->
type == RcvAck);
932 sar = resp_machine->sar;
934 debug(
"wap.wtp", 0,
"WTP: continue_sar_result(): lsegm=%d, nsegm=%d, csegm=%d",
940 sar->
csegm =
event->u.RcvAck.psn;
945 resp_machine->result = NULL;
947 for (psn = sar->
csegm + 1; !sar->
tr; psn++) {
952 debug(
"wap.wtp", 0,
"WTP: dispath_to_wdp(): psn = %u",psn);
964 gw_assert(resp_machine->sar != NULL && event->
type == RcvNegativeAck);
966 sar = resp_machine->sar;
968 debug(
"wap.wtp", 0,
"WTP: resend_sar_result(): lsegm=%d, nsegm=%d, csegm=%d",
973 if (event->
u.RcvNegativeAck.nmissing) {
975 for(i = 0; i <
event->u.RcvNegativeAck.nmissing; i++) {
979 debug(
"wap.wtp", 0,
"WTP: dispath_to_wdp(): psn = %u", psn);
986 for (psn = sar->
csegm+1; !sar->
tr; psn++) {
989 debug(
"wap.wtp", 0,
"WTP: dispath_to_wdp(): psn = %u", psn);
static void sardata_destroy(void *sardata)
static WAPEvent * create_tr_invoke_ind(WTPRespMachine *sm, Octstr *user_data)
void error(int err, const char *fmt,...)
WAPEvent * wtp_pack_sar_result(WTPRespMachine *machine, int psn)
void info(int err, const char *fmt,...)
static WTPRespMachine * resp_machine_create(WAPAddrTuple *tuple, long tid, long tcl)
static void handle_wrong_version(WAPEvent *event)
static int is_wanted_sar_data(void *a, void *b)
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
static void send_abort(WTPRespMachine *machine, long type, long reason)
gw_assert(wtls_machine->packet_to_send !=NULL)
void counter_destroy(Counter *counter)
void gwlist_append(List *list, void *item)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
void gwlist_produce(List *list, void *item)
long gwlist_len(List *list)
static int process_sar_transaction(WTPRespMachine *machine, WAPEvent **event)
static WTPRespMachine * resp_machine_find_or_create(WAPEvent *event)
void wtp_resp_shutdown(void)
void wtp_pack_set_rid(WAPEvent *dgram, long rid)
static void start_timer_W(WTPRespMachine *machine)
wap_dispatch_func_t * dispatch_to_wdp
static WTPRespMachine * resp_machine_find(WAPAddrTuple *tuple, long tid, long mid)
void wap_event_dump(WAPEvent *event)
void gwthread_join_every(gwthread_func_t *func)
unsigned long counter_increase(Counter *counter)
WAPAddrTuple * wap_addr_tuple_duplicate(WAPAddrTuple *tuple)
WAPEvent * wtp_pack_sar_ack(long ack_type, long tid, WAPAddrTuple *address, int psn)
void wtp_tid_cache_init(void)
static void resend_sar_result(WTPRespMachine *resp_machine, WAPEvent *event)
static void resp_event_handle(WTPRespMachine *machine, WAPEvent *event)
static Counter * resp_machine_id_counter
static void main_thread(void *)
T DUnitdata TR Invoke TR Invoke TR Result TR Abort S Connect S Suspend S Resume S Suspend S Resume S Disconnect S MethodInvoke S MethodInvoke S MethodResult S MethodInvoke S MethodResult S MethodAbort S Push S ConfirmedPush S ConfirmedPush S PushAbort RcvAck
static WAPEvent * assembly_sar_event(WTPRespMachine *machine, int last_psn)
Counter * counter_create(void)
void gwtimer_start(Timer *timer, int interval, WAPEvent *event)
void gwlist_remove_producer(List *list)
static int add_sar_transaction(WTPRespMachine *machine, Octstr *data, int psn)
static void start_timer_R(WTPRespMachine *machine)
static WAPEvent * create_tr_abort_ind(WTPRespMachine *sm, long abort_reason)
void wtp_resp_dispatch_event(WAPEvent *event)
void wap_event_destroy_item(void *event)
static int is_wanted_resp_machine(void *a, void *b)
#define octstr_duplicate(ostr)
wap_dispatch_func_t * dispatch_to_push
const char * wap_event_name(WAPEventName type)
long gwlist_delete_equal(List *list, void *item)
#define wap_event_create(type)
void timers_shutdown(void)
void octstr_destroy(Octstr *ostr)
static void resp_machine_destroy(void *sm)
static long resp_timer_freq
#define gwthread_create(func, arg)
static void send_ack(WTPRespMachine *machine, long ack_type, int rid_flag)
static char * name_resp_state(int name)
void wtp_tid_cache_shutdown(void)
static void begin_sar_result(WTPRespMachine *machine, WAPEvent *event)
WAPEvent * wtp_pack_ack(long ack_type, int rid_flag, long tid, WAPAddrTuple *address)
static int erroneous_field_in(WAPEvent *event)
WAPEvent * wap_event_duplicate(WAPEvent *event)
long octstr_len(const Octstr *ostr)
T DUnitdata TR Invoke TR Invoke TR Result TR Abort S Connect S Suspend S Resume S Suspend S Resume S Disconnect S MethodInvoke S MethodInvoke S MethodResult S MethodInvoke S MethodResult S MethodAbort S Push S ConfirmedPush S ConfirmedPush S PushAbort RcvInvoke
int wap_addr_tuple_same(WAPAddrTuple *a, WAPAddrTuple *b)
void * gwlist_consume(List *list)
void debug(const char *place, int err, const char *fmt,...)
static WAPEvent * create_tr_result_cnf(WTPRespMachine *sm)
static List * resp_machines
void wtp_resp_init(wap_dispatch_func_t *datagram_dispatch, wap_dispatch_func_t *session_dispatch, wap_dispatch_func_t *push_dispatch, long timer_freq)
WAPEvent * wtp_pack_abort(long abort_type, long abort_reason, long tid, WAPAddrTuple *address)
static void handle_erroneous_field_in(WAPEvent *event)
static void start_timer_A(WTPRespMachine *machine)
static enum @108 resp_run_status
void gwlist_add_producer(List *list)
int octstr_get_char(const Octstr *ostr, long pos)
static void sar_info_destroy(void *sar_info)
void wap_event_destroy(WAPEvent *event)
void wap_dispatch_func_t(WAPEvent *event)
wap_dispatch_func_t * dispatch_to_wsp
static void continue_sar_result(WTPRespMachine *machine, WAPEvent *event)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)