Make TC-user signalling of TC-RESULT-{L,NL} work

This commit is contained in:
Harald Welte 2010-07-19 16:29:51 +02:00
parent a764e40c80
commit a7c47009c9
4 changed files with 138 additions and 95 deletions

View File

@ -203,6 +203,7 @@ int tcap_cha_proc_components(struct tcap_dialogue *td, struct ComponentPortion *
for (i = 0; i < comp_por->list.count; i++) {
/* Extract next component */
struct Component *comp = comp_por->list.array[i];
int is_last_component = i+1 == comp_por->list.count ? 1 : 0;
/* Check syntax error and proceed with 5, 3 or 4 */
switch (comp->present) {
@ -216,29 +217,33 @@ int tcap_cha_proc_components(struct tcap_dialogue *td, struct ComponentPortion *
/* TC-INVOKE.ind (TCU <- CHA) */
rc = tcap_tcu_tc_invoke_ind(ti, &comp->choice.invoke.opCode,
comp->choice.invoke.parameter,
i+1 == comp_por->list.count ? 1 : 0);
is_last_component);
break;
case Component_PR_returnResultNotLast:
ti = tcap_ism_lookup(td, comp->choice.returnResultNotLast.invokeID);
/* ISM active? */
/* RR-NL.recv CCO -> ISM */
rc = tcap_ism_rr_nl_recv(ti, &comp->choice.returnResultNotLast);
rc = tcap_ism_rr_nl_recv(ti, &comp->choice.returnResultNotLast,
is_last_component);
break;
case Component_PR_returnResultLast:
ti = tcap_ism_lookup(td, comp->choice.returnResultLast.invokeID);
/* ISM active? */
/* RR-L.recv CCO -> ISM */
rc = tcap_ism_rr_l_recv(ti, &comp->choice.returnResultLast);
rc = tcap_ism_rr_l_recv(ti, &comp->choice.returnResultLast,
is_last_component);
break;
case Component_PR_returnError:
ti = tcap_ism_lookup(td, comp->choice.returnError.invokeID);
/* ISM active? */
/* RE.recv CCO -> ISM */
rc = tcap_ism_re_recv(ti, &comp->choice.returnError);
rc = tcap_ism_re_recv(ti, &comp->choice.returnError,
is_last_component);
break;
case Component_PR_reject:
/* TC-R-REJECT or TC-U-REJECT.ind (TCU <- CHA) */
rc = tcap_tcu_tc_r_rej_ind(ti, &ti->invoke_id, 0 /* FIXME problem */);
rc = tcap_tcu_tc_r_rej_ind(ti, &ti->invoke_id, 0 /* FIXME problem */,
is_last_component);
break;
case Component_PR_NOTHING:
break;

View File

@ -117,15 +117,23 @@ int tcap_ism_op_sent(struct tcap_invocation *ti, uint8_t op_class)
}
/* RR-L received (CCO -> ISM) */
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res)
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int last_component)
{
int rc = 0;
OPERATION_t *opCode = NULL;
Parameter_t *param = NULL;
if (res->resultretres) {
opCode = &res->resultretres->opCode;
param = res->resultretres->parameter;
}
switch (ti->state) {
case TCAP_IS_OP_SENT_CL1:
case TCAP_IS_OP_SENT_CL3:
/* TC-RESULT-L.ind (TCU <- CHA) */
rc = tcap_tcu_result_l_ind();
rc = tcap_tcu_result_l_ind(ti, opCode, param, last_component);
/* Stop invocation timer */
bsc_del_timer(&ti->inv_timer);
/* Start reject timer */
@ -147,7 +155,8 @@ int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res)
}
/* RE received (CCO -> ISM) */
int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *re)
int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *re,
int last_component)
{
switch (ti->state) {
case TCAP_IS_OP_SENT_CL1:
@ -174,15 +183,23 @@ int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *re)
}
/* RR-NL received (CCO -> ISM) */
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res)
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int last_component)
{
int rc = 0;
OPERATION_t *opCode = NULL;
Parameter_t *param = NULL;
if (res->resultretres) {
opCode = &res->resultretres->opCode;
param = res->resultretres->parameter;
}
switch (ti->state) {
case TCAP_IS_OP_SENT_CL1:
case TCAP_IS_OP_SENT_CL3:
/* TC-RESULT-NL.ind (TCU <- CHA) */
rc = tcap_tcu_result_nl_ind();
rc = tcap_tcu_result_nl_ind(ti, opCode, param, last_component);
/* stay in SENT_CL1 state */
break;
case TCAP_IS_OP_SENT_CL2:

View File

@ -121,13 +121,16 @@ void tcap_ism_free(struct tcap_invocation *ti);
int tcap_ism_op_sent(struct tcap_invocation *ti, uint8_t op_class);
/* RR-L received (CCO -> ISM) */
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res);
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int is_last_comp);
/* RE received (CCO -> ISM) */
int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *err);
int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *err,
int is_last_comp);
/* RR-NL received (CCO -> ISM) */
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res);
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int is_last_comp);
/* Terminate (CCO -> ISM) */
int tcap_ism_terminate(struct tcap_invocation *ti);
@ -242,7 +245,7 @@ int tcap_scXp_n_unitdata_req(struct tcap_transport_entity *se, struct msgb *msg)
/* TCU */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last);
int tcap_tcu_tc_l_rej_ind(struct tcap_invocation *td, int8_t *invoke_id, uint32_t problem);
int tcap_tcu_tc_r_rej_ind(struct tcap_invocation *td, int8_t *invoke_id, uint32_t problem);
int tcap_tcu_tc_r_rej_ind(struct tcap_invocation *td, int8_t *invoke_id, uint32_t problem, int is_last);
int tcap_tcu_begin_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present);
int tcap_tcu_uni_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present);
int tcap_tcu_cont_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present);

180
src/tcu.c
View File

@ -66,35 +66,9 @@ LIB_EXPORTED const char *tcap_prim_name(enum tcap_primitive prim)
return get_value_string(tcap_prim_names, prim);
}
/* Table 10 / Q.771 : TC-INVOKE.ind */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last)
{
struct tcap_component_ind tcci;
memset(&tcci, 0, sizeof(tcci));
tcci.dialg_id = ti->dialogue->dialogue_id;
tcci.invoke_id = ti->invoke_id;
if (ti->linked_id) {
tcci._linked_id = ti->_linked_id;
tcci.linked_id = &tcci._linked_id;
}
memcpy(&tcci.operation, oper, sizeof(tcci.operation));
tcci.last_component = last;
return tcap_user_ind_comp(TCAP_PR_TC_INVOKE, &tcci);
}
/* TC-L-REJECT.ind */
int tcap_tcu_tc_l_rej_ind(struct tcap_invocation *ti, int8_t *invoke_id, uint32_t problem)
{
}
/* TC-R-REJECT.ind */
int tcap_tcu_tc_r_rej_ind(struct tcap_invocation *ti, int8_t *invoke_id, uint32_t problem)
{
}
/***********************************************************************/
/* Component Primitives */
/***********************************************************************/
/* fill the application context and user information part of 'tcap_dialg_ind' */
static int fill_tcap_dialg_ind(struct tcap_dialg_ind *tcdi,
@ -186,58 +160,6 @@ int tcap_tcu_notice_ind(struct tcap_dialogue *td, uint32_t cause)
{
}
/* TC-RESULT-L.ind from ISM */
int tcap_tcu_result_l_ind()
{
}
/* TC-RESULT-NL.ind from ISM */
int tcap_tcu_result_nl_ind()
{
}
LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
{
struct tcap_dialogue *td;
int rc = 0;
fprintf(stdout, "<- USER_REQ_COMP(%s)\n", tcap_prim_name(prim));
/* Resolve (or allocate) the dialogue/transaction state */
td = tcap_dialg_by_dialg_id(tcci->dialg_id);
if (!td) {
switch (prim) {
case TCAP_PR_TC_INVOKE:
td = tcap_dialg_alloc(tcci->dialg_id);
td->trans.tid_local = tcap_trans_id_alloc();
break;
default:
return -EINVAL;
}
}
/* Actually dispatch the primitive */
switch (prim) {
case TCAP_PR_TC_INVOKE:
rc = tcap_cha_tc_invoke_req(td, tcci->op_class, tcci->invoke_id, tcci->linked_id, &tcci->operation,
tcci->parameter.buf, tcci->parameter.size, tcci->timeout_secs);
break;
case TCAP_PR_TC_RESULT_L:
rc = tcap_cha_tc_result_req(td, tcci->invoke_id, 1, &tcci->operation, &tcci->parameter.buf,
tcci->parameter.buf);
break;
case TCAP_PR_TC_RESULT_NL:
rc = tcap_cha_tc_result_req(td, tcci->invoke_id, 0, &tcci->operation, tcci->parameter.buf,
tcci->parameter.buf);
break;
default:
fprintf(stderr, "unsupported dialogue primitive %s\n", tcap_prim_name(prim));
return -EINVAL;
}
return rc;
}
/* DIALOGUE primitive received from TC-User */
LIB_EXPORTED int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)
{
@ -299,3 +221,99 @@ LIB_EXPORTED int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg
return rc;
}
/***********************************************************************/
/* Component Primitives */
/***********************************************************************/
static int _tcu_comp_ind(enum tcap_primitive prim, struct tcap_invocation *ti, struct OPERATION *oper,
Parameter_t *param, int last)
{
struct tcap_component_ind tcci;
memset(&tcci, 0, sizeof(tcci));
tcci.dialg_id = ti->dialogue->dialogue_id;
tcci.invoke_id = ti->invoke_id;
if (ti->linked_id) {
tcci._linked_id = ti->_linked_id;
tcci.linked_id = &tcci._linked_id;
}
memcpy(&tcci.operation, oper, sizeof(tcci.operation));
tcci.last_component = last;
return tcap_user_ind_comp(prim, &tcci);
}
/* Table 10 / Q.771 : TC-INVOKE.ind */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last)
{
return _tcu_comp_ind(TCAP_PR_TC_INVOKE, ti, oper, param, last);
}
/* TC-L-REJECT.ind */
int tcap_tcu_tc_l_rej_ind(struct tcap_invocation *ti, int8_t *invoke_id, uint32_t problem)
{
/* FIXME */
}
/* TC-R-REJECT.ind */
int tcap_tcu_tc_r_rej_ind(struct tcap_invocation *ti, int8_t *invoke_id, uint32_t problem,
int last_component)
{
/* FIXME */
}
/* TC-RESULT-L.ind from ISM */
int tcap_tcu_result_l_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last)
{
return _tcu_comp_ind(TCAP_PR_TC_RESULT_L, ti, oper, param, last);
}
int tcap_tcu_result_nl_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last)
{
return _tcu_comp_ind(TCAP_PR_TC_RESULT_NL, ti, oper, param, last);
}
LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
{
struct tcap_dialogue *td;
int rc = 0;
fprintf(stdout, "<- USER_REQ_COMP(%s)\n", tcap_prim_name(prim));
/* Resolve (or allocate) the dialogue/transaction state */
td = tcap_dialg_by_dialg_id(tcci->dialg_id);
if (!td) {
switch (prim) {
case TCAP_PR_TC_INVOKE:
td = tcap_dialg_alloc(tcci->dialg_id);
td->trans.tid_local = tcap_trans_id_alloc();
break;
default:
return -EINVAL;
}
}
/* Actually dispatch the primitive */
switch (prim) {
case TCAP_PR_TC_INVOKE:
rc = tcap_cha_tc_invoke_req(td, tcci->op_class, tcci->invoke_id, tcci->linked_id, &tcci->operation,
tcci->parameter.buf, tcci->parameter.size, tcci->timeout_secs);
break;
case TCAP_PR_TC_RESULT_L:
rc = tcap_cha_tc_result_req(td, tcci->invoke_id, 1, &tcci->operation, &tcci->parameter.buf,
tcci->parameter.buf);
break;
case TCAP_PR_TC_RESULT_NL:
rc = tcap_cha_tc_result_req(td, tcci->invoke_id, 0, &tcci->operation, tcci->parameter.buf,
tcci->parameter.buf);
break;
default:
fprintf(stderr, "unsupported dialogue primitive %s\n", tcap_prim_name(prim));
return -EINVAL;
}
return rc;
}