some more tcap progress, mostly on the TC-USER API side

This commit is contained in:
Harald Welte 2010-07-13 11:29:19 +02:00
parent a1d37b0441
commit e00f62a3a1
5 changed files with 264 additions and 43 deletions

View File

@ -1,6 +1,11 @@
/* ITU-T Q.77x TCAP / CCO - Component CoOrdinator
* part of CHA (ComponentHAndling), part of CSL (Component Sub-Layer) */
#include <osmocore/talloc.h>
#include <osmcoore/msgb.h>
#include "tcap.h"
int tcap_tc_invoke_req(uint32_t dialogue_id, uint8_t op_class, int8_t inv_id,
int8_t *linked_id, struct OPERATION *op,
uint8_t *param, uint32_t param_len, uint32_t timeout)
@ -21,6 +26,7 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
int8_t *linked_id, struct OPERATION *op,
uint8_t *param, uint32_t param_len, uint32_t timeout)
{
/* allocate new Invocation State Machine, link it with dialogue */
struct tcap_invocation *ti = tcap_ism_alloc(td, inv_id);
struct Component *comp;
struct Invoke *inv;
@ -49,11 +55,19 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
inv->opCode = op;
if (param && param_len) {
Parameter_t *p = talloc_zero(inv, Parameter_t)
p->buf = param;
uint8_t *_param;
/* make our local copy of the parameter data */
param = talloc_size(p, param_len);
memcpy(_param, param, param_len);
/* initialize Parameter structure and link it with invocation */
p->buf = _param;
p->size = param_len;
inv->parameter = p;
}
/* FIXME: Make component available for this Dialogue ID */
/* Make component available for this Dialogue ID */
ti->inv = inv;
return 0;
}
@ -148,7 +162,8 @@ int tcap_cha_proc_components(struct ComponentPortion *comp_por)
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;
/* TC-INVOKE.ind (TCU <- CHA) */
rc = tcap_tcu_tc_invoke_ind(ti, oper, params);
break;

View File

@ -1,6 +1,11 @@
/* ITU-T Q.77x TCAP / ISM - Invocation State Machine,
* part of CHA (ComponentHAndling), part of CSL (Component Sub-Layer) */
#include <osmocore/talloc.h>
#include <osmocore/msgb.h>
#include "tcap.h"
struct tcap_invocation *tcap_ism_lookup(struct tcap_dialogue *td, int8_t invoke_id)
{
struct tcap_invocation *ti;
@ -26,6 +31,49 @@ struct tcap_invocation *tcap_ism_alloc(struct tcap_dialogue *td, int8_t invoke_i
return ti;
}
void tcap_ism_free(struct tcap_invocation *ti)
{
llist_del(&ti->list);
talloc_free(ti);
}
/* Invocation timer expiry */
static int tcap_ism_inv_timer_exp(void *_ti)
{
struct tcap_invocation *ti = _ti;
switch (ti->state) {
case TCAP_IS_OP_SENT_CL1:
case TCAP_IS_OP_SENT_CL2:
case TCAP_IS_OP_SENT_CL3:
case TCAP_IS_OP_SENT_CL4:
/* TC-L-CANCEL.ind (TCU <- CHA) */
ti->state = TI_IS_INVALID;
llist_del(&ti->list);
talloc_free(ti);
break;
default:
return -EINVAL;
}
return 0;
}
/* Reject timer expiry */
static int tcap_ism_rej_timer_exp(void *_ti)
{
struct tcap_invocation *ti = _ti;
if (state != TCAP_IS_WAIT_REJECT)
return -EINVAL;
ti->state = TI_IS_INVALID;
llist_del(&ti->list);
talloc_free(ti);
return 0;
}
/* Operation sent (CCO -> ISM) */
int tcap_ism_op_sent(struct tcap_invocation *ti, uint8_t op_class)
{
@ -55,10 +103,13 @@ 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 rc = 0;
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();
/* Stop invocation timer */
bsc_del_timer(&ti->inv_timer);
/* Start reject timer */
@ -111,10 +162,13 @@ int tcap_ism_re_recv(struct tcap_invocation *ti)
/* RR-NL received (CCO -> ISM) */
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti)
{
int rc = 0;
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();
/* stay in SENT_CL1 state */
break;
case TCAP_IS_OP_SENT_CL2:
@ -131,7 +185,7 @@ int tcap_ism_rr_nl_recv(struct tcap_invocation *ti)
return -EINVAL;
}
return 0;
return rc;
}
/* Terminate (CCO -> ISM) */
@ -158,39 +212,4 @@ int tcap_ism_terminate(struct tcap_invocation *ti)
return 0;
}
/* Invocation timer expiry */
static int tcap_ism_inv_timer_exp(void *_ti)
{
struct tcap_invocation *ti = _ti;
switch (ti->state) {
case TCAP_IS_OP_SENT_CL1:
case TCAP_IS_OP_SENT_CL2:
case TCAP_IS_OP_SENT_CL3:
case TCAP_IS_OP_SENT_CL4:
/* TC-L-CANCEL.ind (TCU <- CHA) */
ti->state = TI_IS_INVALID;
llist_del(&ti->list);
talloc_free(ti);
break;
default:
return -EINVAL;
}
return 0;
}
/* Reject timer expiry */
static int tcap_ism_rej_timer_exp(void *_ti)
{
struct tcap_invocation *ti = _ti;
if (state != TCAP_IS_WAIT_REJECT)
return -EINVAL;
ti->state = TI_IS_INVALID;
llist_del(&ti->list);
talloc_free(ti);
return 0;
}

