diff --git a/src/csl_cha_cco.c b/src/csl_cha_cco.c index 9440f41..91d4951 100644 --- a/src/csl_cha_cco.c +++ b/src/csl_cha_cco.c @@ -40,8 +40,10 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in ti->inv_timeout = timeout; - if (linked_id) - ti->linked_id = *linked_id; + if (linked_id) { + ti->_linked_id = *linked_id; + ti->linked_id = &ti->_linked_id; + } ti->op_class = op_class; @@ -52,9 +54,9 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in /* Assemble INV component */ inv = &comp->choice.invoke; inv->invokeID = ti->invoke_id; - if (ti->linked_id != TCAP_INV_LINKED_NONE) { + if (ti->linked_id) { InvokeIdType_t *lid = talloc_zero(inv, InvokeIdType_t); - *lid = ti->linked_id; + *lid = *ti->linked_id; inv->linkedID = lid; } memcpy(&inv->opCode, op, sizeof(inv->opCode)); @@ -98,7 +100,7 @@ int tcap_cha_dialg_term(struct tcap_dialogue *td) 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 tcap_invocation *ti = tcap_ism_lookup(td, inv_id); struct Component *comp; struct ReturnResult *res; struct resultretres *retres; @@ -154,47 +156,51 @@ int tcap_cha_tc_u_rej_req(struct tcap_invocation *ti, enum problem_PR problem) /* Components (CHA <- DHA) */ int tcap_cha_proc_components(struct ComponentPortion *comp_por) { - int rc; + struct tcap_invocation *ti; struct Component *comp; + int rc; /* Iterate over list of components as part of comp_por */ while (components) { /* Extract next component */ /* Check syntax error and proceed with 5, 3 or 4 */ - switch (type) { + switch (comp->present) { case Component_PR_invoke: ti = tcap_ism_alloc(td, comp->choice.invoke.invokeID); if (comp->choice.invoke.linkedID) { /* Linked to ISM not in sent state? Proceed with 6 */ - ti->linked_id = *comp->choice.invoke.linkedID; - } else - ti->linked_id = TCAP_INV_LINKED_NONE; + ti->_linked_id = *comp->choice.invoke.linkedID; + ti->linked_id = &ti->_linked_id; + } /* TC-INVOKE.ind (TCU <- CHA) */ - rc = tcap_tcu_tc_invoke_ind(ti, oper, params); + rc = tcap_tcu_tc_invoke_ind(ti, &comp->choice.invoke.opCode, + comp->choice.invoke.parameter); 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); + rc = tcap_ism_rr_nl_recv(ti, &comp->choice.returnResultNotLast); 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); + rc = tcap_ism_rr_l_recv(ti, &comp->choice.returnResultLast); 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); + rc = tcap_ism_re_recv(ti, &comp->choice.returnError); break; case Component_PR_reject: /* TC-R-REJECT or TC-U-REJECT.ind (TCU <- CHA) */ rc = tcap_tcu_tc_r_rej_ind(ti->dialogue, &ti->invoke_id, problem); break; + case Component_PR_NOTHING: + break; } } } diff --git a/src/dialogue.c b/src/dialogue.c index 05d9905..b4ccb45 100644 --- a/src/dialogue.c +++ b/src/dialogue.c @@ -1,4 +1,8 @@ +#include + +#include "tcap.h" + static LLIST_HEAD(tcap_dialogues); struct tcap_dialogue *tcap_dialg_by_dialg_id(uint32_t dialogue_id) diff --git a/src/scXp.c b/src/scXp.c index aaaeb5a..87cc82b 100644 --- a/src/scXp.c +++ b/src/scXp.c @@ -1,24 +1,5 @@ /* SCCP / SCTP+SUA interface */ -enum scxp_entity_type { - SCXP_T_SCCP, - SCXP_T_SUA_SCTP, -}; - -/* One entity of the underlying network protocol */ -struct scxp_entity { - struct llist_head list; - - enum sccp_entity_type type; - - union { - struct { - } sccp; - struct { - } sua_sctp; - }; -}; - /* Called by TCAP stack if it wants to request transmission of UNITDATA */ int tcap_scXp_n_unitdata_req(struct scxp_entity *se, struct msgb *msg) { diff --git a/src/tcap.h b/src/tcap.h index 3ba8c09..dc277b5 100644 --- a/src/tcap.h +++ b/src/tcap.h @@ -41,7 +41,8 @@ struct tcap_dialogue { /* There is a 1:1 mapping of transactions to dialogues */ struct tcap_transaction trans; - /* FIXME: reference to the SUA+SCTP / SCCP transport layer */ + /* reference to the SUA+SCTP / SCCP transport layer */ + struct scxp_entity *se; }; enum tcap_invocation_state { @@ -88,13 +89,13 @@ 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); +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); +int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *err); /* RR-NL received (CCO -> ISM) */ -int tcap_ism_rr_nl_recv(struct tcap_invocation *ti); +int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res); /* Terminate (CCO -> ISM) */ int tcap_ism_terminate(struct tcap_invocation *ti); @@ -157,9 +158,64 @@ int tcap_csl_tr_notice_ind(struct tcap_transaction *tt); int tcap_csl_tr_continue_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); /* TR-U-ABORT.ind from TSL */ -int tcap_csl_tr_u_abort_ind(struct tcap_transaction *tt); +int tcap_csl_tr_u_abort_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); /* TR-P-ABORT.ind from TSL */ int tcap_csl_tr_p_abort_ind(struct tcap_transaction *tt); + +/* TSL TCO */ +int tcap_tco_tsm_stopped_ind(struct tcap_transaction *tt); + + +/* TSL TSM */ +int tcap_tsm_begin_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_begin_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_continue_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_end_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_abort_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_continue_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_end_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_abort_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg); +int tcap_tsm_local_abort(struct tcap_transaction *tt); + + +/* dialogue.c */ +struct tcap_dialogue *tcap_dialg_by_dialg_id(uint32_t dialogue_id); +struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id); + + +/* scXp.c */ +enum scxp_entity_type { + SCXP_T_SCCP, + SCXP_T_SUA_SCTP, +}; +/* One entity of the underlying network protocol */ +struct scxp_entity { + struct llist_head list; + + enum scxp_entity_type type; + + union { + struct { + } sccp; + struct { + } sua_sctp; + }; +}; +/* Called by TCAP stack if it wants to request transmission of UNITDATA */ +int tcap_scXp_n_unitdata_req(struct scxp_entity *se, struct msgb *msg); + + +/* TCU */ +int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, struct Parameter *param); +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_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); +int tcap_tcu_end_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present); +int tcap_tcu_abort_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info); +int tcap_tcu_notice_ind(struct tcap_dialogue *td, uint32_t cause); + #endif /* _OSMO_TCAP_H */ diff --git a/src/tsl_tco.c b/src/tsl_tco.c index 2002e6b..3e9cdde 100644 --- a/src/tsl_tco.c +++ b/src/tsl_tco.c @@ -1,18 +1,24 @@ /* ITU-T Q.77x TCAP / TCO - Transoaction CoOrdinatior */ +#include +#include + #include #include +#include "tcap.h" + /* N-UNITDATA.ind from SCCP / SUA */ int tcap_tco_n_unitdata_ind(struct scxp_entity *se, struct msgb *msg) { int rc; + asn_dec_rval_t rv; struct TCMessage *tcmsg; struct tcap_transaction *tt; - rc = ber_decode(NULL, &asn_DEF_TCMessage, &tcmsg, buf, len); - if (rc < 0) + rv = ber_decode(NULL, &asn_DEF_TCMessage, (void **) &tcmsg, msg->data, msg->len); + if (rv.code != RC_OK) return rc; switch (tcmsg->present) { diff --git a/src/tsl_tsm.c b/src/tsl_tsm.c index 9104219..0a0316e 100644 --- a/src/tsl_tsm.c +++ b/src/tsl_tsm.c @@ -1,26 +1,31 @@ /* ITU-T Q.77x TCAP / TSM - Transaction State Machine */ +#include +#include + #include #include +#include "tcap.h" + /* BEGIN received from remote (TCO -> TSM) */ int tcap_tsm_begin_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg) { - struct Begin *msg_beg = &tcmsg->choice.begin + struct Begin *msg_beg = &tcmsg->choice.begin; int rc; if (tt->state != TCAP_TS_IDLE) return -EINVAL; /* FIXME: Store remote address and remote TID */ - tt->tid_remote = msg_beg->otid; + memcpy(&tt->tid_remote, msg_beg->otid.buf, sizeof(uint32_t)); /* FIXME: DHA */ /* FIXME: TR-BEGIN.ind to CSL */ rc = tcap_csl_tr_begin_ind(tt, tcmsg, msg); - tt->state = TCPA_TS_INIT_RECV; + tt->state = TCAP_TS_INIT_RECV; return rc; } @@ -28,6 +33,7 @@ int tcap_tsm_begin_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, st /* BEGIN Transaction (TCO -> TSM) */ int tcap_tsm_begin_trans(struct tcap_transaction *tt, struct msgb *msg) { + struct tcap_dialogue *td = dialg_by_trans(tt); int rc; if (tt->state != TCAP_TS_IDLE) @@ -36,7 +42,7 @@ int tcap_tsm_begin_trans(struct tcap_transaction *tt, struct msgb *msg) /* FIXME: Store Local Address */ /* FIXME: Assemble TR-portion of BEGIN message */ /* Send N-UNITDATA.req to SCCP / SUA */ - rc = tcap_scXp_n_unitdata_req(se, msg); + rc = tcap_scXp_n_unitdata_req(td->se, msg); tt->state = TCAP_TS_INIT_SENT; @@ -46,6 +52,7 @@ int tcap_tsm_begin_trans(struct tcap_transaction *tt, struct msgb *msg) /* CONTINUE Transaction (TCO -> TSM) */ int tcap_tsm_continue_trans(struct tcap_transaction *tt, struct msgb *msg) { + struct tcap_dialogue *td = dialg_by_trans(tt); enum tcap_transaction_state new_state; int rc; @@ -63,7 +70,7 @@ int tcap_tsm_continue_trans(struct tcap_transaction *tt, struct msgb *msg) /* FIXME: Assemble TR-portion of CONTINUE message */ /* Send N-UNITDATA.req to SCCP / SUA */ - rc = tcap_scXp_n_unitdata_req(se, msg); + rc = tcap_scXp_n_unitdata_req(td->se, msg); tt->state = new_state; @@ -73,6 +80,7 @@ int tcap_tsm_continue_trans(struct tcap_transaction *tt, struct msgb *msg) /* END transaction (TCO -> TSM) */ int tcap_tsm_end_trans(struct tcap_transaction *tt, struct msgb *msg) { + struct tcap_dialogue *td = dialg_by_trans(tt); int rc; switch (tt->state) { @@ -81,7 +89,7 @@ int tcap_tsm_end_trans(struct tcap_transaction *tt, struct msgb *msg) if (!prearranged) { /* FIXME: Assemble TR-portion of END message */ /* Send N-UNITDATA.req to SCCP / SUA */ - rc = tcap_scXp_n_unitdata_req(se, msg); + rc = tcap_scXp_n_unitdata_req(td->se, msg); } break; case TCAP_TS_INIT_SENT: @@ -101,6 +109,7 @@ int tcap_tsm_end_trans(struct tcap_transaction *tt, struct msgb *msg) /* ABORT transaction (TCO -> TSM) */ int tcap_tsm_abort_trans(struct tcap_transaction *tt, struct msgb *msg) { + struct tcap_dialogue *td = dialg_by_trans(tt); int rc; switch (tt->state) { @@ -108,7 +117,7 @@ int tcap_tsm_abort_trans(struct tcap_transaction *tt, struct msgb *msg) case TCAP_TS_ACTIVE: /* FIXME: Assemble TR-portion of ABORT message */ /* N-UNITDATA.req to SCCP / SUA */ - rc = tcap_scXp_n_unitdata_req(se, msg); + rc = tcap_scXp_n_unitdata_req(td->se, msg); break; case TCAP_TS_INIT_SENT: break; @@ -135,7 +144,7 @@ int tcap_tsm_continue_rcvd(struct tcap_transaction *tt, struct TCMessage *tcmsg, case TCAP_TS_INIT_SENT: /* FIXME: Store remote address */ /* Store remote TID */ - tt->tid_remote = msg_cnt->otid; + memcpy(&tt->tid_remote, msg_cnt->otid.buf, sizeof(uint32_t)); /* fall-through */ case TCAP_TS_ACTIVE: /* TR-CONTINUE.ind to CSL */