Add small test program for testing/debugging the TCAP library
This commit is contained in:
parent
39e8a8625e
commit
deff1dd9da
|
@ -21,3 +21,4 @@ missing
|
|||
.deps
|
||||
.libs
|
||||
.version
|
||||
src/tcap_test
|
||||
|
|
|
@ -5,7 +5,7 @@ LIBVERSION=0:0:0
|
|||
|
||||
INCLUDES = $(all_includes) -I/usr/local/include/asn1c -I$(top_srcdir)/include
|
||||
AM_CFLAGS = -fPIC -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOASN1TCAP_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LDFLAGS) $(LIBOSMOASN1TCAP_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOASN1TCAP_LIBS)
|
||||
|
||||
libosmo_tcap_la_SOURCES = \
|
||||
csl_cha_cco.c \
|
||||
|
@ -17,4 +17,9 @@ libosmo_tcap_la_SOURCES = \
|
|||
tsl_tco.c \
|
||||
tsl_tsm.c
|
||||
|
||||
tcap_test_SOURCES = tcap_test.c
|
||||
tcap_test_LDADD = -losmo-tcap -losmo-asn1-tcap -lm
|
||||
|
||||
lib_LTLIBRARIES=libosmo-tcap.la
|
||||
|
||||
bin_PROGRAMS = tcap_test
|
||||
|
|
|
@ -42,7 +42,7 @@ int tcap_csl_tc_uni_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx,
|
|||
/* 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)
|
||||
{
|
||||
struct TCMessage *tcm;
|
||||
struct TCMessage tcm;
|
||||
struct ComponentPortion cp;
|
||||
ExternalPDU_t ext;
|
||||
DialoguePDU_t *dial = NULL;
|
||||
|
@ -50,6 +50,9 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
uint32_t trans_id, comp_count = 0;
|
||||
int rc;
|
||||
|
||||
memset(&tcm, 0, sizeof(tcm));
|
||||
tcm.present = TCMessage_PR_begin;
|
||||
|
||||
if (app_ctx) {
|
||||
AARQ_apdu_t *aarq;
|
||||
|
||||
|
@ -68,7 +71,7 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
fprintf(stdout, "\nDialogue portion:\n");
|
||||
xer_fprint(stdout, &asn_DEF_DialoguePDU, dial);
|
||||
ANY_fromType(&ext.dialog, &asn_DEF_DialoguePDU, dial);
|
||||
tcm->choice.begin.dialoguePortion = ANY_new_fromType(&asn_DEF_ExternalPDU, &ext);
|
||||
tcm.choice.begin.dialoguePortion = ANY_new_fromType(&asn_DEF_ExternalPDU, &ext);
|
||||
}
|
||||
/* Request components to CHA */
|
||||
/* Process components */
|
||||
|
@ -82,15 +85,15 @@ int tcap_csl_tc_begin_req(struct tcap_dialogue *td, OBJECT_IDENTIFIER_t *app_ctx
|
|||
}
|
||||
/* Assemble TSL user data */
|
||||
if (comp_count)
|
||||
tcm->choice.begin.components = &cp;
|
||||
tcm.choice.begin.components = &cp;
|
||||
|
||||
/* Assign local transaction ID */
|
||||
trans_id = td->trans.tid_local;
|
||||
OCTET_STRING_fromBuf(&tcm->choice.begin.otid,
|
||||
OCTET_STRING_fromBuf(&tcm.choice.begin.otid,
|
||||
(const char *) &trans_id, sizeof(trans_id));
|
||||
|
||||
/* TR-BEGIN-REQ to TSL */
|
||||
rc = tcap_tco_tr_begin_req(&td->trans, tcm, NULL);
|
||||
rc = tcap_tco_tr_begin_req(&td->trans, &tcm, NULL);
|
||||
|
||||
td->trans.state = TCAP_TS_INIT_SENT;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id)
|
|||
return NULL;
|
||||
|
||||
td->dialogue_id = dialogue_id;
|
||||
td->trans.state = TCAP_TS_IDLE;
|
||||
llist_add(&td->list, &tcap_dialogues);
|
||||
INIT_LLIST_HEAD(&td->ism_list);
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tcap_user.h"
|
||||
|
||||
int tcap_user_ind_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)
|
||||
{
|
||||
printf("-> USER_IND_DIALG(%s)\n", tcap_prim_name(prim));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tcap_user_ind_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
|
||||
{
|
||||
printf("-> USER_IND_COMP(%s)\n", tcap_prim_name(prim));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tcap_gen_oper_local(struct OPERATION *op, uint32_t local_value)
|
||||
{
|
||||
op->present = OPERATION_PR_localValue;
|
||||
asn_long2INTEGER(&op->choice.localValue, local_value);
|
||||
}
|
||||
|
||||
static int send_invoke(int8_t invoke_id)
|
||||
{
|
||||
struct tcap_component_ind tcci;
|
||||
|
||||
memset(&tcci, 0, sizeof(tcci));
|
||||
tcci.dialg_id = 1234;
|
||||
tcci.invoke_id = invoke_id;
|
||||
tcci.linked_id = NULL;
|
||||
tcap_gen_oper_local(&tcci.operation, 1);
|
||||
tcci.timeout_secs = 10;
|
||||
tcci.op_class = 1;
|
||||
|
||||
return tcap_user_req_comp(TCAP_PR_TC_INVOKE, &tcci);
|
||||
}
|
||||
|
||||
static int send_begin(void)
|
||||
{
|
||||
struct tcap_dialg_ind tcdi;
|
||||
|
||||
memset(&tcdi, 0, sizeof(tcdi));
|
||||
tcdi.dialg_id = 1234;
|
||||
|
||||
return tcap_user_req_dialg(TCAP_PR_TC_BEGIN, &tcdi);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
send_invoke(0);
|
||||
send_invoke(1);
|
||||
send_invoke(-1);
|
||||
send_begin();
|
||||
}
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <asn1c/OBJECT_IDENTIFIER.h>
|
||||
#include <osmocom/tcap/Parameter.h>
|
||||
#include <osmocom/tcap/OPERATION.h>
|
||||
|
||||
/* Call-back to user from other points in the stack */
|
||||
|
||||
/* metadata associated with a dialogue indication primitive */
|
||||
|
@ -10,7 +14,7 @@ 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 OBJECT_IDENTIFIER *app_ctx_name;
|
||||
struct user_information *user_info;
|
||||
int components_present;
|
||||
uint32_t reason;
|
||||
|
@ -54,6 +58,8 @@ enum tcap_primitive {
|
|||
TCAP_PR_TC_P_ABORT,
|
||||
};
|
||||
|
||||
const char *tcap_prim_name(enum tcap_primitive prim);
|
||||
|
||||
|
||||
/* callbacks to application code regarding various INDICATIONs */
|
||||
extern int tcap_user_ind_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci);
|
||||
|
|
70
src/tcu.c
70
src/tcu.c
|
@ -4,12 +4,39 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/utils.h>
|
||||
|
||||
#include <osmocom/tcap/Parameter.h>
|
||||
|
||||
#include "tcap.h"
|
||||
#include "tcap_user.h"
|
||||
|
||||
static const struct value_string tcap_prim_names[] = {
|
||||
/* dialogue handling */
|
||||
{ TCAP_PR_TC_UNI, "TC-UNI" },
|
||||
{ TCAP_PR_TC_BEGIN, "TC-BEGIN" },
|
||||
{ TCAP_PR_TC_CONTINUE, "TC-CONTINUE" },
|
||||
{ TCAP_PR_TC_END, "TC-END" },
|
||||
{ TCAP_PR_TC_U_ABORT, "TC-U-ABORT" },
|
||||
{ TCAP_PR_TC_NOTICE, "TC-NOTICE" },
|
||||
/* component handling */
|
||||
{ TCAP_PR_TC_INVOKE, "TC-INVOKE" },
|
||||
{ TCAP_PR_TC_RESULT_L, "TC-RESULT-L" },
|
||||
{ TCAP_PR_TC_RESULT_NL, "TC-RESULT-NL" },
|
||||
{ TCAP_PR_TC_U_ERROR, "TC-U-ERROR" },
|
||||
{ TCAP_PR_TC_U_REJECT, "TC-U-REJECT" },
|
||||
{ TCAP_PR_TC_CANCEL, "TC-CANCEL" },
|
||||
{ TCAP_PR_TC_L_REJECT, "TC-L-REJECT" },
|
||||
{ TCAP_PR_TC_R_REJECT, "TC-R-REJECT" },
|
||||
{ TCAP_PR_TC_P_ABORT, "TC-P-ABORT" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -111,7 +138,9 @@ int tcap_tcu_result_nl_ind()
|
|||
int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
|
||||
{
|
||||
struct tcap_dialogue *td;
|
||||
int rc = 0;
|
||||
|
||||
/* Resolve (or allocate) the dialogue/transaction state */
|
||||
td = tcap_dialg_by_dialg_id(tcci->dialg_id);
|
||||
if (!td) {
|
||||
switch (prim) {
|
||||
|
@ -122,9 +151,46 @@ int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 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);
|
||||
|
||||
/* 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;
|
||||
default:
|
||||
fprintf(stderr, "unsupported dialogue primitive %s\n", tcap_prim_name(prim));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)
|
||||
{
|
||||
struct tcap_dialogue *td;
|
||||
int rc = 0;
|
||||
|
||||
/* Resolve (or allocate) the dialogue/transaction state */
|
||||
td = tcap_dialg_by_dialg_id(tcdi->dialg_id);
|
||||
if (!td) {
|
||||
switch (prim) {
|
||||
case TCAP_PR_TC_BEGIN:
|
||||
td = tcap_dialg_alloc(tcdi->dialg_id);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (prim) {
|
||||
case TCAP_PR_TC_BEGIN:
|
||||
rc = tcap_csl_tc_begin_req(td, tcdi->app_ctx_name, tcdi->user_info);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unsupported component primitive %s\n", tcap_prim_name(prim));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue