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/m3ua/m3ua_asp.c#ident "@(#) $RCSfile: m3ua_asp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:31 $" static char const ident[] = "$RCSfile: m3ua_asp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:31 $"; #define __NO_VERSION__ #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 "../debug.h" #include "../bufq.h" #include "../../include/ss7/mtp.h" #include "../mtp/mtp_prov.h" #include "../ua/ua_data.h" #include "m3ua_data.h" #include "../ua/ua_msg.h" #include "m3ua_msg.h" #include "../ua/ua_asp.h" /* * ========================================================================= * * M3UA Peer --> M3UA (ASP) Received Messages * * ========================================================================= */ /* * XFER DATA (Pass along as M_DATA) * ------------------------------------------------------------------------- */ static int m3ua_recv_data(asp_t * asp, mblk_t * msg) { uint32_t tag, *p = ((uint32_t *) msg->b_rptr) + 4; size_t len = UA_SIZE(*p); tag = *p++ & UA_TAG_MASK; (void) len; (void) tag; /* * FIXME: */ return (-EFAULT); } /* * SNMM * ------------------------------------------------------------------------- * Some routines for distributing SNMM messages. */ /* * Distribute SNMM primitives to MTP for a range of Routing Contexts. */ static int m3ua_distribute(asp_t * asp, mblk_t * mp, parm_t * rc) { int i; mblk_t *dp, *ep; for (i = 0; i < rc->len >> 2; i++) { gp_t *gp; uint found = 0; uint32_t rcval = ntohl(rc->u.wptr[i]); for (gp = Q_SP(q)->gp; gp; gp = gp->as_next) { as_t *as = gp->as; if (!rc->len || as->list->id == rcval) { if (!(dp = dupmsg(mp))) { freemsg(mp); /* free original */ return (-ENOBUFS); } putq(as->list->lp->q, dp); found = 1; } } if (rc->len && !found) { ep = ua_send_err(UA_ECODE_INVALID_ROUTING_CONTEXT, (caddr_t) & rc->u.wptr[i], 4); if (!ep) return (-ENOBUFS); ptrace(("Error: DUNA: invalid Routing Context\n")); qreply(q, ep); } } freemsg(mp); /* free original */ return (0); } static int m3ua_snmm_parm_check(asp_t * asp, mblk_t * msg, m3ua_parms_t * parms) { mblk_t *ep; size_t elen = min(40, msgdsize(msg)); parm_t *rc = &parms->common.rc; parm_t *ad = &parms->affect_dest; if (!ad->u.wptr) { ep = ua_send_err(UA_ECODE_PROTOCOL_ERROR, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); ptrace(("Error: SNMM: missing mandatory parm Affected Desination\n")); qreply(q, ep); return (-EINVAL); } if (ad->len < sizeof(uint32_t)) { ep = ua_send_err(UA_ECODE_INVALID_PARAMETER_VALUE, ad->u.cptr - 4, ad->len + 4); if (!ep) return (-ENOBUFS); ptrace(("Error: SNMM: parm Affected Desination too short: %d bytes\n", ad->len)); qreply(q, ep); return (-EINVAL); } if (rc->u.wptr && rc->len < sizeof(uint32_t)) { ep = ua_send_err(UA_ECODE_INVALID_PARAMETER_VALUE, (caddr_t) rc->u.wptr - 4, ad->len + 4); if (!ep) return (-ENOBUFS); ptrace(("Error: SNMM: parm Routing Context too short: %d bytes\n", rc->len)); qreply(q, ep); return (-EINVAL); } return (0); } static int m3ua_not_sg(asp_t * asp, mblk_t * msg) { mblk_t *ep; if (Q_MODE(q) & Q_MODE_SG) { uint elen = min(40, msgdsize(msg)); ep = ua_send_err(UA_ECODE_UNEXPECTED_MESSAGE, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); qreply(q, ep); return (-EINVAL); } return (0); } /* * SNMM DUNA * ------------------------------------------------------------------------- * DUNA messages are only sent from SGP to ASP/IPSP. They are never sent * from ASP to SGP. At the ASP we must determine which routing contexts * correspond to the given Network Appearance (if any) and signal * MTP_PAUSE_IND to the user. If our MTP user is running fully responsive, * we only update our internal routing tables. We wait for the MTP-User to * send to us and immediately return N_UDERROR_IND. */ static int m3ua_recv_duna(asp_t * asp, mblk_t * msg) { int err; mblk_t *mp; m3ua_parms_t parms; if ((err = m3ua_not_sg(q, msg))) return (err); if ((err = m3ua_decode_parms(msg, &parms))) return (err); if ((err = m3ua_snmm_parm_check(q, msg, &parms))) return (err); for (; parms.affect_dest.len; parms.affect_dest.len -= 4) { int i; mblk_t *dp, *ep; parm_t *rc = &parms.common.rc; mtp_pc_t dest = { 0, ntohl(*(parms.affect_dest.u.wptr)++) }; if (dest.pc & 0xff000000) /* don't indicate clusters */ continue; if (dest.pc == 0xffffffff) { /* mtp restart */ if (!(mp = mtp_uderror_ind(MTP_RESTARTING, NULL, NULL, NULL))) return (-ENOBUFS); } else { if (!(mp = mtp_uderror_ind(MTP_DEST_PROHIBITED, &dest, NULL, NULL))) return (-ENOBUFS); } for (i = 0; i < rc->len >> 2; i++) { gp_t *gp; uint found = 0; uint32_t rcval = ntohl(rc->u.wptr[i]); for (gp = Q_SP(q)->gp; gp; gp = gp->as_next) { rc_t *rcp = gp->as->list; if (rcp->id == rcval) { if (!(dp = dupmsg(mp))) { freemsg(mp); /* free original */ return (-ENOBUFS); } putq(rcp->lp->q, dp); found = 1; /* * FIXME: mark in the network * appearance table. */ } } if (!found) { ep = ua_send_err(UA_ECODE_INVALID_ROUTING_CONTEXT, (caddr_t) & rc->u.wptr[i], 4); if (!ep) return (-ENOBUFS); ptrace(("Error: DUNA: invalid Routing Context\n")); qreply(q, ep); } } if (!rc->len) { gp_t *gp; uint found = 0; (void) found; for (gp = Q_SP(q)->gp; gp; gp = gp->as_next) { rc_t *rcp = gp->as->list; if (!(dp = dupmsg(mp))) { freemsg(mp); /* free original */ return (-ENOBUFS); } putq(rcp->lp->q, dp); /* * FIXME: mark in the network * appearance table. */ } } freemsg(mp); /* free original */ } return (0); } /* * SNMM DAVA * ------------------------------------------------------------------------- * DAVA messages are only send from SGP to ASP/IPSP. They are never sent * from ASP to SGP. * It might be an idea to do some work for the user here and only send * MTP-RESUME for a destination that the user has actually sent a message for * in the past or that we have sent an MTP-PAUSE for. There is no need for * the user to be "promiscuous" about point code availability. */ static int m3ua_recv_dava(asp_t * asp, mblk_t * msg) { (void) q; (void) msg; /* * FIXME: */ return (-EFAULT); } /* * SNMM DAUD * ------------------------------------------------------------------------- */ static int m3ua_recv_daud(asp_t * asp, mblk_t * msg) { mblk_t *ep; size_t mlen = msgdsize(msg); if (Q_MODE(q) & Q_MODE_SG) { uint elen = min(40, mlen); ep = ua_send_err(UA_ECODE_UNEXPECTED_MESSAGE, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); return (-EINVAL); } return (-EOPNOTSUPP); } /* * SNMM SCON * ------------------------------------------------------------------------- */ static int m3ua_recv_scon(asp_t * asp, mblk_t * msg) { mblk_t *ep; size_t mlen = msgdsize(msg); if (Q_MODE(q) & Q_MODE_SG) { uint elen = min(40, mlen); ep = ua_send_err(UA_ECODE_UNEXPECTED_MESSAGE, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); return (-EINVAL); } return (-EOPNOTSUPP); } /* * SNMM DUPU * ------------------------------------------------------------------------- */ static int m3ua_recv_dupu(asp_t * asp, mblk_t * msg) { mblk_t *ep; size_t mlen = msgdsize(msg); if (Q_MODE(q) & Q_MODE_SG) { uint elen = min(40, mlen); ep = ua_send_err(UA_ECODE_UNEXPECTED_MESSAGE, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); return (-EINVAL); } return (-EOPNOTSUPP); } /* * SNMM DRST * ------------------------------------------------------------------------- */ static int m3ua_recv_drst(asp_t * asp, mblk_t * msg) { mblk_t *ep; size_t mlen = msgdsize(msg); if (Q_MODE(q) & Q_MODE_SG) { uint elen = min(40, mlen); ep = ua_send_err(UA_ECODE_UNEXPECTED_MESSAGE, msg->b_rptr, elen); if (!ep) return (-ENOBUFS); return (-EINVAL); } return (-EOPNOTSUPP); } /* * RKMM REG RSP * ------------------------------------------------------------------------- */ static int m3ua_recv_reg_rsp(asp_t * asp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * RKMM DEREG RSP * ------------------------------------------------------------------------- */ static int m3ua_recv_dereg_rsp(asp_t * asp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * Common defined ASP/SGP management procedures. */ extern int (*ua_asp_mgmt[]) (asp_t *, mblk_t *); extern int (*ua_asp_asps[]) (asp_t *, mblk_t *); extern int (*ua_asp_aspt[]) (asp_t *, mblk_t *); static int (*m3ua_xfer[]) (asp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ m3ua_recv_data /* M3UA_XFER_DATA 0x1 */ }; static int (*m3ua_snmm[]) (asp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ m3ua_recv_duna, /* UA_SNMM_DUNA 0x1 */ m3ua_recv_dava, /* UA_SNMM_DAVA 0x2 */ m3ua_recv_daud, /* UA_SNMM_DAUD 0x3 */ m3ua_recv_scon, /* UA_SNMM_SCON 0x4 */ m3ua_recv_dupu, /* UA_SNMM_DUPU 0x5 */ m3ua_recv_drst /* UA_SNMM_DRST 0x6 */ }; static int (*m3ua_rkmm[]) (asp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ NULL, /* UA_RKMM_REG_REQ 0x1 */ m3ua_recv_reg_rsp, /* UA_RKMM_REG_RSP 0x2 */ NULL, /* UA_RKMM_DEREG_REQ 0x3 */ m3ua_recv_dereg_rsp /* UA_RKMM_DEREG_RSP 0x4 */ }; static struct msg_class msg_decode[] = { {ua_asp_mgmt, UA_MGMT_LAST}, /* UA_CLASS_MGMT 0x0 */ {m3ua_xfer, M3UA_XFER_LAST}, /* UA_CLASS_XFER 0x1 */ {m3ua_snmm, UA_SNMM_LAST}, /* UA_CLASS_SNMM 0x2 */ {ua_asp_asps, UA_ASPS_LAST}, /* UA_CLASS_ASPS 0x3 */ {ua_asp_aspt, UA_ASPT_LAST}, /* UA_CLASS_ASPT 0x4 */ {NULL, 0}, /* UA_CLASS_Q921 0x5 */ {NULL, 0}, /* UA_CLASS_MAUP 0x6 */ {NULL, 0}, /* UA_CLASS_CNLS 0x7 */ {NULL, 0}, /* UA_CLASS_CONS 0x8 */ {m3ua_rkmm, UA_RKMM_LAST}, /* UA_CLASS_RKMM 0x9 */ {NULL, 0}, /* UA_CLASS_TDHM 0xa */ {NULL, 0} /* UA_CLASS_TCHM 0xb */ }; int m3ua_asp_recv_msg(asp_t * asp, mblk_t * mp) { return ua_recv_msg(q, mp, msg_decode); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |