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

📄 wtp_init.c

📁 mms client
💻 C
📖 第 1 页 / 共 2 页
字号:
 */                if (event->u.RcvAck.tid_ok) {                    dispatch_to_wdp(wtp_pack_abort(PROVIDER, INVALIDTID,                                                   tid, tuple));                }/* Case nro 3, normal ack */                else                    info(0, "WTP_INIT: machine_find_or_create: ack "                         "received, yet having no machine");                break;/* Case nro 3, abort */            case RcvAbort:                info(0, "WTP_INIT: machine_find_or_create: abort "                     "received, yet having no machine");                break;            case TR_Invoke_Req:                machine = init_machine_create(tuple, tid, tidnew, event->u.TR_Invoke_Req.handle, event->u.TR_Invoke_Req.tcl);                /* if SAR needed */                if (octstr_len(event->u.TR_Invoke_Req.user_data) > SAR_SEGM_SIZE) {                    machine->sar = gw_malloc(sizeof(WTPSARData));                    machine->sar->nsegm = 0;                    machine->sar->csegm = 0;                    machine->sar->lsegm = 0;                    machine->sar->data = NULL;		                }                break;            case TR_Abort_Req:                error(0, "WTP_INIT: machine_find_or_create: WSP "                      "primitive to a wrong WTP machine");                break;            case TimerTO_R:                error(0, "WTP_INIT: machine_find_or_create: timer "                      "event without a corresponding machine");                break;            default:                error(0, "WTP_INIT: machine_find_or_create: unhandled"                      "event");                wap_event_dump(event);                break;         }    }    else {        switch(event->type) {            case RcvResult:                /* if SAR requested */                if (!event->u.RcvResult.gtr || !event->u.RcvResult.ttr) {                    machine->sar = gw_malloc(sizeof(WTPSARData));                    machine->sar->nsegm = 0;                    machine->sar->csegm = 0;                    machine->sar->lsegm = 0;                    machine->sar->data = NULL;		                }                break;            default:                break;        }    }    return machine;}/* * Creates TR-Invoke.cnf event */static WAPEvent *create_tr_invoke_cnf(WTPInitMachine *init_machine) {    WAPEvent *event;    gw_assert(init_machine != NULL);    event = wap_event_create(TR_Invoke_Cnf);    event->u.TR_Invoke_Cnf.handle = init_machine->mid;    event->u.TR_Invoke_Cnf.addr_tuple =     wap_addr_tuple_duplicate(init_machine->addr_tuple);    return event;}/* * Creates TR-Abort.ind event from an initiator state machine. In addtion, set * the ir_flag on. */static WAPEvent *create_tr_abort_ind(WTPInitMachine *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 = INITIATOR_INDICATION;    return event;}static int tid_wrapped(unsigned short tid) {    return tid > (1 << 15);}static unsigned short rcv_tid(unsigned short tid) {    return tid ^ 0x8000;}/* * Start retry interval timer (strictly speaking, timer iniatilised with retry * interval). Multiply timer value with init_timer_freq. */static void start_initiator_timer_R(WTPInitMachine *machine) {    WAPEvent *timer_event;    int seconds;    timer_event = wap_event_create(TimerTO_R);    timer_event->u.TimerTO_R.handle = machine->mid;    if (machine->u_ack)        seconds = S_R_WITH_USER_ACK * init_timer_freq;    else        seconds = S_R_WITHOUT_USER_ACK * init_timer_freq;    gwtimer_start(machine->timer, seconds, timer_event);}static void start_initiator_timer_A(WTPInitMachine *machine) {    WAPEvent *timer_event;    int seconds;    timer_event = wap_event_create(TimerTO_A);    timer_event->u.TimerTO_A.handle = machine->mid;    if (machine->u_ack)        seconds = S_R_WITH_USER_ACK * init_timer_freq;    else        seconds = S_R_WITHOUT_USER_ACK * init_timer_freq;    gwtimer_start(machine->timer, seconds, timer_event);}static void start_initiator_timer_W(WTPInitMachine *machine) {    WAPEvent *timer_event;    int seconds;    timer_event = wap_event_create(TimerTO_W);    timer_event->u.TimerTO_W.handle = machine->mid;    if (machine->u_ack)        seconds = S_R_WITH_USER_ACK * init_timer_freq;    else        seconds = S_R_WITHOUT_USER_ACK * init_timer_freq;    gwtimer_start(machine->timer, seconds, timer_event);}static void stop_initiator_timer(Timer *timer) {    debug("wap.wtp_init", 0, "stopping timer");    gw_assert(timer);    gwtimer_stop(timer);}static void send_abort(WTPInitMachine *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(WTPInitMachine *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(WTPInitMachine *machine, WAPEvent **event) {    WAPEvent *e, *orig_event;    int psn;      orig_event = *event;    if (orig_event->type == RcvResult) {         if (!orig_event->u.RcvResult.ttr || !orig_event->u.RcvResult.gtr) { /* SAR */            /* Ericcson set TTR flag even if we have the only part */            if (orig_event->u.RcvResult.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.RcvResult.user_data, 0);                if (orig_event->u.RcvResult.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 == RcvSegResult) {        add_sar_transaction(machine, orig_event->u.RcvSegResult.user_data,                             orig_event->u.RcvSegResult.psn);        if (orig_event->u.RcvSegResult.gtr == 1) { /* Need to acknowledge */            e = wtp_pack_sar_ack(ACKNOWLEDGEMENT, machine->tid, machine->addr_tuple,                                 orig_event->u.RcvSegResult.psn);            dispatch_to_wdp(e);        }        if (orig_event->u.RcvSegResult.ttr == 1) { /* Need to feed to WSP */            /* Create assembled event */            psn = orig_event->u.RcvSegResult.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(WTPInitMachine *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(WTPInitMachine *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.RcvResult.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_invoke(WTPInitMachine *init_machine, WAPEvent *event) {    WAPEvent *invoke;    WTPSARData *sar;    int psn;    gw_assert(init_machine->sar != NULL);    sar = init_machine->sar;    sar->data = octstr_duplicate(event->u.TR_Invoke_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_invoke(): data len = %lu",           octstr_len(sar->data));    for (psn = 0; !sar->tr; psn++) {        invoke = wtp_pack_sar_invoke(init_machine, psn);        if (sar->tr)             init_machine->invoke = wap_event_duplicate(invoke);        debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);        dispatch_to_wdp(invoke);        sar->lsegm = psn;    }    init_machine->rid = 1;}static void continue_sar_invoke(WTPInitMachine *init_machine, WAPEvent *event) {    WAPEvent *invoke;    WTPSARData *sar;    int psn;    gw_assert(init_machine->sar != NULL && event->type == RcvAck);    sar = init_machine->sar;    debug("wap.wtp", 0, "WTP: continue_sar_invoke(): lsegm=%d, nsegm=%d, csegm=%d",          sar->lsegm, sar->nsegm, sar->csegm);    start_initiator_timer_R(init_machine);    if (event->u.RcvAck.psn>sar->csegm) {        sar->csegm = event->u.RcvAck.psn;    }    sar->tr = 0;    wap_event_destroy(init_machine->invoke);    init_machine->invoke = NULL;    for (psn = sar->csegm + 1; !sar->tr; psn++) {        invoke = wtp_pack_sar_invoke(init_machine, psn);        if (sar->tr)             init_machine->invoke = wap_event_duplicate(invoke);        debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u",psn);        dispatch_to_wdp(invoke);        sar->lsegm = psn;    }}static void resend_sar_invoke(WTPInitMachine *init_machine, WAPEvent *event){    WAPEvent *invoke;    WTPSARData *sar;    int	psn, i;    gw_assert(init_machine->sar != NULL && event->type == RcvNegativeAck);    sar = init_machine->sar;    debug("wap.wtp", 0, "WTP: resend_sar_invoke(): lsegm=%d, nsegm=%d, csegm=%d",          sar->lsegm, sar->nsegm, sar->csegm);    start_initiator_timer_R(init_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) {		                invoke = wtp_pack_sar_invoke(init_machine, psn);                wtp_pack_set_rid(invoke, 1);                debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);                dispatch_to_wdp(invoke);            }        }    } else {         /* if we have to resend a whole group */        sar->tr = 0;        for (psn = sar->csegm+1; !sar->tr; psn++) {            invoke = wtp_pack_sar_invoke(init_machine, psn);            wtp_pack_set_rid(invoke, 1);            debug("wap.wtp", 0, "WTP: dispath_to_wdp(): psn = %u", psn);            dispatch_to_wdp(invoke);        }    }}

⌨️ 快捷键说明

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