⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtp_resp.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 2 页
字号:
                resp_machine->sar = gw_malloc(sizeof(WTPSARData));                resp_machine->sar->nsegm = 0;                resp_machine->sar->csegm = 0;                resp_machine->sar->lsegm = 0;                resp_machine->sar->data = NULL;		            }            break;	            case RcvSegInvoke:            info(0, "WTP_RESP: resp_machine_find_or_create:"                 " segmented invoke received, yet having no machine");            break;        /*         * This and the following branch implement test nro 3 in WTP 10.2.         */        case RcvAck:             info(0, "WTP_RESP: resp_machine_find_or_create:"                 " ack received, yet having no machine");            break;        case RcvNegativeAck:             info(0, "WTP_RESP: resp_machine_find_or_create:"                 " negative ack received, yet having no machine");            break;        case RcvAbort:             info(0, "WTP_RESP: resp_machine_find_or_create:"                 " abort received, yet having no machine");            break;        case TR_Invoke_Res:         case TR_Result_Req:         case TR_Abort_Req:            error(0, "WTP_RESP: resp_machine_find_or_create: WSP primitive to"                  " a wrong WTP machine");            break;        case TimerTO_A:         case TimerTO_R:         case TimerTO_W:            error(0, "WTP_RESP: resp_machine_find_or_create: timer event"                  " without a corresponding machine");            break;                         default:            error(0, "WTP_RESP: resp_machine_find_or_create: unhandled event");            wap_event_dump(event);            break;        }   } /* if machine == NULL */      return resp_machine;}static int is_wanted_resp_machine(void *a, void *b) {    machine_pattern *pat;    WTPRespMachine *m;	    m = a;    pat = b;    if (m->mid == pat->mid)	return 1;    if (pat->mid != -1)	return 0;    return m->tid == pat->tid &&            wap_addr_tuple_same(m->addr_tuple, pat->tuple);}static WTPRespMachine *resp_machine_find(WAPAddrTuple *tuple, long tid,                                          long mid) {    machine_pattern pat;    WTPRespMachine *m;	    pat.tuple = tuple;    pat.tid = tid;    pat.mid = mid;	    m = list_search(resp_machines, &pat, is_wanted_resp_machine);    return m;}static WTPRespMachine *resp_machine_create(WAPAddrTuple *tuple, long tid,                                            long tcl) {    WTPRespMachine *resp_machine;	    resp_machine = gw_malloc(sizeof(WTPRespMachine));             #define ENUM(name) resp_machine->name = LISTEN;    #define EVENT(name) resp_machine->name = NULL;    #define INTEGER(name) resp_machine->name = 0;     #define TIMER(name) resp_machine->name = gwtimer_create(resp_queue);     #define ADDRTUPLE(name) resp_machine->name = NULL;     #define LIST(name) resp_machine->name = NULL;    #define SARDATA(name) resp_machine->name = NULL;    #define MACHINE(field) field    #include "wtp_resp_machine.def"    list_append(resp_machines, resp_machine);    resp_machine->mid = counter_increase(resp_machine_id_counter);    resp_machine->addr_tuple = wap_addr_tuple_duplicate(tuple);    resp_machine->tid = tid;    resp_machine->tcl = tcl;	    debug("wap.wtp", 0, "WTP: Created WTPRespMachine %p (%ld)", 	  (void *) resp_machine, resp_machine->mid);    return resp_machine;} /* * Destroys a WTPRespMachine. Assumes it is safe to do so. Assumes it has  * already been deleted from the machines list. */static void resp_machine_destroy(void * p){    WTPRespMachine *resp_machine;    resp_machine = p;    debug("wap.wtp", 0, "WTP: Destroying WTPRespMachine %p (%ld)", 	  (void *) resp_machine, resp_machine->mid);	    list_delete_equal(resp_machines, resp_machine);            #define ENUM(name) resp_machine->name = LISTEN;    #define EVENT(name) wap_event_destroy(resp_machine->name);    #define INTEGER(name) resp_machine->name = 0;     #define TIMER(name) gwtimer_destroy(resp_machine->name);     #define ADDRTUPLE(name) wap_addr_tuple_destroy(resp_machine->name);     #define LIST(name) list_destroy(resp_machine->name,sar_info_destroy);    #define SARDATA(name) sardata_destroy(resp_machine->name);    #define MACHINE(field) field    #include "wtp_resp_machine.def"    gw_free(resp_machine);}/* * Create a TR-Invoke.ind event. */static WAPEvent *create_tr_invoke_ind(WTPRespMachine *sm, Octstr *user_data) {    WAPEvent *event;	    event = wap_event_create(TR_Invoke_Ind);    event->u.TR_Invoke_Ind.ack_type = sm->u_ack;    event->u.TR_Invoke_Ind.user_data = octstr_duplicate(user_data);    event->u.TR_Invoke_Ind.tcl = sm->tcl;    event->u.TR_Invoke_Ind.addr_tuple = 	wap_addr_tuple_duplicate(sm->addr_tuple);    event->u.TR_Invoke_Ind.handle = sm->mid;    return event;}/* * Create a TR-Result.cnf event. */static WAPEvent *create_tr_result_cnf(WTPRespMachine *sm) {    WAPEvent *event;	    event = wap_event_create(TR_Result_Cnf);    event->u.TR_Result_Cnf.addr_tuple = 	wap_addr_tuple_duplicate(sm->addr_tuple);    event->u.TR_Result_Cnf.handle = sm->mid;    return event;}/* * Creates TR-Abort.ind event from a responder state machine. In addition, set * the responder indication flag. */static WAPEvent *create_tr_abort_ind(WTPRespMachine *sm, long abort_reason) {    WAPEvent *event;	    event = wap_event_create(TR_Abort_Ind);    event->u.TR_Abort_Ind.abort_code = abort_reason;    event->u.TR_Abort_Ind.addr_tuple = 	wap_addr_tuple_duplicate(sm->addr_tuple);    event->u.TR_Abort_Ind.handle = sm->mid;    event->u.TR_Abort_Ind.ir_flag = RESPONDER_INDICATION;    return event;}/* * Start acknowledgement interval timer. Multiply time with * resp_timer_freq. */static void start_timer_A(WTPRespMachine *machine) {    WAPEvent *timer_event;    timer_event = wap_event_create(TimerTO_A);    timer_event->u.TimerTO_A.handle = machine->mid;    gwtimer_start(machine->timer, L_A_WITH_USER_ACK * resp_timer_freq,                   timer_event);}/* * Start retry interval timer. Multiply time with resp_timer_freq. */static void start_timer_R(WTPRespMachine *machine) {    WAPEvent *timer_event;    timer_event = wap_event_create(TimerTO_R);    timer_event->u.TimerTO_R.handle = machine->mid;    gwtimer_start(machine->timer, L_R_WITH_USER_ACK * resp_timer_freq,                   timer_event);}/* * Start segmentation timeout interval timer. Multiply time with * resp_timer_freq. */static void start_timer_W(WTPRespMachine *machine){    WAPEvent *timer_event;    timer_event = wap_event_create(TimerTO_W);    timer_event->u.TimerTO_W.handle = machine->mid;    gwtimer_start(machine->timer, W_WITH_USER_ACK * resp_timer_freq,                   timer_event);}static void send_abort(WTPRespMachine *machine, long type, long reason){    WAPEvent *e;    e = wtp_pack_abort(type, reason, machine->tid, machine->addr_tuple);    dispatch_to_wdp(e);}static void send_ack(WTPRespMachine *machine, long ack_type, int rid_flag){    WAPEvent *e;    e = wtp_pack_ack(ack_type, rid_flag, machine->tid, machine->addr_tuple);    dispatch_to_wdp(e);}/*  * Process incoming event, checking for WTP SAR  */static int process_sar_transaction(WTPRespMachine *machine, WAPEvent **event) {    WAPEvent *e, *orig_event;    int psn;      orig_event = *event;    if (orig_event->type == RcvInvoke) {         if (!orig_event->u.RcvInvoke.ttr || !orig_event->u.RcvInvoke.gtr) { /* SAR */            /* Ericcson set TTR flag even if we have the only part */            if (orig_event->u.RcvInvoke.ttr == 1) {                return 1; /* Not SAR although TTR flag was set */            } else {                /* save initial event */                machine->sar_invoke = wap_event_duplicate(orig_event);                /* save data into list with psn = 0 */                add_sar_transaction(machine, orig_event->u.RcvInvoke.user_data, 0);                if (orig_event->u.RcvInvoke.gtr == 1) { /* Need to acknowledge */                    e = wtp_pack_sar_ack(ACKNOWLEDGEMENT, machine->tid,                                         machine->addr_tuple, 0);                    dispatch_to_wdp(e);                }                return 0;            }        } else {            return 1; /* Not SAR */        }     }    if (orig_event->type == RcvSegInvoke) {        add_sar_transaction(machine, orig_event->u.RcvSegInvoke.user_data,                             orig_event->u.RcvSegInvoke.psn);        if (orig_event->u.RcvSegInvoke.gtr == 1) { /* Need to acknowledge */            e = wtp_pack_sar_ack(ACKNOWLEDGEMENT, machine->tid, machine->addr_tuple,                                 orig_event->u.RcvSegInvoke.psn);            dispatch_to_wdp(e);        }        if (orig_event->u.RcvSegInvoke.ttr == 1) { /* Need to feed to WSP */            /* Create assembled event */            psn = orig_event->u.RcvSegInvoke.psn;            wap_event_destroy(orig_event);                  *event = assembly_sar_event(machine,psn);            gw_assert(event != NULL);            return 1;        }        return 0;    }    /* Not SAR message */    return 1;}static int is_wanted_sar_data(void *a, void *b){    sar_info_t *s;    int *i;    s = a;    i = b;    if (*i == s->sar_psn) {        return 1;    } else {        return 0;    }}/*  * Return 0 if transaction added suscessufully, 1 otherwise. */static int add_sar_transaction(WTPRespMachine *machine, Octstr *data, int psn) {    sar_info_t *sar_info;    if (machine->sar_info == NULL) {        machine->sar_info = list_create();    }    if (list_search(machine->sar_info, &psn, is_wanted_sar_data) == NULL) {        sar_info = gw_malloc(sizeof(sar_info_t));        sar_info->sar_psn = psn;        sar_info->sar_data = octstr_duplicate(data);        list_append(machine->sar_info, sar_info);        return 0;    } else {        debug("wap.wtp", 0, "Duplicated psn found, ignore packet");        return 1;    } }static WAPEvent *assembly_sar_event(WTPRespMachine *machine, int last_psn) {    WAPEvent *e;    int i;    sar_info_t *sar_info;    e = wap_event_duplicate(machine->sar_invoke);    for (i = 1; i <= last_psn; i++) {        if ((sar_info = list_search(machine->sar_info, &i, is_wanted_sar_data)) != NULL) {            octstr_append(e->u.RcvInvoke.user_data,sar_info->sar_data);        } else {            debug("wap.wtp", 0, "Packet with psn %d not found", i);            return e;        }    }    return e;}static void sar_info_destroy(void *p) {    sar_info_t *sar_info;    sar_info = p;      octstr_destroy(sar_info->sar_data);    gw_free(sar_info);}static void sardata_destroy(void *p) {    WTPSARData * sardata;    if (p) {        sardata = p;        octstr_destroy(sardata->data);        gw_free(sardata);    }}static void begin_sar_result(WTPRespMachine *resp_machine, WAPEvent *event) {    WAPEvent *result;    WTPSARData *sar;    int psn;    gw_assert(resp_machine->sar != NULL);    sar = resp_machine->sar;    sar->data = octstr_duplicate(event->u.TR_Result_Req.user_data);    sar->nsegm = (octstr_len(sar->data)-1)/SAR_SEGM_SIZE;    sar->tr = sar->lsegm = 0;    sar->csegm = -1;    debug("wap.wtp", 0, "WTP: begin_sar_result(): data len = %lu",           octstr_len(sar->data));    for (psn = 0; !sar->tr; psn++) {        result = wtp_pack_sar_result(resp_machine, psn);        if (sar->tr)             resp_machine->result = wap_event_duplicate(result);        debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);        dispatch_to_wdp(result);        sar->lsegm = psn;    }    resp_machine->rid = 1;}static void continue_sar_result(WTPRespMachine *resp_machine, WAPEvent *event) {    WAPEvent *result;    WTPSARData *sar;    int psn;    gw_assert(resp_machine->sar != NULL && event->type == RcvAck);    sar = resp_machine->sar;    debug("wap.wtp", 0, "WTP: continue_sar_result(): lsegm=%d, nsegm=%d, csegm=%d",          sar->lsegm, sar->nsegm, sar->csegm);    start_timer_R(resp_machine);    if (event->u.RcvAck.psn>sar->csegm) {        sar->csegm = event->u.RcvAck.psn;    }    sar->tr = 0;    wap_event_destroy(resp_machine->result);    resp_machine->result = NULL;    for (psn = sar->csegm + 1; !sar->tr; psn++) {        result = wtp_pack_sar_result(resp_machine, psn);        if (sar->tr)             resp_machine->result = wap_event_duplicate(result);        debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u",psn);        dispatch_to_wdp(result);        sar->lsegm = psn;    }}static void resend_sar_result(WTPRespMachine *resp_machine, WAPEvent *event){    WAPEvent *result;    WTPSARData *sar;    int	psn, i;    gw_assert(resp_machine->sar != NULL && event->type == RcvNegativeAck);    sar = resp_machine->sar;    debug("wap.wtp", 0, "WTP: resend_sar_result(): lsegm=%d, nsegm=%d, csegm=%d",          sar->lsegm, sar->nsegm, sar->csegm);    start_timer_R(resp_machine);    if (event->u.RcvNegativeAck.nmissing) {         /* if we have a list of missed packets */        for(i = 0; i < event->u.RcvNegativeAck.nmissing; i++) {            if ((psn = octstr_get_char(event->u.RcvNegativeAck.missing, i)) >= 0) {		                result = wtp_pack_sar_result(resp_machine, psn);                wtp_pack_set_rid(result, 1);                debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);                dispatch_to_wdp(result);            }        }    } else {         /* if we have to resend a whole group */        sar->tr = 0;        for (psn = sar->csegm+1; !sar->tr; psn++) {            result = wtp_pack_sar_result(resp_machine, psn);            wtp_pack_set_rid(result, 1);            debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);            dispatch_to_wdp(result);        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -