introduce a user-specified 'user_ref' that gets passed back in result/error indications

This will allow us to store a reference to e.g. a map operation
at INVOKE time, which we can then de-reference once the RESULT
arrives.
This commit is contained in:
Harald Welte 2010-07-21 15:27:11 +02:00
parent 19070cb104
commit d6f49749dc
5 changed files with 55 additions and 41 deletions

View File

@ -78,7 +78,8 @@ static Parameter_t *gen_param(const void *ctx, uint8_t *param, uint32_t param_le
*/
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)
uint8_t *param, uint32_t param_len, uint32_t timeout,
unsigned long user_ref)
{
/* allocate new Invocation State Machine, link it with dialogue */
struct tcap_invocation *ti = tcap_ism_alloc(td, inv_id);
@ -88,6 +89,7 @@ int tcap_cha_tc_invoke_req(struct tcap_dialogue *td, uint8_t op_class, int8_t in
if (!ti)
return -ENOMEM;
ti->user_ref = user_ref;
ti->inv_timeout = timeout;
if (linked_id) {

View File

@ -108,6 +108,9 @@ struct tcap_invocation {
uint32_t rej_timeout; /* Seconds */
struct timer_list inv_timer; /* Invoke Timer */
struct timer_list rej_timer; /* Reject Timer */
/* user reference */
unsigned long user_ref;
};
@ -141,7 +144,8 @@ int tcap_ism_terminate(struct tcap_invocation *ti);
/* 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);
uint8_t *param, uint32_t param_len, uint32_t timeout,
unsigned long user_ref);
/* TC-U-ERROR request (TCL -> CHA) */
int tcap_cha_tc_u_error_req(struct tcap_dialogue *td, int8_t inv_id,

View File

@ -43,25 +43,25 @@ static struct {
static int send_cont_end(uint32_t dialg_id, struct tcap_obj_ident *app_ctx, struct tcap_user_info *user_info,
int end)
{
struct tcap_dialg_ind tcdi;
enum tcap_primitive prim;
struct tcap_prim_buf tcpb;
struct tcap_dialg_ind *tcdi = &tcpb.dialg;
if (end)
prim = TCAP_PR_TC_END;
tcpb.prim = TCAP_PR_TC_END;
else
prim = TCAP_PR_TC_CONTINUE;
tcpb.prim = TCAP_PR_TC_CONTINUE;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = dialg_id;
memset(&tcpb, 0, sizeof(tcpb));
tcdi->dialg_id = dialg_id;
if (app_ctx) {
memcpy(&tcdi.app_ctx_name, app_ctx, sizeof(tcdi.app_ctx_name));
tcdi.app_ctx_present = 1;
memcpy(&tcdi->app_ctx_name, app_ctx, sizeof(tcdi->app_ctx_name));
tcdi->app_ctx_present = 1;
}
if (user_info) {
memcpy(&tcdi.user_info, user_info, sizeof(tcdi.user_info));
tcdi.user_info_present = 1;
memcpy(&tcdi->user_info, user_info, sizeof(tcdi->user_info));
tcdi->user_info_present = 1;
}
return tcap_user_req_dialg(prim, &tcdi);
return tcap_user_req(&tcpb);
}
/* UpdateGprsLocationArg */
@ -78,37 +78,41 @@ static uint8_t gprs_loc_upd_param[] = {
static int send_comp_req(enum tcap_primitive prim, uint32_t dialg_id,
int8_t invoke_id, uint8_t *param, uint32_t param_len)
{
struct tcap_component_ind tcci;
struct tcap_prim_buf tcpb;
struct tcap_component_ind *tcci = &tcpb.comp;
memset(&tcci, 0, sizeof(tcci));
tcci.dialg_id = dialg_id;
tcci.invoke_id = invoke_id;
tcci.linked_id = NULL;
tcci.operation.local = 1;
tcci.timeout_secs = 10;
tcci.op_class = 1;
memset(&tcpb, 0, sizeof(tcpb));
tcpb.prim = prim;
tcci->dialg_id = dialg_id;
tcci->invoke_id = invoke_id;
tcci->linked_id = NULL;
tcci->operation.local = 1;
tcci->timeout_secs = 10;
tcci->op_class = 1;
if (param_len > sizeof(tcci.parameter.data))
if (param_len > sizeof(tcci->parameter.data))
return -EINVAL;
memcpy(&tcci.parameter.data, param, param_len);
tcci.parameter.data_len = param_len;
memcpy(&tcci->parameter.data, param, param_len);
tcci->parameter.data_len = param_len;
return tcap_user_req_comp(prim, &tcci);
return tcap_user_req(&tcpb);
}
static int send_begin(uint32_t dialg_id, struct tcap_obj_ident *app_ctx)
{
struct tcap_dialg_ind tcdi;
struct tcap_prim_buf tcpb;
struct tcap_dialg_ind *tcdi = &tcpb.dialg;
memset(&tcdi, 0, sizeof(tcdi));
tcdi.dialg_id = dialg_id;
memset(&tcpb, 0, sizeof(tcpb));
tcpb.prim = TCAP_PR_TC_BEGIN;
tcdi->dialg_id = dialg_id;
if (app_ctx) {
memcpy(&tcdi.app_ctx_name, app_ctx, sizeof(tcdi.app_ctx_name));
tcdi.app_ctx_present = 1;
memcpy(&tcdi->app_ctx_name, app_ctx, sizeof(tcdi->app_ctx_name));
tcdi->app_ctx_present = 1;
}
tcdi.transp_ent = test_state.tte;
tcdi->transp_ent = test_state.tte;
return tcap_user_req_dialg(TCAP_PR_TC_BEGIN, &tcdi);
return tcap_user_req(&tcpb);
}
static int tcap_user_ind_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi)

View File

@ -150,6 +150,9 @@ struct tcap_prim_buf {
/* Dummy list head structure for the user. libosmo-tcap doesn't use it */
struct llist_head list;
/* private reference of the caller */
unsigned long user_ref;
/* The actual primitive number */
enum tcap_primitive prim;
union {
@ -167,7 +170,5 @@ const char *tcap_prim_name(enum tcap_primitive prim);
extern int tcap_user_ind_cb(struct tcap_prim_buf *tcpb);
/* application wants to issue a REQUEST type primitive */
extern int tcap_user_req(struct tcap_prim_buf *tcpb);
extern int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci);
extern int tcap_user_req_dialg(enum tcap_primitive prim, struct tcap_dialg_ind *tcdi);
#endif /* TCAP_USER_H */

View File

@ -249,6 +249,7 @@ static int _tcu_comp_ind(enum tcap_primitive prim, struct tcap_invocation *ti, s
tcci->dialg_id = ti->dialogue->dialogue_id;
tcci->invoke_id = ti->invoke_id;
tcpb->user_ref = ti->user_ref;
if (ti->linked_id) {
tcci->_linked_id = ti->_linked_id;
tcci->linked_id = &tcci->_linked_id;
@ -361,19 +362,20 @@ static ErrorCode_t *generate_errcode(struct tcap_dialogue *td, struct tcap_compo
return err;
}
LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_component_ind *tcci)
static int tcap_user_req_comp(struct tcap_prim_buf *tcpb)
{
struct tcap_component_ind *tcci = &tcpb->comp;
struct tcap_dialogue *td;
OPERATION_t *op = NULL;
ErrorCode_t *err = NULL;
int rc = 0;
fprintf(stdout, "<- USER_REQ_COMP(%s)\n", tcap_prim_name(prim));
fprintf(stdout, "<- USER_REQ_COMP(%s)\n", tcap_prim_name(tcpb->prim));
/* Resolve (or allocate) the dialogue/transaction state */
td = tcap_dialg_by_dialg_id(tcci->dialg_id);
if (!td) {
switch (prim) {
switch (tcpb->prim) {
case TCAP_PR_TC_INVOKE:
td = tcap_dialg_alloc(tcci->dialg_id);
break;
@ -383,12 +385,13 @@ LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_compon
}
/* Actually dispatch the primitive */
switch (prim) {
switch (tcpb->prim) {
case TCAP_PR_TC_INVOKE:
op = generate_op(td, tcci);
rc = tcap_cha_tc_invoke_req(td, tcci->op_class, tcci->invoke_id,
tcci->linked_id, op, tcci->parameter.data,
tcci->parameter.data_len, tcci->timeout_secs);
tcci->parameter.data_len, tcci->timeout_secs,
tcpb->user_ref);
break;
case TCAP_PR_TC_RESULT_L:
op = generate_op(td, tcci);
@ -413,7 +416,7 @@ LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_compon
break;
case TCAP_PR_TC_TIMER_RESET:
default:
fprintf(stderr, "unsupported dialogue primitive %s\n", tcap_prim_name(prim));
fprintf(stderr, "unsupported dialogue primitive %s\n", tcap_prim_name(tcpb->prim));
return -EINVAL;
}
@ -427,7 +430,7 @@ LIB_EXPORTED int tcap_user_req_comp(enum tcap_primitive prim, struct tcap_compon
LIB_EXPORTED int tcap_user_req(struct tcap_prim_buf *tcpb)
{
if (tcpb->prim > _TCAP_PR_COMP_BASE)
return tcap_user_req_comp(tcpb->prim, &tcpb->comp);
return tcap_user_req_comp(tcpb);
else
return tcap_user_req_dialg(tcpb->prim, &tcpb->dialg);
}