OpenSS7 SS7 for the Common Man |
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
||||||||||||||||||||||||||
Home | Overview | Status | News | Documentation | Resources | About | |||||||||||||||||||||
File /code/strss7/drivers/sigtran/tua.c#ident "@(#) $RCSfile: tua.c,v $ $Name: $($Revision: 0.8.2.4 $) $Date: 2003/04/14 12:13:19 $" static char const ident[] = "$RCSfile: tua.c,v $ $Name: $($Revision: 0.8.2.4 $) $Date: 2003/04/14 12:13:19 $"; #include <linux/config.h> #include <linux/version.h> #ifdef MODVERSIONS #include <linux/modversions.h> #endif #include <linux/module.h> #include <sys/stream.h> #include <sys/stropts.h> #include <sys/cmn_err.h> #include <sys/dki.h> #include "../debug.h" #include "../bufq.h" #define TUA_DESCRIP "SIGTRAN TUA STREAMS MULTIPLEXING DRIVER." #define TUA_COPYRIGHT "Copyright (c) 1997-2002 OpenSS7 Corporation. All Rights Reserved." #define TUA_DEVICE "Part of the OpenSS7 Stack for LiS STREAMS." #define TUA_CONTACT "Brian Bidulock <bidulock@openss7.org>" #define TUA_LICENSE "GPL" #define TUA_BANNER TUA_DESCRIP "\n" \ TUA_COPYRIGHT "\n" \ TUA_DEVICE "\n" \ TUA_CONTACT "\n" MODULE_AUTHOR(TUA_CONTACT); MODULE_DESCRIPTION(TUA_DESCRIP); MODULE_SUPPORTED_DEVICE(TUA_DEVICE); #ifdef MODULE_LICENSE MODULE_LICENSE(TUA_LICENSE); #endif #ifndef INT #define INT void #endif /* * ========================================================================= * * STREAMS Definitions * * ========================================================================= */ static int tua_open(queue_t *, dev_t *, int, int, cred_t *); static int tua_close(queue_t *, int, cred_t *); static struct module_info tua_m_minfo = { 0, /* Module ID number */ "tua-lm", /* Module name */ 0, /* Min packet size accepted */ INFPSZ, /* Max packet size accepted */ 1, /* Hi water mark */ 0 /* Lo water mark */ }; static INT tua_m_rput(queue_t *, mblk_t *); static INT tua_m_rsrv(queue_t *); static struct qinit tua_m_rinit { tua_m_rput, /* Read put (msg from below) */ tua_m_rsrv, /* Read queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_m_minfo, /* Information */ NULL /* Statistics */ }; static INT tua_m_wput(queue_t *, mblk_t *); static INT tua_m_wsrv(queue_t *); static struct qinit tua_m_winit { tua_m_wput, /* Write put (msg from above) */ tua_m_wsrv, /* Write queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_m_minfo, /* Information */ NULL /* Statistics */ }; static struct module_info tua_u_minfo = { 0, /* Module ID number */ "tua-slu", /* Module name */ 0, /* Min packet size accepted */ INFPSZ, /* Max packet size accepted */ 1, /* Hi water mark */ 0 /* Lo water mark */ }; static INT tua_u_rput(queue_t *, mblk_t *); static INT tua_u_rsrv(queue_t *); static struct qinit tua_u_rinit { tua_u_rput, /* Read put (msg from below) */ tua_u_rsrv, /* Read queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_u_minfo, /* Information */ NULL /* Statistics */ }; static INT tua_u_wput(queue_t *, mblk_t *); static INT tua_u_wsrv(queue_t *); static struct qinit tua_u_winit { tua_u_wput, /* Write put (msg from above) */ tua_u_wsrv, /* Write queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_u_minfo, /* Information */ NULL /* Statistics */ }; static struct module_info tua_l_info = { 0, /* Module ID number */ "tua-slp", /* Module name */ 0, /* Min packet size accepted */ INFPSZ, /* Max packet size accepted */ 1, /* Hi water mark */ 0 /* Lo water mark */ }; static INT tua_l_rput(queue_t *, mblk_t *); static INT tua_l_rsrv(queue_t *); static struct qinit tua_l_rinit { tua_l_rput, /* Read put (msg from below) */ tua_l_rsrv, /* Read queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_l_info, /* Information */ NULL /* Statistics */ }; static INT tua_l_wput(queue_t *, mblk_t *); static INT tua_l_wsrv(queue_t *); static struct qinit tua_l_winit { tua_l_wput, /* Write put (msg from above) */ tua_l_wsrv, /* Write queue service */ tua_open, /* Each open */ tua_close, /* Last close */ NULL, /* Admin (not used) */ &tua_l_info, /* Information */ NULL /* Statistics */ }; static struct streamtab tua_m_info = { &tua_m_rinit, /* Upper read queue */ &tua_m_winit, /* Upper write queue */ &tua_l_rinit, /* Lower read queue */ &tua_l_winit /* Lower write queue */ }; static struct streamtab tua_u_info = { &tua_u_rinit, /* Upper read queue */ &tua_u_winit, /* Upper write queue */ &tua_l_rinit, /* Lower read queue */ &tua_l_winit /* Lower write queue */ }; /* * ========================================================================= * * OUTPUT Events * * ========================================================================= */ /* * TUA --> LM Primitives * ----------------------------------- */ int lm_ok_ack(ua_t * ua, mblk_t * mp) { int rtn; lm_ok_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->prim = LM_OK_ACK; putq(ua->rq, mp); } return (rtn); } int lm_error_ack(ua_t * ua, mblk_t * mp) { int rtn; lm_error_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->prim = LM_ERROR_ACK; putq(ua->rq, mp); } return (rtn); } int lm_reg_ind(ua_t * ua, mblk_t * mp) { int rtn; lm_reg_ind_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->prim = LM_REG_IND; putq(ua->rq, mp); } return (rtn); } int lm_dereg_ind(ua_t * ua, mblk_t * mp) { int rtn; lm_dereg_ind_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->prim = LM_DEREG_IND; putq(ua->rq, mp); } return (rtn); } int lm_error_ind(ua_t * ua, mblk_t * mp) { int rtn; lm_error_ind_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->prim = LM_ERROR_IND; putq(ua->rq, mp); } return (rtn); } /* * TUA --> SCCPP Primitives * ----------------------------------- */ static int n_info_ack(ua_t * ua, mblk_t * mp) { int rtn; N_info_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_INFO_ACK; putq(ua->wq, mp); } return (rtn); } static int n_bind_ack(ua_t * ua, mblk_t * mp) { int rtn; N_bind_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_BIND_ACK; putq(ua->wq, mp); } return (rtn); } static int n_error_ack(ua_t * ua, mblk_t * mp) { int rtn; N_error_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_ERROR_ACK; putq(ua->wq, mp); } return (rtn); } static int n_ok_ack(ua_t * ua, mblk_t * mp) { int rtn; N_ok_ack_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_OK_ACK; putq(ua->wq, mp); } return (rtn); } static int n_unitdata_ind(ua_t * ua, mblk_t * mp) { int rtn; N_unitdata_ind_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_UNITDATA_IND; putq(ua->wq, mp); } return (rtn); } static int n_uderror_ind(ua_t * ua, mblk_t * mp) { int rtn; N_uderror_ind_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_UDERROR_IND; putq(ua->wq, mp); } return (rtn); } /* * TUA --> SCCPU Primitives * ----------------------------------- */ static int n_info_req(ua_t * ua, mblk_t * mp) { int rtn; N_info_req_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_INFO_REQ; putq(ua->rq, mp); } return (rtn); } static int n_bind_req(ua_t * ua, mblk_t * mp) { int rtn; N_bind_req_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_BIND_REQ; putq(ua->rq, mp); } return (rtn); } static int n_unbind_req(ua_t * ua, mblk_t * mp) { int rtn; N_unbind_req_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_UNBIND_REQ; putq(ua->rq, mp); } return (rtn); } static int n_unitdata_req(ua_t * ua, mblk_t * mp) { int rtn; N_unitdata_req_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_UNITDATA_REQ; putq(ua->rq, mp); } return (rtn); } static int n_optmgmt_req(ua_t * ua, mblk_t * mp) { int rtn; N_optmgmt_req_t *p; if ((rtn = ua_reuseb(ua, sizeof(*p), BPRI_MED, &mp)) >= 0) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_OPTMGMT_REQ; putq(ua->rq, mp); } return (rtn); } /* * ========================================================================= * * STREAMS Message Handling * * ========================================================================= */ /* * ------------------------------------------------------------------------- * * Management Stream (LM) Message Handling * * ------------------------------------------------------------------------- */ /* * LM --> TUA Primitives * ----------------------------------- */ int lm_as_add_req(queue_t * q, mblk_t * mp) { } int lm_as_del_req(queue_t * q, mblk_t * mp) { } int lm_proc_add_req(queue_t * q, mblk_t * mp) { } int lm_proc_del_req(queue_t * q, mblk_t * mp) { } int lm_link_add_req(queue_t * q, mblk_t * mp) { } int lm_link_del_req(queue_t * q, mblk_t * mp) { } int lm_route_add_req(queue_t * q, mblk_t * mp) { } int lm_route_del_req(queue_t * q, mblk_t * mp) { } int lm_reg_res(queue_t * q, mblk_t * mp) { } int lm_reg_ref(queue_t * q, mblk_t * mp) { } static int tua_m_w_ioctl(queue_t * q, mblk_t * mp) { } static int tua_m_w_proto(queue_t * q, mblk_t * mp) { switch (*((long *) mp->b_rptr)) { case LM_AS_ADD_REQ: return lm_as_add_req(q, mp); case LM_AS_DEL_REQ: return lm_as_del_req(q, mp); case LM_PROC_ADD_REQ: return lm_proc_add_req(q, mp); case LM_PROC_DEL_REQ: return lm_proc_del_req(q, mp); case LM_LINK_ADD_REQ: return lm_link_add_req(q, mp); case LM_LINK_DEL_REQ: return lm_link_del_req(q, mp); case LM_ROUTE_ADD_REQ: return lm_route_add_req(q, mp); case LM_ROUTE_DEL_REQ: return lm_route - del_req(q, mp); case LM_REG_RES: return lm_reg_res(q, mp); case LM_REG_REF: return lm_reg_ref(q, mp); } return (-EOPNOTSUPP); } static int tua_m_w_pcproto(queue_t * q, mblk_t * mp) { return tua_m_w_proto(q, mp); } static int tua_m_w_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_PROTO: return tua_m_w_proto(q, mp); case M_PCPROTO: return tua_m_w_pcproto(q, mp); case M_IOCTL: return tua_m_w_ioctl(q, mp); case M_FLUSH: return ua_w_flush(q, mp); } return (-EOPNOTSUPP); } static INT tua_m_wput(queue_t * q, mblk_t * mp) { return ((INT) ua_putq(q, mp, &tua_m_w_prim)); } static INT tua_m_wsrv(queue_t * q) { return ((INT) ua_srvq(q, &tua_m_w_prim)); } /* * TUA --> LM Primitives * ----------------------------------- */ static int tua_m_r_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_FLUSH: return ua_r_flush(q, mp); } return (5); } static INT tua_m_rput(queue_t * q, mblk_t * mp) { return ((INT) ua_putq(q, mp, &tua_m_r_prim)); } static INT tua_m_rsrv(queue_t * q) { return ((INT) ua_srvq(q, &tua_m_r_prim)); } /* * ------------------------------------------------------------------------- * * SCCP User (SCCPU) Stream Message Handling * * ------------------------------------------------------------------------- */ /* * TCAP User --> TUA Primitives * ----------------------------------- */ static int tcapu_info_req(queue_t * q, mblk_t * mp) { } static int tcapu_bind_req(queue_t * q, mblk_t * mp) { } static int tcapu_unbind_req(queue_t * q, mblk_t * mp) { } static int tcapu_unitdata_req(queue_t * q, mblk_t * mp) { } static int tcapu_optmgmt_req(queue_t * q, mblk_t * mp) { } static int tua_u_w_ioctl(queue_t * q, mblk_t * mp) { } static int tua_u_w_data(queue_t * q, mblk_t * dp) { /* * Need to convert data to SL_PDU_REQ. */ int rtn; mblk_t *mp; sl_pdu_req_t *p; if ((mp = allocb(sizeof(*p), BPRI_MED))) { mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->sl_primitive = SL_PDU_REQ; mp->b_cont = dp; switch ((rtn = slu_pdu_req(q, mp))) { } return (1); } return (-ENOBUFS); } static int tua_u_w_proto(queue_t * q, mblk_t * mp) { switch (*((long *) mp->b - rptr)) { case N_INFO_REQ: return tcapu_info_req(q, mp); case N_BIND_REQ: return tcapu_bind_req(q, mp); case N_UNBIND_REQ: return tcapu_unbind_req(q, mp); case N_UNITDATA_REQ: return tcapu_unitdata_req(q, mp); case N_OPTMGMT_REQ: return tcapu_optmgmt_req(q, mp); } return (-EOPNOTSUPP); } static int tua_u_w_pcproto(queue_t * q, mblk_t * mp) { return tua_u_w_proto(q, mp); } static int tua_u_w_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_DATA: return tua_u_w_data(q, mp); case M_PROTO: return tua_u_w_proto(q, mp); case M_PCPROTO: return tua_u_w_pcproto(q, mp); case M_IOCTL: return tua_u_w_ioctl(q, mp); case M_FLUSH: return ua_w_flush(q, mp); } return (-EOPNOTSUPP); } static INT tua_u_wput(queue_t * q, mblk_t * mp) { return ((INT) ua_putq(q, mp, &tua_u_w_prim)); } static INT tua_u_wsrv(queue_t * q) { return ((INT) ua_srvq(q, &tua_u_w_prim)); } /* * TUA --> TCAP User Primitives * ----------------------------------- */ static int tua_u_r_data(queue_t * q, mblk_t * mp) { } static int tua_u_r_ctl(queue_t * q, mblk_t * mp) { } static int tua_u_r_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_DATA: return tua_u_r_data(q, mp); case M_CTL: return tua_u_r_ctl(q, mp); case M_FLUSH: return ua_r_flush(q, mp); } return (5); } static INT tua_u_rput(queue_t * q, mblk_t * mp) { return ((INT) ua_putq(q, mp, &tua_u_r_prim)); } static INT tua_u_rsrv(queue_t * q) { return ((INT) ua_srvq(q, &tua_u_r_prim)); } /* * ------------------------------------------------------------------------- * * SCCP Provider (SCCPP) Stream Message Handling * * ------------------------------------------------------------------------- */ /* * TUA --> TCAP Provider Primitives * ----------------------------------- */ static int tua_l_w_data(queue_t * q, mblk_t * mp) { } static int tua_l_w_ctl(queue_t * q, mblk_t * mp) { } static int tua_l_w_error(queue_t * q, mblk_t * mp) { } static int tua_l_w_hangup(queue_t * q, mblk_t * mp) { } static int tua_l_w_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_DATA: return tua_l_w_data(q, mp); case M_CTL: return tua_l_w_ctl(q, mp); case M_ERROR: return tua_l_w_error(q, mp); case M_HANGUP: return tua_l_w_hangup(q, mp); case M_FLUSH: return ua_w_flush(q, mp); } return (5); } static INT tua_l_wput(queue_t * q, mblk_t * mp) { return ((INT) ua_putq(q, mp, &tua_l_w_prim)); } static INT tua_l_wsrv(queue_t * q) { return ((INT) ua_srvq(q, &tua_l_w_prim)); } /* * TCAP Provider --> TUA Primitives * ----------------------------------- */ static int tcapp_uni_ind(queue_t * q, mblk_t ** mpp); { mblk_t *mp; TC_uni_ind_t *p = (typeof(p)) (*mpp)->b_rptr; tcap_addr_t *src = (typeof(src)) (*mpp)->b_rptr + p->SRC_offset; tcap_addr_t *dst = (typeof(dst)) (*mpp)->b_rptr + p->DEST_offset; TC_qos_sel_data_t *qos = (typeof(qos)) (dst + 1); size_t mlen = *sizeof(uint32_t); size_t dlen = msgdsize((*mpp)->b_cont); if ((mp = allocb(mlen, BPRI_MED))) { mp->b_datap->db_type = M_DATA; *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DEST_ADDR; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_ORIG_ADDR; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_APPL_CTXT; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_USER_INFO; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_CONFIDENT; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_SECU_CNTX; } return ua_bufcall(as->ss7->rq, mlen); } static int tcapp_begin_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_begin_con(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_cont_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_end_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_abort_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_notice_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_ID; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_DIAL_FLAG; *((uint32_t *) mp->b_wptr)++ = TUA_PARM_QOS; } static int tcapp_invoke_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; } static int tcapp_result_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; } static int tcapp_error_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; } static int tcapp_cancel_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; } static int tcapp_reject_ind(queue_t * q, mblk_t ** mpp); { *((uint32_t *) mp->b_wptr)++ = TUA_TDHM_TUNI; *((uint32_t *) mp->b_wptr)++ = UA_PARM_RC; *((uint32_t *) mp->b_wptr)++ = UA_PARM_CORR_ID; } static int tcapp_xlat_prim(queue_t * q, mblk_t ** mpp) { switch (*((long *) (*mpp)->b_rptr)) { case TC_UNI_IND: return tcapp_uni_ind(q, mpp); case TC_BEGIN_IND: return tcapp_begin_ind(q, mpp); case TC_BEGIN_CON: return tcapp_begin_con(q, mpp); case TC_CONT_IND: return tcapp_cont_ind(q, mpp); case TC_END_IND: return tcapp_end_ind(q, mpp); case TC_ABORT_IND: return tcapp_abort_ind(q, mpp); case TC_NOTICE_IND: return tcapp_notice_ind(q, mpp); case TC_INVOKE_IND: return tcapp_invoke_ind(q, mpp); case TC_RESULT_IND: return tcapp_result_ind(q, mpp); case TC_ERROR_IND: return tcapp_error_ind(q, mpp); case TC_CANCEL_IND: return tcapp_cancel_ind(q, mpp); case TC_REJECT_IND: return tcapp_reject_ind(q, mpp); } return (-EOPNOTSUPP); } static int tcapp_xlat_prim(queue_t * q, mblk_t * mp) { int err; xp_t *xp; pp_t *pp; as_t *as; lp_t *lp = (lp_t *) q->q_ptr; ensure(q, return (-EFAULT)); ensure(lp, return (-EFAULT)); if (lp->l.state != NS_IDLE) return (0); /* * If we have a local TCAP User, then just pass the primitive on to * the local user. */ if ((pp = ua_as_route_loc(as))) { if (mp->b_datap->db_type < QPCTL && !canput(pp->rq)) return (-EBUSY); putq(pp->rq, mp); return (1); } /* * If we have a remote SCCP User (i.e, SUA AS), then translate the * primitive to an SUA messages and pass it to the AS> */ if ((xp = ua_as_route_rem(as))) { if (!(pp = xp->pp.pp)) { ptrace(("Have route to XP but no LP\n")); return (-EFAULT); } if (mp->b_datap->db_type < QPCTL && !caonput(pp->rq)) return (-EBUSY); if ((err = tcapp_xlat(as, &mp))) return (err); putq(pp->rq, mp); return (1); } ptrace(("AS-U marked active but not AS-U\n")); return (-EFAULT); } static int tua_l_r_proto(queue_t * q, mblk_t * mp) { switch (*((long *) mp->b_rptr)) { case TC_INFO_ACK: return tcapp_info_ack(q, mp); case TC_BIND_ACK: return tcapp_bind_ack(q, mp); case TC_SUBS_BIND_ACK: return tcapp_subs_bind_ack(q, mp); case TC_OK_ACK: return tcapp_ok_ack(q, mp); case TC_ERROR_ACK: return tcapp_error_ack(q, mp); case TC_OPTMGMT_ACK: return tcapp_optmgmt_ack(q, mp); case TC_UNI_IND: case TC_BEGIN_IND: case TC_BEGIN_CON: case TC_CONT_IND: case TC_END_IND: case TC_ABORT_IND: case TC_NOTICE_IND: case TC_INVOKE_IND: case TC_RESULT_IND: case TC_ERROR_IND: case TC_CANCEL_IND: case TC_REJECT_IND: return tcapp_xlat_prim(q, mp); } return (-EOPNOTSUPP); } static int tua_l_r_pcproto(queue_t * q, mblk_t * mp) { return tua_l_r_proto(q, mp); } static int tua_l_r_error(queue_t * q, mblk_t * mp) { fixme(("Deactivate and take down AS, notify LM.\n")); return (-EFAULT); } static int tua_l_r_hangup(queue_t * q, mblk_t * mp) { fixme(("Deactivate and take down AS, notify LM.\n")); return (-EFAULT); } static int tua_l_r_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_PROTO: return tua_l_r_proto(q, mp); case M_PCPROTO: return tua_l_r_pcproto(q, mp); case M_ERROR: return tua_l_r_error(q, mp); case M_HANGUP: return tua_l_r_hangup(q, mp); case M_FLUSH: return ua_r_flush(q, mp); } return (-EOPNOTSUPP); } /* * ------------------------------------------------------------------------- * * SCTP NPI Transport Message Handling * * ------------------------------------------------------------------------- * * TUA --> SCTP NPI Transport Primitives * ------------------------------------------------------------------------- */ static int tua_s_w_data(queue_t * q, mblk_t * dp) { mblk_t *mp; N_data_req_t *p; N_qos_sel_data_sctp_t *q; if ((mp = allocb(sizeof(*p) + sizeof(*q), BPRI_MED))) { uint32_t mhdr = ((uint32_t *) dp->b_rptr)[0]; mp->b_datap->db_type = M_PROTO; p = ((typeof(p)) mp->b_wptr)++; p->PRIM_type = N_DATA_REQ; p->DATA_xfer_flags = 0; q = ((typeof(q)) mp->b_wptr)++; q->n_qos_type = N_QOS_SEL_DATA_SCTP; q->ppi = TUA_PPI; q->tsn = 0; q->ssn = 0; mp->b_cont = dp; switch (UA_MSG_CLAS(mhdr)) { case UA_CLASS_MGMT: case UA_CLASS_ASPS: case UA_CLASS_RKMM: q->sid = 0; break; case UA_CLASS_ASPT: case UA_CLASS_XFER: case UA_CLASS_SNMM: { uint32_t rc = ((uint32_t *) dp->b_rptr)[3]; fixme(("Map RC onto a stream id\n")); q->sid = rc; break; } default: case UA_CLASS_MAUP: case UA_CLASS_Q921: case UA_CLASS_CNLS: case UA_CLASS_CONS: case UA_CLASS_TDHM: case UA_CLASS_TCHM: freeb(mp); return (-EPROTO); } putq(q, mp); return (1); } return (-ENOBUFS); } static int tua_s_w_ctl(queue_t * q, mblk_t * mp) { return tua_s_w_data(q, mp); } static int tua_s_w_error(queue_t * q, mblk_t * mp) { fixme(("Disconnect, deactivate and take down ASP and notify LM\n")); noenable(q); return (-EFAULT); } static int tua_s_w_hangup(queue_t * q, mblk_t * mp) { fixme(("Disconnect, deactivate and take down ASP and notify LM\n")); noenable(q); return (-EFAULT); } static int tua_x_w_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_DATA: return tua_s_w_data(q, mp); case M_CTL: return tua_s_w_ctl(q, mp); case M_ERROR: return tua_s_w_error(q, mp); case M_HANGUP: return tua_s_w_hangup(q, mp); case M_FLUSH: return ua_w_flush(q, mp); } return (-EOPNOTSUPP); } /* * SCTP NPI Transport --> TUA Primitives * ------------------------------------------------------------------------- */ static int tua_s_data_ind(queue_t * q, mblk_t * mp) { } static int tua_s_exdata_ind(queue_t * q, mblk_t * mp) { } static int tua_s_other_ind(queue_t * q, mblk_t * mp) { } static int tua_s_r_proto(queue_t * q, mblk_t * mp) { switch (*((long *) mp->b_rptr)) { case N_DATA_IND: return tua_s_data_ind(q, mp); case N_EXDATA_IND: return tua_s_exdata_ind(q, mp); default: return tua_s_other_ind(q, mp); } } static int tua_s_r_pcproto(queue_t * q, mblk_t * mp) { return tua_s_r_proto(q, mp); } static int tua_s_r_error(queue_t * q, mblk_t * mp) { fixme(("Deactivate and take down ASP and notify LM\n")); noenable(q); return (-EFAULT); } static int tua_s_r_hangup(queue_t * q, mblk_t * mp) { fixme(("Deactivate and take down ASP and notify LM\n")); noenable(q); return (-EFAULT); } static int tua_x_r_prim(queue_t * q, mblk_t * mp) { switch (mp->b_datap->db_type) { case M_PROTO: return tua_s_r_proto(q, mp); case M_PCPROTO: return tua_s_r_pcproto(q, mp); case M_ERROR: return tua_s_r_error(q, mp); case M_HANGUP: return tua_s_r_hangup(q, mp); case M_FLUSH: return ua_r_flush(q, mp); } return (-EOPNOTSUPP); } extern struct drv tua_driver = { TUA_CMAJOR, TUA_NMAJOR, TUA_NMINOR, {&tua_u_r_prim, &tua_u_w_prim}, {&tua_l_r_prim, &tua_l_w_prim}, {&tua_x_r_prim, &tua_x_w_prim} };
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |