Properly set ISM state 'sent' while gathering components for new message

This is done by the new tcap_cha_req_components() function.  Also,
we now have a tcap_ism_state_set() function for debugging ISM state
changes
This commit is contained in:
Harald Welte 2010-07-20 10:01:56 +02:00
parent 2e7a6f8cdd
commit 241880bc87
4 changed files with 58 additions and 25 deletions

View File

@ -343,3 +343,28 @@ int tcap_cco_gen_rej(struct tcap_invocation *ti)
/* TC-L-REJ.ind (TCU <- CHA) */
return tcap_tcu_tc_l_rej_ind(ti, &ti->invoke_id, 0 /* FIXME problem */);
}
/* Return list of pending components for given dialogue */
ComponentPortion_t *tcap_cha_req_components(struct tcap_dialogue *td)
{
ComponentPortion_t *cp = td->pend_comp;
Component_t *comp;
struct tcap_invocation *ti;
unsigned int i;
/* iterate over list of components, find INV components and call
* tcap_ism_op_sent() */
for (i = 0; i < cp->list.count; i++) {
comp = cp->list.array[i];
if (comp->present != Component_PR_invoke)
continue;
ti = tcap_ism_lookup(td, comp->choice.invoke.invokeID);
if (!ti)
continue;
tcap_ism_op_sent(ti);
}
td->pend_comp = NULL;
return cp;
}

View File

@ -28,6 +28,13 @@
#include "tcap.h"
static void tcap_ism_set_state(struct tcap_invocation *ti, enum tcap_invocation_state st)
{
printf("Invocation %d old_state=%s, new_state=%s\n", ti->invoke_id,
tcap_inv_state_name(ti->state), tcap_inv_state_name(st));
ti->state = st;
}
struct tcap_invocation *tcap_ism_lookup(struct tcap_dialogue *td, int8_t invoke_id)
{
struct tcap_invocation *ti;
@ -46,7 +53,7 @@ struct tcap_invocation *tcap_ism_alloc(struct tcap_dialogue *td, int8_t invoke_i
ti->invoke_id = invoke_id;
ti->linked_id = NULL;
ti->dialogue = td;
ti->state = TCAP_IS_IDLE;
tcap_ism_set_state(ti, TCAP_IS_IDLE);
llist_add_tail(&ti->list, &td->ism_list);
@ -72,7 +79,7 @@ static void tcap_ism_inv_timer_exp(void *_ti)
case TCAP_IS_OP_SENT_CL3:
case TCAP_IS_OP_SENT_CL4:
/* TC-L-CANCEL.ind (TCU <- CHA) */
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
break;
default:
@ -90,30 +97,30 @@ static void tcap_ism_rej_timer_exp(void *_ti)
if (ti->state != TCAP_IS_WAIT_REJECT)
return;
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
}
/* Operation sent (CCO -> ISM) */
int tcap_ism_op_sent(struct tcap_invocation *ti, uint8_t op_class)
int tcap_ism_op_sent(struct tcap_invocation *ti)
{
/* Start invocation timer */
ti->inv_timer.cb = tcap_ism_inv_timer_exp;
ti->inv_timer.data = ti;
bsc_schedule_timer(&ti->inv_timer, ti->inv_timeout, 0);
switch (op_class) {
switch (ti->op_class) {
case 1:
ti->state = TCAP_IS_OP_SENT_CL1;
tcap_ism_set_state(ti, TCAP_IS_OP_SENT_CL1);
break;
case 2:
ti->state = TCAP_IS_OP_SENT_CL2;
tcap_ism_set_state(ti, TCAP_IS_OP_SENT_CL2);
break;
case 3:
ti->state = TCAP_IS_OP_SENT_CL3;
tcap_ism_set_state(ti, TCAP_IS_OP_SENT_CL3);
break;
case 4:
ti->state = TCAP_IS_OP_SENT_CL4;
tcap_ism_set_state(ti, TCAP_IS_OP_SENT_CL4);
break;
default:
return -EINVAL;
@ -144,7 +151,7 @@ int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
ti->rej_timer.cb = tcap_ism_rej_timer_exp;
ti->rej_timer.data = ti;
bsc_schedule_timer(&ti->rej_timer, ti->rej_timeout, 0);
ti->state = TCAP_IS_WAIT_REJECT;
tcap_ism_set_state(ti, TCAP_IS_WAIT_REJECT);
break;
case TCAP_IS_OP_SENT_CL2:
case TCAP_IS_OP_SENT_CL4:
@ -152,7 +159,7 @@ int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
rc = tcap_cco_gen_rej(ti);
/* Stop invocation timer */
bsc_del_timer(&ti->inv_timer);
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
break;
}
@ -172,11 +179,11 @@ int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *re,
ti->rej_timer.cb = tcap_ism_rej_timer_exp;
ti->rej_timer.data = ti;
bsc_schedule_timer(&ti->rej_timer, ti->rej_timeout, 0);
ti->state = TCAP_IS_WAIT_REJECT;
tcap_ism_set_state(ti, TCAP_IS_WAIT_REJECT);
break;
case TCAP_IS_OP_SENT_CL3:
case TCAP_IS_OP_SENT_CL4:
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
break;
default:
@ -212,7 +219,7 @@ int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res,
rc = tcap_cco_gen_rej(ti);
/* Stop invocation timer */
bsc_del_timer(&ti->inv_timer);
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
break;
default:
@ -239,7 +246,7 @@ int tcap_ism_terminate(struct tcap_invocation *ti)
/* Stop invoation timer */
bsc_del_timer(&ti->inv_timer);
ti->state = TCAP_IS_INVALID;
tcap_ism_set_state(ti, TCAP_IS_INVALID);
tcap_ism_free(ti);
return 0;

View File

@ -77,6 +77,7 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
ExternalPDU_t *ext;
UniDialoguePDU_t *dial;
ANY_t *any;
ComponentPortion_t *pend_comp;
int rc;
tcm = talloc_zero(td, struct TCMessage);
@ -105,11 +106,11 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
tcm->choice.unidirectional.dialoguePortion = (OCTET_STRING_t *) any;
}
/* Request components to CHA */
pend_comp = tcap_cha_req_components(td);
/* Process components */
memcpy(&tcm->choice.unidirectional.components, pend_comp, sizeof(*pend_comp));
talloc_free(pend_comp);
/* Assemble TSL user data */
memcpy(&tcm->choice.unidirectional.components, td->pend_comp, sizeof(*td->pend_comp));
talloc_free(td->pend_comp);
td->pend_comp = NULL;
/* TR-UNI-REQ to TSL */
rc = tcap_tco_tr_uni_req(&td->trans, tcm);
@ -166,8 +167,7 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
/* Request components to CHA */
/* Process components */
/* Assemble TSL user data */
tcm->choice.begin.components = td->pend_comp;
td->pend_comp = NULL;
tcm->choice.begin.components = tcap_cha_req_components(td);
/* Assign local transaction ID */
trans_id = ntohl(td->trans.tid_local);
@ -334,6 +334,7 @@ static ANY_t *gen_ext_AARE(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ct
asn_long2INTEGER(&aare->result_source_diagnostic.choice.dialogue_service_user,
dialogue_service_user_no_reason_given);
/* Link Dialogue into External PDU */
printf("calling ANY_fromType(%p, %p, %p)\n", &ext->dialog, &asn_DEF_DialoguePDU, dial);
rc = ANY_fromType((ANY_t *) &ext->dialog, &asn_DEF_DialoguePDU, dial);
if (rc < 0) {
fprintf(stderr, "Error generating ExternalPDU from DialoguePDU\n");
@ -380,8 +381,7 @@ int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
/* Request components to CHA */
/* Process components */
/* Assemble TSL user data */
tcm.choice.Continue.components = td->pend_comp;
td->pend_comp = NULL;
tcm.choice.Continue.components = tcap_cha_req_components(td);
/* Assign local transaction ID */
trans_id = htonl(td->trans.tid_local);
@ -447,8 +447,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 = td->pend_comp;
td->pend_comp = NULL;
tcm.choice.end.components = tcap_cha_req_components(td);
/* TR-END.req to TSL */
rc = tcap_tco_tr_end_req(&td->trans, &tcm);
/* Dialogue terminated to CHA */

View File

@ -118,7 +118,7 @@ struct tcap_invocation *tcap_ism_alloc(struct tcap_dialogue *td, int8_t invoke_i
void tcap_ism_free(struct tcap_invocation *ti);
/* Operation sent (CCO -> ISM) */
int tcap_ism_op_sent(struct tcap_invocation *ti, uint8_t op_class);
int tcap_ism_op_sent(struct tcap_invocation *ti);
/* RR-L received (CCO -> ISM) */
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
@ -168,6 +168,8 @@ int tcap_cha_proc_components(struct tcap_dialogue *td, struct ComponentPortion *
/* Generate REJ component (CCO <- ISM) */
int tcap_cco_gen_rej(struct tcap_invocation *ti);
/* Return list of pending components for given dialogue */
ComponentPortion_t *tcap_cha_req_components(struct tcap_dialogue *td);
/* CSL DHA (Dialogue Handling)*/