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/ua/ua_lower.c#ident "@(#) $RCSfile: ua_lower.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $" static char const ident[] = "$RCSfile: ua_lower.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $"; #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 "ua.h" #include "ua_data.h" /* * ========================================================================= * * SCCP/NPI/TPI --> SUA (Upstream Primitives received from downstream) * * ========================================================================= */ /* from ua_nsp.c */ extern int nsp_r_data(queue_t *, mblk_t *); extern int nsp_r_proto(queue_t *, mblk_t *); /* from ua_tsp.c */ extern int tsp_r_data(queue_t *, mblk_t *); extern int tsp_r_proto(queue_t *, mblk_t *); /* from ua_ss7.c *//* UA-specific */ extern int ss7_r_data(queue_t *, mblk_t *); extern int ss7_r_proto(queue_t *, mblk_t *); /* * M_ERROR, M_HANGUP Processing * ------------------------------------------------------------------------- */ static int spp_r_error(queue_t * q, mblk_t * msg) { int err; if ((err = lm_link_ind(q, mp))) return (err); if ((err = ua_spp_blocked(q))) return (err); return (0); } static int ss7_r_error(queue_t * q, mblk_t * msg) { int err; if ((err = lm_link_ind(q, mp))) return (err); if ((err = ua_ss7_blocked(q))) return (err); return (0); } /* * M_CTL Processing * ------------------------------------------------------------------------- * None of the SS7 or TSP support any M_CTL messages. Notify management and * ignore the message. */ static int xxx_r_ctl(queue_t * q, mblk_t * msg) { int err; if ((err = lm_link_ind(q, mp))) return (err); return (0); } /* * M_FLUSH Processing * ------------------------------------------------------------------------- * Take flushes from below and turn them around back down to the SS7 or TSP * provider. */ static int xxx_r_flush(queue_t * q, mblk_t * msg) { if (*msg->b_rptr & FLUSHR) { if (*msg->b_rptr & FLUSHBAND) flushband(q, msg->b_rptr[1], FLUSHALL); else flushall(q, FLUSHALL); *msg->b_rptr &= ~FLUSHR; } if ((*msg->b_rptr & FLUSHW) && !(msg->b_flags & MSGNOLOOP)) { if (*msg->b_rptr & FLUSHBAND) flushband(q, msg->b_rptr[1], FLUSHALL); else flushall(q, FLUSHALL); msg->b_flag |= MSGNOLOOP; qreply(q, msg); /* flush all the way back down */ } freemsg(msg); return (0); } /* * ========================================================================= * * QUEUE PUT and SERVICE routines * * ========================================================================= */ static inline int ua_recover(queue_t * q, mblk_t * mp, int err) { switch (err) { case -EBUSY: case -EAGAIN: case -ENOMEM: case -ENOBUFS: putq(q, mp); return (0); } freemsg(mp); return (err); } static inline int ua_reservice(queue_t * q, mblk_t * mp, int err) { if (mp->b_datap->db_type < QPCTL) switch (err) { case -EBUSY: case -EAGAIN: case -ENOMEM: case -ENOBUFS: putbq(q, mp); return (0); } freemsg(mp); return (err); } /* * READ PUT and SERVICE (Message from below SCCP/NPI/TPI --> SUA) * ------------------------------------------------------------------------- */ static inline int ua_rd(queue_t * q, mblk_t * mp) { switch (Q_TYPE(q)) { case Q_TYPE_NPI: switch (mp->b_datap->db_type) { case M_DATA: return nsp_r_data(q, mp); case M_PROTO: case M_PCPROTO: return nsp_r_proto(q, mp); case M_ERROR: case M_HANGUP: return spp_r_error(q, mp); case M_CTL: return xxx_r_ctl(q, mp); case M_FLUSH: return xxx_r_flush(q, mp); } return (-EOPNOTSUPP); case Q_TYPE_TPI: switch (mp->b_datap->db_type) { case M_DATA: return tsp_r_data(q, mp); case M_PROTO: case M_PCPROTO: return tsp_r_proto(q, mp); case M_ERROR: case M_HANGUP: return spp_r_error(q, mp); case M_CTL: return xxx_r_ctl(q, mp); case M_FLUSH: return xxx_r_flush(q, mp); } return (-EOPNOTSUPP); case Q_TYPE_SS7: switch (mp->b_datap->db_type) { case M_DATA: return ss7_r_data(q, mp); case M_PROTO: case M_PCPROTO: return ss7_r_proto(q, mp); case M_ERROR: case M_HANGUP: return ss7_r_error(q, mp); case M_CTL: return xxx_r_ctl(q, mp); case M_FLUSH: return xxx_r_flush(q, mp); } return (-EOPNOTSUPP); } return (-EFAULT); } INT ua_l_rput(queue_t * q, mblk_t * mp) { int err; if (mp->b_datap->db_type < QPCTL && (q->q_count || !canputnext(q))) { putq(q, mp); return (INT) (0); } if ((err = ua_rd(q, mp))) return (INT) (ua_recover(q, mp, err)); return (INT) (0); } INT ua_l_rsrv(queue_t * q) { mblk_t *mp; while ((mp = getq(q))) { int err; if (!(err = ua_rd(q, mp))) continue; if (mp->b_datap->db_type < QPCTL) return (INT) (ua_reservice(q, mp, err)); freemsg(mp); return (INT) (err); } return (INT) (0); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |