libosmo-tcap/src/tcap.h

273 lines
10 KiB
C

#ifndef _OSMO_TCAP_H
#define _OSMO_TCAP_H
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 by On-Waves
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <osmocore/linuxlist.h>
#include <osmocore/timer.h>
#include <osmocore/msgb.h>
#include <osmocore/select.h>
#include <osmocom/tcap/TCMessage.h>
#include <osmocom/tcap/OPERATION.h>
#include <osmocom/tcap/Reject.h>
#include <osmocom/tcap/ComponentPortion.h>
#include <osmocom/tcap/ABRT-apdu.h>
#if HAVE_VISIBILITY
#define LIB_EXPORTED __attribute__((__visibility__("default")))
#else
#define LIB_EXPORTED
#endif
enum tcap_transaction_state {
TCAP_TS_INVALID,
TCAP_TS_IDLE,
TCAP_TS_INIT_RECV,
TCAP_TS_INIT_SENT,
TCAP_TS_ACTIVE,
};
/* Transaction, part of the dialogue (as there's 1:1 mapping */
struct tcap_transaction {
enum tcap_transaction_state state;
uint32_t tid_local; /* local transaction ID */
uint32_t tid_remote; /* remote transaction ID */
};
struct tcap_dialogue {
/* global list of dialogues */
struct llist_head list;
/* Dialogue ID: Local significance; maps to Transaction IDs */
uint32_t dialogue_id;
unsigned int app_ctx_mode:1;
/* private list of ISMs / Invocations in this dialogue */
struct llist_head ism_list;
/* list of pending components for this dialogue */
struct ComponentPortion *pend_comp;
/* There is a 1:1 mapping of transactions to dialogues */
struct tcap_transaction trans;
/* reference to the SUA+SCTP / SCCP transport layer */
struct tcap_transport_entity *transp_ent;
};
#define dialg_by_trans(tt) container_of(tt, struct tcap_dialogue, trans)
enum tcap_invocation_state {
TCAP_IS_INVALID,
TCAP_IS_IDLE,
TCAP_IS_OP_SENT_CL1,
TCAP_IS_OP_SENT_CL2,
TCAP_IS_OP_SENT_CL3,
TCAP_IS_OP_SENT_CL4,
TCAP_IS_WAIT_REJECT,
};
#define TCAP_INV_LINKED_NONE -1234
struct tcap_invocation {
struct llist_head list;
/* reference to the dialogue we're part of */
struct tcap_dialogue *dialogue;
int8_t invoke_id; /* Invoke ID */
int8_t _linked_id; /* storage for linked_id */
int8_t *linked_id; /* Linked Invoke ID */
uint8_t op_class; /* Operation Class */
enum tcap_invocation_state state;
/* Invocation timer */
uint32_t inv_timeout; /* Seconds */
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;
};
/* 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);
/* RR-L received (CCO -> ISM) */
int tcap_ism_rr_l_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int is_last_comp);
/* RE received (CCO -> ISM) */
int tcap_ism_re_recv(struct tcap_invocation *ti, struct ReturnError *err,
int is_last_comp);
/* RR-NL received (CCO -> ISM) */
int tcap_ism_rr_nl_recv(struct tcap_invocation *ti, struct ReturnResult *res,
int is_last_comp);
/* 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,
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,
ErrorCode_t *err, uint8_t *param,
uint32_t param_len);
/* Dialogue Terminated (CHA <- DHA) */
int tcap_cha_dialg_term(struct tcap_dialogue *td);
/* TC-U-CANCEL.req (TCU -> CHA) */
int tcap_cha_tc_cancel_req(struct tcap_dialogue *td, int8_t inv_id);
/* TC-RESULT-NL / TC-RESULT-L req (TCL -> CHA) */
int tcap_cha_tc_result_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_dialogue *td, int8_t *invoke_id,
enum problem_PR problem, long problem_code);
/* Components (CHA <- DHA) */
int tcap_cha_proc_components(struct tcap_dialogue *td, struct ComponentPortion *comp_por);
/* 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)*/
/* TC-UNI.req from TCU */
int tcap_csl_tc_uni_req(struct tcap_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, 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_n_unitdata_ind(struct tcap_transport_entity *se, struct msgb *msg);
int tcap_tco_n_notice_ind(struct tcap_transport_entity *se);
int tcap_tco_tsm_stopped_ind(struct tcap_transaction *tt);
int tcap_tco_tr_uni_req(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tco_tr_begin_req(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tco_tr_continue_req(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tco_tr_end_req(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tco_tr_u_abort_req(struct tcap_transaction *tt, struct TCMessage *tcmsg);
/* TSL TSM */
int tcap_tsm_begin_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tsm_continue_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tsm_end_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tsm_abort_trans(struct tcap_transaction *tt, struct TCMessage *tcmsg);
int tcap_tsm_begin_rcvd(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 */
uint32_t tcap_dialg_id_alloc(void);
struct tcap_dialogue *tcap_dialg_by_dialg_id(uint32_t dialogue_id);
struct tcap_dialogue *tcap_dialg_alloc(uint32_t dialogue_id);
void tcap_dialg_free(struct tcap_dialogue *td);
struct tcap_transaction *tcap_transaction_alloc(void);
struct tcap_transaction *tcap_transaction_by_remote_tid(uint32_t tid_remote);
struct tcap_transaction *tcap_transaction_by_local_tid(uint32_t tid_local);
const char *tcap_trans_state_name(enum tcap_transaction_state ts);
const char *tcap_inv_state_name(enum tcap_invocation_state is);
void tcap_trans_set_state(struct tcap_transaction *tt, enum tcap_transaction_state st);
/* Add a single component to the list of pending components of this dialogue */
int tcap_dialg_comp_add(struct tcap_dialogue *td, Component_t *comp);
/* scXp.c */
/* Called by TCAP stack if it wants to request transmission of UNITDATA */
int tcap_scXp_n_unitdata_req(struct tcap_transport_entity *se, struct msgb *msg);
/* TCU */
int tcap_tcu_tc_invoke_ind(struct tcap_invocation *ti, struct OPERATION *oper, Parameter_t *param, int last);
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 is_last);
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 */