diff --git a/src/csl_cha_cco.c b/src/csl_cha_cco.c index 0eee301..7195876 100644 --- a/src/csl_cha_cco.c +++ b/src/csl_cha_cco.c @@ -1,9 +1,59 @@ /* ITU-T Q.77x TCAP / CCO - Component CoOrdinator * part of CHA (ComponentHAndling), part of CSL (Component Sub-Layer) */ -/* TC-INVOKE.req (TCU -> CHA) */ -int tcap_cha_tc_invoke_req() +int tcap_tc_invoke_req(uint32_t dialogue_id, uint8_t class, int8_t inv_id, + int8_t *linked_id, struct OPERATION *op, + uint8_t *param, uint32_t param_len, uint32_t timeout) { + struct tcap_dialogue *td; + + td = tcap_dialg_by_dialg_id(dialogue_id); + if (!td) + td = tcap_dialg_alloc(dialogue_id); + if (!td) + return -ENOMEM; + + return tcap_cha_tc_invoke_req(td, class, inv_id, linked_id, op, param, param_len, timeout); +} + +/* TC-INVOKE.req (TCU -> CHA) */ +int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t class, int8_t inv_id, + int8_t *linked_id, struct OPERATION *op, + uint8_t *param, uint32_t param_len, uint32_t timeout) +{ + struct tcap_invocation *ti = tcap_ism_alloc(td, inv_id); + struct Component *comp; + struct Invoke *inv; + + if (!ti) + return -ENOMEM; + + if (linked_id) + ti->linked_id = *linked_id; + + /* Allocate a new component structure */ + comp = talloc_zero(ti, struct Component); + comp->present = Component_PR_invoke; + + /* Assemble INV component */ + inv = &comp->choice.invoke; + inv->inv_timeout = timeout; + inv->invokeID = ti->invoke_id; + if (ti->linked_id != TCAP_INV_LINKED_NONE) { + InvokeIdType_t *lid = talloc_zero(inv, InvokeIdType_t); + *lid = ti->linked_id; + inv->linkedID = lid; + } + inv->opCode = op; + if (param && param_len) { + Parameter_t *p = talloc_zero(inv, Parameter_t) + p->buf = param; + p->size = param_len; + inv->parameter = p; + } + /* FIXME: Make component available for this Dialogue ID */ + + return 0; } /* TC-U-CANCEL.req (TCU -> CHA) */ @@ -22,6 +72,43 @@ int tcap_cha_dialg_term(struct tcap_dialogue *td) } } + +/* TC-RESULT-NL / TC-RESULT-L req (TCL -> CHA) */ +int tcap_cha_tc_result_l_req(struct tcap_dialogue *td, int8_t inv_id, int last, + struct OPERATION *op, uint8_t *param, uint32_t param_len) +{ + struct tcap_invocation *ti = tcap_ism_by_inv_id(td, inv_id); + struct Component *comp; + struct returnResult *res; + struct resultretres *retres; + + if (!ti) + return -EINVAL; + + /* Allocate a new component structure */ + comp = talloc_zero(ti, struct Component); + + /* Assemble requested component */ + if (last) { + comp->present = Component_PR_returnResultLast; + res = &comp->choice.returnResultLast; + } else { + comp->present = Component_PR_returnResultNotLast; + res = &comp->choice.returnResultNotLast; + } + res->invokeID = ti->invoke_id; + retres = talloc_zero(comp, struct resultretres); + res->resultretres = retres; + retres->opCode = op; + if (param && param_len) { + Parameter_t *p = talloc_zero(comp, Parameter_t) + p->buf = param; + p->size = param_len; + retres->parameter = p; + } + /* FIXME: Mark component available for this dialogue ID */ +} + /* TC-RESULT-NL / TC-RESULT-L / TC-U-ERROR request TCL -> CHA */ { /* Assemble requested component */ diff --git a/src/csl_cha_ism.c b/src/csl_cha_ism.c index c34d068..58ae0e7 100644 --- a/src/csl_cha_ism.c +++ b/src/csl_cha_ism.c @@ -13,7 +13,7 @@ struct tcap_invocation *tcap_ism_lookup(struct tcap_dialogue *td, int8_t invoke_ struct tcap_invocation *tcap_ism_alloc(struct tcap_dialogue *td, int8_t invoke_id) { - struct tcap_invocation *ti = talloc_zero(tall_tcap_ism_ctx, struct tcap_invocation); + struct tcap_invocation *ti = talloc_zero(td, struct tcap_invocation); if (!ti) return NULL; ti->invoke_id = invoke_id; diff --git a/src/csl_dha.c b/src/csl_dha.c index ef8e18a..cf6ede6 100644 --- a/src/csl_dha.c +++ b/src/csl_dha.c @@ -51,10 +51,13 @@ int tcap_csl_tr_uni_ind() /* Free Dialogue ID */ } -/* TR-BEGIN.ind from TSL */ -int tcap_csl_tr_beg_ind() +/* TR-BEGIN.ind from TSL(TSM) -> CSL(DHA) */ +int tcap_csl_tr_begin_ind(struct TCMessage *tcmsg) { - if (dialogue) { + struct Begin *bgmsg = &tcmsg.choice.begin; + struct tcap_dialogue *td = td_alloc(); + + if (bgmsg->dialoguePortion) { /* extract dialogue portion */ if (0/* Check for correctness */) { /* Build ABORT apdu */ @@ -76,7 +79,7 @@ int tcap_csl_tr_beg_ind() /* Assign Dialogue ID */ /* TC-BEGIN.ind to TCU */ rc = tcap_tcu_begin_ind(td, app_ctx_name, user_info, com_present); - if (components) { + if (bgmsg->components) { /* Components to CHA */ } state = INIT_RECV; @@ -174,11 +177,13 @@ int tcap_csl_tc_u_abort_req(struct tcap_dialogue *td, uint32_t *abrt_reason, voi } /* TR-END.ind from TSL */ -int tcap_csl_tc_end_ind(struct tcap_dialogue *td) +int tcap_csl_tr_end_ind(struct tcap_dialogue *td, struct TCMessage *tcmsg) { + struct End *endmsg = &tcmsg.choice.end; + switch (state) { case ACTIVE: - if (dialogue) { + if (endmsg->dialoguePortion) { /* Discard components */ /* TC-P-ABORT.ind to TCU */ rc = tcap_tcu_abort_ind(td, app_ctx_name, user_info); @@ -199,7 +204,7 @@ int tcap_csl_tc_end_ind(struct tcap_dialogue *td) return -EINVAL; } - if (dialogue) { + if (endmsg->dialoguePortion) { if (app_ctx_mode) { /* Extract dialogue portion */ /* Is dialogue portion corect? */ @@ -209,7 +214,7 @@ int tcap_csl_tc_end_ind(struct tcap_dialogue *td) } /* TC-END.ind to TCU */ rc = tcap_tcu_end_ind(td, app_ctx_name, user_info, components); - if (components) { + if (endmsg->components) { /* Components to CHA */ } } else { @@ -239,9 +244,11 @@ int tcap_csl_tr_notice_ind() return tcap_tcu_notice_ind(td, cause); } -/* TR-CONTONUE.ind from TSL */ -int tcap_csl_tr_continue_ind() +/* TR-CONTINUE.ind from TSL */ +int tcap_csl_tr_continue_ind(struct TCMessage *tcmsg) { + struct Continue *ctmsg = &tcmsg->choice.Continue; + switch (state) { case INIT_SENT: break; @@ -250,7 +257,7 @@ int tcap_csl_tr_continue_ind() return -EINVAL; } - if (dialogue) { + if (ctmsg->dialoguePortion) { if (app_ctx_mode) { /* Extract dialogue portion */ if (!correct) { @@ -274,7 +281,7 @@ err_discard: } /* TC-CONTINUE.ind to TCU */ rc = tcap_tcu_cont_ind(td, app_ctx_name, user_info); - if (components) { + if (ctmsg->components) { /* Components to CHA */ } state = ACTIVE; diff --git a/src/tcap.h b/src/tcap.h index 537feb5..763ca07 100644 --- a/src/tcap.h +++ b/src/tcap.h @@ -23,7 +23,7 @@ struct tcap_dialogue { /* global list of dialogues */ struct llist_head list; - /* Dialogue ID: Maps onto Transaction IDs */ + /* Dialogue ID: Local significance; maps to Transaction IDs */ uint32_t dialogue_id; /* private list of ISMs / Invocations in this dialogue */ @@ -42,6 +42,7 @@ enum tcap_invocation_state { TCAP_IS_WAIT_REJECT, }; +#define TCAP_INV_LINKED_NONE -1234 struct tcap_invocation { struct llist_head list; @@ -54,6 +55,7 @@ struct tcap_invocation { struct tcap_invocation_state state; /* Invocation timer */ + uint32_t inv_timeout; /* Seconds */ struct bsc_timer inv_timer; struct bsc_timer rej_timer; }; diff --git a/src/tsl_tsm.c b/src/tsl_tsm.c index d520445..b131626 100644 --- a/src/tsl_tsm.c +++ b/src/tsl_tsm.c @@ -14,7 +14,7 @@ int tcap_tsm_begin_recv(struct tcap_transaction *tt, struct TCMessage *tcmsg) /* FIXME: DHA */ /* FIXME: TR-BEGIN.ind to CSL */ - tcap_csl_tc_begin_ind(); + tcap_csl_tr_begin_ind(); tt->state = TCPA_TS_INIT_RECV;