View File

@ -1,7 +1,12 @@
/* ITU-T Q.77x TCAP / CSL - Component Sub-Layer */
#include <osmocore/talloc.h>
#include <osmocore/msgb.h>
#include <asn1c/OBJECT_IDENTIFIER.h>
#include "tcap.h"
static uint8_t _dial_version1 = 0x80;
static BIT_STRING_t dial_version1 = {
.buf = &_dial_version1,

View File

@ -53,7 +53,7 @@ struct tcap_invocation {
struct tcap_dialogue *dialogue;
int8_t invoke_id;
int8_t linked_id;
int16_t linked_id;
uint8_t op_class;
struct tcap_invocation_state state;
@ -65,4 +65,88 @@ struct tcap_invocation {
};
/* CSL CHA ISM (Invocation State Machine) */
struct tcap_invocation *tcap_ism_lookup(struct tcap_dialogue *td, int8_t invoke_id);
struct tcap_invocation *tcap_ism_alloc(struct tcap_dialogue *td, int8_t invoke_id);
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);
/* RR-L received (CCO -> ISM) */
int tcap_ism_rr_l_recv(struct tcap_invocation *ti);
/* RE received (CCO -> ISM) */
int tcap_ism_re_recv(struct tcap_invocation *ti);
/* RR-NL received (CCO -> ISM) */
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti);
/* Terminate (CCO -> ISM) */
int tcap_ism_terminate(struct tcap_invocation *ti);
/* CSL CHA CCO (Component Coordinator) */
/* TC-INVOKE.req (TCU -> CHA) */
int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t inv_id,
int8_t *linked_id, struct OPERATION *op,
uint8_t *param, uint32_t param_len, uint32_t timeout);
/* Dialogue Terminated (CHA <- DHA) */
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);
/* TC-U-REJECT.req (TCU -> CHA) */
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);
/* Generate REJ component (CCO <- ISM) */
int tcap_cco_gen_rej(struct tcap_invocation *ti);
/* CSL DHA (Dialogue Handling)*/
/* TC-UNI.req from TCU */
int tcap_csl_tc_uni_req(struct tap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info);
/* TC-BEGIN.req from TCU */
int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info);
/* TR-UNI.ind from TSL */
int tcap_csl_tr_uni_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg);
/* TR-BEGIN.ind from TSL(TSM) -> CSL(DHA) */
int tcap_csl_tr_begin_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg);
/* TC-CONTINUE.req from TCU */
int tcap_csl_tc_cont_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info);
/* TC-END.req from TCU */
int tcap_csl_tc_end_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info, int prearranged);
/* TC-U-APORT.req from TCU */
int tcap_csl_tc_u_abort_req(struct tcap_dialogue *td, uint32_t *abrt_reason, OBJECT_IDENTIFIER_t *app_ctx, struct user_information *user_info);
/* TR-END.ind from TSL */
int tcap_csl_tr_end_ind(struct tcap_transaction *tt, struct TCMessage *tcmsg, struct msgb *msg);
/* TR-NOTICE.ind from TSL */
int tcap_csl_tr_notice_ind(struct tcap_transaction *tt);
/* TR-CONTINUE.ind from TSL */
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);
/* TR-P-ABORT.ind from TSL */
int tcap_csl_tr_p_abort_ind(struct tcap_trnasaction *tt);
#endif /* _OSMO_TCAP_H */

104
src/tcu.c
View File

@ -1,11 +1,76 @@
/* TC-User */
#include <osmocore/msgb.h>
#include "tcap.h"
/* Call-back to user from other points in the stack */
/* Table 10 / Q.771 : TC-INVOKE.ind */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, void *oper, void *par)
{
/* metadata associated with a dialogue indication primitive */
struct tcap_dialg_ind {
uint32_t dialg_id;
struct tcap_address *src_addr;
struct tcap_address *dst_addr;
struct OBJECT_IDENTNFIER *app_ctx_name;
struct user_information *user_info;
int components_present;
uint32_t reason;
void *qos;
};
/* metadata associated with a component indication primitive */
struct tcap_component_ind {
uint32_t dialg_id; /* Dialogue ID */
int8_t invoke_id; /* Invoke ID */
int16_t linked_id; /* Linked ID */
struct OPERATION operation; /* Operation Code */
struct Parameter *parameter; /* ANY_t */
int last_component; /* is this the last component in the msg? */
uint32_t error;
};
enum tcap_primitives {
/* dialogue handling primitives */
TCAP_PR_TC_UNI,
TCAP_PR_TC_BEGIN,
TCAP_PR_TC_CONTINUE,
TCAP_PR_TC_END,
TCAP_PR_TC_U_ABORT,
TCAP_PR_TC_NOTICE,
/* component handling primitives */
TCAP_PR_TC_INVOKE,
TCAP_PR_TC_RESULT_L,
TCAP_PR_TC_RESULT_NL,
TCAP_PR_TC_U_ERROR,
TCAP_PR_TC_U_REJECT,
TCAP_PR_TC_CANCEL,
TCAP_PR_TC_TIMER_RESET,
TCAP_PR_TC_L_REJECT,
TCAP_PR_TC_R_REJECT,
TCAP_PR_TC_P_ABORT,
};
struct tcap_indication {
union {
struct tcap_dialg_ind dialg;
struct tcap_component_ind comp;
};
};
/* Table 10 / Q.771 : TC-INVOKE.ind */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, struct Parameter *param)
{
struct tcap_component_ind tcci;
memset(&tcci, 0, sizeof(tcci));
tcci.dialg_id = ti->dialogue->dialogue_id;
tcci.invoke_id = ti->id;
tcci.linked_id = ti->linked_id;
tcci.operation = oper;
tcci.last_component = param;
return tcap_user_ind_comp(TCAP_PR_TC_INVOKE, &tcci);
}
/* TC-L-REJECT.ind */
@ -23,16 +88,49 @@ int tcap_tcu_tc_r_rej_ind(struct tcap_invocation *td, int8_t *invoke_id, uint32_
/* TC-BEGIN.ind from DHA */
int tcap_tcu_begin_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present)
{
struct tcap_dialg_ind tcdi;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = td->dialogue_id;
tcdi.app_ctx_name;
tcdi.user_info;
tcdi.components_present = comp_present;
return tcap_user_ind_dialg(TCAP_PR_TC_BEGIN, &tcdi);
}
/* TC-UNI.ind from DHA */
int tcap_tcu_uni_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present)
{
}
/* TC-CONT.ind from DHA */
int tcap_tcu_cont_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present)
{
struct tcap_dialg_ind tcdi;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = td->dialogue_id;
tcdi.app_ctx_name;
tcdi.user_info;
tcdi.components_present = comp_present;
return tcap_user_ind_dialg(TCAP_PR_TC_CONTINUE, &tcdi);
}
/* TC-END.ind from DHA */
int tcap_tcu_end_ind(struct tcap_dialogue *td, void *app_ctx_name, void *user_info, int comp_present)
{
struct tcap_dialg_ind tcdi;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = td->dialogue_id;
tcdi.app_ctx_name;
tcdi.user_info;
tcdi.components_present = comp_present;
return tcap_user_ind_dialg(TCAP_PR_TC_END, &tcdi);
}
/* TC-ABORT.ind from DHA */