From 0b555a70c7195e12a587b01021bec426da6dd4d4 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 17 Jul 2010 13:05:56 +0200 Subject: [PATCH] Move from one component per invocation to a per-dialogue component list --- src/csl_cha_cco.c | 25 +++++++++++++++------ src/csl_dha.c | 57 +++++++++++++++++++++++------------------------ src/dialogue.c | 1 + src/tcap.h | 12 ++++++++-- 4 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/csl_cha_cco.c b/src/csl_cha_cco.c index b4d501e..ebaf7d1 100644 --- a/src/csl_cha_cco.c +++ b/src/csl_cha_cco.c @@ -57,6 +57,7 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in { /* allocate new Invocation State Machine, link it with dialogue */ struct tcap_invocation *ti = tcap_ism_alloc(td, inv_id); + struct tcap_component *tcomp; struct Component *comp; struct Invoke *inv; @@ -73,7 +74,10 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in ti->op_class = op_class; /* Allocate a new component structure */ - comp = talloc_zero(ti, struct Component); + tcomp = talloc_zero(td, struct tcap_component); + if (!tcomp) + return -ENOMEM; + comp = &tcomp->comp; comp->present = Component_PR_invoke; /* Assemble INV component */ @@ -86,10 +90,10 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in } memcpy(&inv->opCode, op, sizeof(inv->opCode)); if (param && param_len) - inv->parameter = gen_param(comp, param, param_len); + inv->parameter = gen_param(tcomp, param, param_len); /* Make component available for this Dialogue ID */ - ti->comp = comp; + llist_add_tail(&tcomp->list, &td->pend_comp_list); return 0; } @@ -116,15 +120,19 @@ int tcap_cha_tc_result_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_lookup(td, inv_id); + struct tcap_component *tcomp; struct Component *comp; struct ReturnResult *res; struct resultretres *retres; if (!ti) - return -EINVAL; + return -ENOENT; /* Allocate a new component structure */ - comp = talloc_zero(ti, struct Component); + tcomp = talloc_zero(ti, struct tcap_component); + if (!tcomp) + return -ENOMEM; + comp = &tcomp->comp; /* Assemble requested component */ if (last) { @@ -139,9 +147,12 @@ int tcap_cha_tc_result_req(struct tcap_dialogue *td, int8_t inv_id, int last, res->resultretres = retres; memcpy(&retres->opCode, op, sizeof(retres->opCode)); if (param && param_len) - retres->parameter = gen_param(comp, param, param_len); + retres->parameter = gen_param(tcomp, param, param_len); - /* FIXME: Mark component available for this dialogue ID */ + /* Mark component available for this dialogue ID */ + llist_add_tail(&tcomp->list, &td->pend_comp_list); + + return 0; } /* TC-U-ERROR request TCL -> CHA */ diff --git a/src/csl_dha.c b/src/csl_dha.c index db7d60e..6a10e47 100644 --- a/src/csl_dha.c +++ b/src/csl_dha.c @@ -23,6 +23,22 @@ static BIT_STRING_t dial_version1 = { .bits_unused = 7, }; +static ComponentPortion_t *assemble_components(ComponentPortion_t *cp, struct tcap_dialogue *td) +{ + struct tcap_component *tcomp; + unsigned int comp_count = 0; + + memset(cp, 0, sizeof(*cp)); + llist_for_each_entry(tcomp, &td->pend_comp_list, list) { + ASN_SEQUENCE_ADD(&cp->list, &tcomp->comp); + comp_count++; + } + if (comp_count) + return cp; + + return NULL; +} + /* TC-UNI.req from TCU */ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info) { @@ -32,7 +48,7 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, UniDialoguePDU_t dial; ANY_t any; struct tcap_invocation *ti; - uint32_t trans_id, comp_count = 0; + uint32_t trans_id; int rc; if (app_ctx) { @@ -51,22 +67,14 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, memset(&ext, 0, sizeof(ext)); ANY_fromType(&ext.dialog, &asn_DEF_UniDialoguePDU, &dial); + memset(&any, 0, sizeof(any)); ANY_fromType(&any, &asn_DEF_ExternalPDU, &ext); tcm.choice.begin.dialoguePortion = (OCTET_STRING_t *) &any; } /* Request components to CHA */ /* Process components */ - memset(&cp, 0, sizeof(cp)); - llist_for_each_entry(ti, &td->ism_list, list) { - if (!ti->comp) - continue; - - ASN_SEQUENCE_ADD(&cp.list, ti->comp); - comp_count++; - } /* Assemble TSL user data */ - if (comp_count) - tcm.choice.begin.components = &cp; + tcm.choice.begin.components = assemble_components(&cp, td); /* TR-UNI-REQ to TSL */ rc = tcap_tco_tr_uni_req(&td->trans, &tcm); @@ -86,7 +94,7 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx DialoguePDU_t dial; ANY_t any; struct tcap_invocation *ti; - uint32_t trans_id, comp_count = 0; + uint32_t trans_id; int rc; memset(&tcm, 0, sizeof(tcm)); @@ -111,22 +119,14 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx memset(&ext, 0, sizeof(ext)); ANY_fromType(&ext.dialog, &asn_DEF_DialoguePDU, &dial); + memset(&any, 0, sizeof(any)); ANY_fromType(&any, &asn_DEF_ExternalPDU, &ext); tcm.choice.begin.dialoguePortion = (OCTET_STRING_t *) &any; } /* Request components to CHA */ /* Process components */ - memset(&cp, 0, sizeof(cp)); - llist_for_each_entry(ti, &td->ism_list, list) { - if (!ti->comp) - continue; - - ASN_SEQUENCE_ADD(&cp.list, ti->comp); - comp_count++; - } /* Assemble TSL user data */ - if (comp_count) - tcm.choice.begin.components = &cp; + tcm.choice.begin.components = assemble_components(&cp, td); /* Assign local transaction ID */ trans_id = ntohl(td->trans.tid_local); @@ -236,7 +236,7 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, ExternalPDU_t ext; DialoguePDU_t dial; ANY_t any; - uint32_t trans_id, comp_count = 0; + uint32_t trans_id; int rc = 0; memset(&tcm, 0, sizeof(tcm)); @@ -257,12 +257,10 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, fprintf(stderr, "TC-CONTNUE.req in invalid state\n"); return -EINVAL; } - /* FIXME: Request components to CHA */ - /* FIXME: Process components */ - + /* Request components to CHA */ + /* Process components */ /* Assemble TSL user data */ - if (comp_count) - tcm.choice.Continue.components = &cp; + tcm.choice.Continue.components = assemble_components(&cp, td); /* TR-CONTINUE to TSL */ rc = tcap_tco_tr_continue_req(&td->trans, &tcm); @@ -280,7 +278,7 @@ int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, ExternalPDU_t ext; DialoguePDU_t dial; ANY_t any; - uint32_t trans_id, comp_count = 0; + uint32_t trans_id; int rc = 0; memset(&tcm, 0, sizeof(tcm)); @@ -318,6 +316,7 @@ int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, /* Request component to CHA */ /* Process components */ /* Assemble TLS user data */ + tcm.choice.end.components = assemble_components(&cp, td); /* TR-END.req to TSL */ rc = tcap_tco_tr_end_req(&td->trans, &tcm); /* Dialogue terminated to CHA */ diff --git a/src/dialogue.c b/src/dialogue.c index 9eb31af..9d18979 100644 --- a/src/dialogue.c +++ b/src/dialogue.c @@ -44,6 +44,7 @@ struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id) td->trans.tid_local = tcap_trans_id_alloc(); llist_add(&td->list, &tcap_dialogues); INIT_LLIST_HEAD(&td->ism_list); + INIT_LLIST_HEAD(&td->pend_comp_list); return td; } diff --git a/src/tcap.h b/src/tcap.h index 20d259e..58c57d9 100644 --- a/src/tcap.h +++ b/src/tcap.h @@ -12,6 +12,13 @@ #include #include + +struct tcap_component { + struct llist_head list; + + struct Component comp; /* Invoke Component */ +}; + enum tcap_transaction_state { TCAP_TS_INVALID, TCAP_TS_IDLE, @@ -38,6 +45,9 @@ struct tcap_dialogue { /* private list of ISMs / Invocations in this dialogue */ struct llist_head ism_list; + /* list of pending components for this dialogue */ + struct llist_head pend_comp_list; + /* There is a 1:1 mapping of transactions to dialogues */ struct tcap_transaction trans; @@ -77,8 +87,6 @@ struct tcap_invocation { uint32_t rej_timeout; /* Seconds */ struct timer_list inv_timer; /* Invoke Timer */ struct timer_list rej_timer; /* Reject Timer */ - - struct Component *comp; /* Invoke Component */ };