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/m2ua/m2ua_sgp.c#ident "@(#) $RCSfile: m2ua_sgp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:20 $" static char const ident[] = "$RCSfile: m2ua_sgp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:50:20 $"; #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/sl.h" #include "../sl/sl_prov.h" #include "../ua/ua_data.h" #include "m2ua_data.h" #include "../ua/ua_msg.h" #include "m2ua_msg.h" #include "../ua/ua_asp.h" /* * ========================================================================= * * M2UA Peer --> M2UA (SGP) Received messages * * ========================================================================= */ /* * MAUP DATA (SG-->AS or AS-->SG) (Pass along as M_DATA) * ------------------------------------------------------------------------- */ static int m2ua_recv_data(sgp_t * sgp, mblk_t * msg) { uint32_t tag, *p = ((uint32_t *) msg->b_rptr) + 4; size_t len = UA_SIZE(*p); tag = *p++ & UA_TAG_MASK; /* * FIXME: We also need to look for a Correlation Id in the message * and use it to reset the MSU correlation number if there is an Id * in the message. * * Note also that every data message should be acknowledged once the * message has been passed to Level 3. */ if (tag != M2UA_PARM_DATA1 && tag != M2UA_PARM_DATA2) return -EPROTO; if (len > msg->b_wptr - (unsigned char *) p) return -EMSGSIZE; msg->b_datap->db_type = M_DATA; msg->b_rptr = (unsigned char *) p; msg->b_wptr = (unsigned char *) p + len; putq(q, msg); return (0); } /* * MAUP ESTABLISH REQUEST (AS-->SG) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_estab_req(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * MAUP ESTABLISH CONFIRM (SG-->AS) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_estab_con(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * MAUP RELEASE REQUEST (AS-->SG) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_rel_req(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * MAUP RELEASE CONFIRM (SG-->AS) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_rel_con(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * MAUP RELEASE INDICATION (SG-->AS) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_rel_ind(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EOPNOTSUPP); } /* * MAUP STATE REQUEST (AS-->SG) (Pass along as M_PROTO) * ------------------------------------------------------------------------- */ static int m2ua_recv_state_req(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_rptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; if (*p++ != M2UA_PARM_STATE_REQUEST) return -EPROTO; switch (*p++) { case M2UA_STATUS_LPO_SET: m->sl_primitive = SL_LOCAL_PROCESSOR_OUTAGE_REQ; break; case M2UA_STATUS_LPO_CLEAR: m->sl_primitive = SL_RESUME_REQ; break; case M2UA_STATUS_EMER_SET: m->sl_primitive = SL_EMERGENCY_REQ; break; case M2UA_STATUS_EMER_CLEAR: m->sl_primitive = SL_EMERGENCY_CEASES_REQ; break; case M2UA_STATUS_FLUSH_BUFFERS: m->sl_primitive = SL_CLEAR_BUFFERS_REQ; break; case M2UA_STATUS_CONTINUE: m->sl_primitive = SL_RESUME_REQ; break; case M2UA_STATUS_AUDIT: /* * FIXME: return state according to 5.3.8 */ freemsg(msg); return (0); case M2UA_STATUS_CONG_CLEAR: m->sl_primitive = SL_NO_CONGESTION_REQ; break; case M2UA_STATUS_CONG_ACCEPT: m->sl_primitive = SL_CONGESTION_ACCEPT_REQ; break; case M2UA_STATUS_CONG_DISCARD: m->sl_primitive = SL_CONGESTION_DISCARD_REQ; break; default: return (-EPROTO); } msg->b_datap->db_type = M_PROTO; msg->b_band = 2; /* expedite around data */ msg->b_wptr = msg->b_rptr + sizeof(m->sl_primitive); putq(q, msg); return (0); } /* * MAUP STATE CONFIRM * ------------------------------------------------------------------------- */ static int m2ua_recv_state_con(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_rptr) + 4; sl_t *sl = Q_SL(q); if (*p++ != M2UA_PARM_STATE_REQUEST) return -EPROTO; switch (*p++) { case M2UA_STATUS_LPO_SET: sl->pflags &= ~S_PF_LPO_SET; break; case M2UA_STATUS_LPO_CLEAR: sl->pflags &= ~S_PF_LPO_CLEAR; break; case M2UA_STATUS_EMER_SET: sl->pflags &= ~S_PF_EMER_SET; break; case M2UA_STATUS_EMER_CLEAR: sl->pflags &= ~S_PF_EMER_CLEAR; break; case M2UA_STATUS_FLUSH_BUFFERS: sl->pflags &= ~S_PF_FLUSH_BUFFERS; break; case M2UA_STATUS_CONTINUE: sl->pflags &= ~S_PF_CONTINUE; break; case M2UA_STATUS_AUDIT: sl->pflags &= ~S_PF_AUDIT; break; case M2UA_STATUS_CONG_CLEAR: sl->pflags &= ~S_PF_CONG_CLEAR; break; case M2UA_STATUS_CONG_ACCEPT: sl->pflags &= ~S_PF_CONG_ACCEPT; break; case M2UA_STATUS_CONG_DISCARD: sl->pflags &= ~S_PF_CONG_DISCARD; break; default: return (-EPROTO); } if (!sl->pflags) untimeout(xchg(&sl->resp_timer, 0)); freemsg(msg); return (0); } /* * MAUP STATE INDICATION * ------------------------------------------------------------------------- */ static int m2ua_recv_state_ind(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; if (*p++ != M2UA_PARM_STATE_EVENT) return -EPROTO; switch (*p++) { case M2UA_EVENT_RPO_ENTER: m->sl_primitive = SL_REMOTE_PROCESSOR_OUTAGE_IND; break; case M2UA_EVENT_RPO_EXIT: m->sl_primitive = SL_REMOTE_PROCESSOR_RECOVERED_IND; break; default: case M2UA_EVENT_LPO_ENTER: case M2UA_EVENT_LPO_EXIT: return (-EPROTO); } msg->b_datap->db_type = M_PROTO; msg->b_band = 2; /* expedite around data */ msg->b_wptr = msg->b_rptr + sizeof(m->sl_primitive); putq(q, msg); return (0); } /* * MAUP RETRIEVAL REQUEST * ------------------------------------------------------------------------- */ static int m2ua_recv_retr_req(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; ulong fsnc; if (msg->b_wptr - msg->b_rptr < 6 * sizeof(*p)) return -EMSGSIZE; if (*p++ != M2UA_PARM_ACTION) return -EPROTO; switch (*p++) { case M2UA_ACTION_RTRV_BSN: m->sl_primitive = SL_RETRIEVE_BSNT_REQ; msg->b_wptr = msg->b_rptr + sizeof(m->sl_primitive); break; case M2UA_ACTION_RTRV_MSGS: if (msg->b_wptr - msg->b_rptr < 8 * sizeof(*p)) return -EMSGSIZE; if (*p++ != M2UA_PARM_SEQNO) return -EPROTO; fsnc = ntohl(*p++); m->sl_primitive = SL_RETRIEVAL_REQUEST_AND_FSNC_REQ; m->retrieval_request_and_fsnc_req.sl_fsnc = fsnc; msg->b_wptr = msg->b_rptr + sizeof(m->retrieval_request_and_fsnc_req); break; case M2UA_ACTION_DROP_MSGS: m->sl_primitive = SL_CLEAR_RTB_REQ; msg->b_wptr = msg->b_rptr + sizeof(m->sl_primitive); break; case M2UA_ACTION_RTRV_TRANS: return -EPROTO; default: return -EPROTO; } msg->b_datap->db_type = M_PROTO; msg->b_band = 2; /* expedite around data */ putq(q, msg); return (0); } /* * MAUP RETRIEVAL CONFIRM * ------------------------------------------------------------------------- */ static int m2ua_recv_retr_con(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; (void) p; (void) m; return (-EOPNOTSUPP); } /* * MAUP RETRIEVAL INDICATION * ------------------------------------------------------------------------- */ static int m2ua_recv_retr_ind(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; (void) p; (void) m; return (-EOPNOTSUPP); } /* * MAUP RETRIEVAL COMPLETE INDICATION * ------------------------------------------------------------------------- */ static int m2ua_recv_retr_comp_ind(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; (void) p; (void) m; return (-EOPNOTSUPP); } /* * MAUP CONGESTION INDICATION * ------------------------------------------------------------------------- */ static int m2ua_recv_cong_ind(sgp_t * sgp, mblk_t * msg) { uint32_t *p = ((uint32_t *) msg->b_wptr) + 4; union SL_primitives *m = (union SL_primitives *) msg->b_rptr; ulong cong, disc; if (msg->b_wptr - msg->b_rptr < 8 * sizeof(*p)) return -EMSGSIZE; if (*p++ != M2UA_PARM_CONG_STATUS) return -EPROTO; switch ((cong = *p++)) { case M2UA_LEVEL_NONE: case M2UA_LEVEL_1: case M2UA_LEVEL_2: case M2UA_LEVEL_3: break; case M2UA_LEVEL_4: /* TODO: tell sender to go away! */ default: return -EPROTO; } if (*p++ != M2UA_PARM_DISC_STATUS) return -EPROTO; switch ((disc = *p++)) { case M2UA_LEVEL_NONE: case M2UA_LEVEL_1: case M2UA_LEVEL_2: case M2UA_LEVEL_3: break; case M2UA_LEVEL_4: /* TODO: tell sender to go away! */ default: return -EPROTO; } m->link_congested_ind.sl_primitive = SL_LINK_CONGESTED_IND; m->link_congested_ind.sl_cong_status = ntohl(cong); m->link_congested_ind.sl_disc_status = ntohl(disc); msg->b_datap->db_type = M_PROTO; msg->b_band = 2; /* expedite around data */ msg->b_wptr = msg->b_rptr + sizeof(m->link_congested_ind); putq(q, msg); return (0); } /* * MAUP DATA ACK (SG-->AS or AS-->SG) * ------------------------------------------------------------------------- */ static int m2ua_recv_data_ack(sgp_t * sgp, mblk_t * msg) { uint32_t tag, *p = ((uint32_t *) msg->b_rptr) + 4; size_t len = UA_SIZE(*p); tag = *p++ & UA_TAG_MASK; if (tag != M2UA_PARM_CORR_ID_ACK) return -EPROTO; if (len > msg->b_wptr - (unsigned char *) p) return -EMSGSIZE; /* * FIXME: Ok, so now we have a data ack, what do we do with it? We * must somehow adjust the SL implementation to only acknowledge data * which has been successfully delivered upstream. Then we need to * disable the SL read queue when an acknowledgement is pending and * enable it when data is received. We can set the flow control * thresholds on the queue to have a high water mark of 1 byte to * ensure that only one message is in the read queue at a given point * in time. */ freemsg(msg); return (0); } /* * UA_RKMM_REG_REQ * ------------------------------------------------------------------------- */ static int m2ua_recv_reg_req(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EFAULT); } /* * UA_RKMM_REG_RSP * ------------------------------------------------------------------------- */ static int m2ua_recv_reg_rsp(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EFAULT); } /* * UA_RKMM_DEREG_REQ * ------------------------------------------------------------------------- */ static int m2ua_recv_dereg_req(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EFAULT); } /* * UA_RKMM_DEREG_RSP * ------------------------------------------------------------------------- */ static int m2ua_recv_dereg_rsp(sgp_t * sgp, mblk_t * msg) { (void) q; (void) msg; return (-EFAULT); } /* * Common defined ASP/SGP management procedures. */ extern int (*ua_sgp_mgmt[]) (sgp_t *, mblk_t *); extern int (*ua_sgp_asps[]) (sgp_t *, mblk_t *); extern int (*ua_sgp_aspt[]) (sgp_t *, mblk_t *); static int (*m2ua_maup[]) (sgp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ m2ua_recv_data, /* M2UA_MAUP_DATA 0x1 */ m2ua_recv_estab_req, /* M2UA_MAUP_ESTAB_REQ 0x2 */ m2ua_recv_estab_con, /* M2UA_MAUP_ESTAB_CON 0x3 */ m2ua_recv_rel_req, /* M2UA_MAUP_REL_REQ 0x4 */ m2ua_recv_rel_con, /* M2UA_MAUP_REL_CON 0x5 */ m2ua_recv_rel_ind, /* M2UA_MAUP_REL_IND 0x6 */ m2ua_recv_state_req, /* M2UA_MAUP_STATE_REQ 0x7 */ m2ua_recv_state_con, /* M2UA_MAUP_STATE_CON 0x8 */ m2ua_recv_state_ind, /* M2UA_MAUP_STATE_IND 0x9 */ m2ua_recv_retr_req, /* M2UA_MAUP_RETR_REQ 0xa */ m2ua_recv_retr_con, /* M2UA_MAUP_RETR_CON 0xb */ m2ua_recv_retr_ind, /* M2UA_MAUP_RETR_IND 0xc */ m2ua_recv_retr_comp_ind, /* M2UA_MAUP_RETR_COMP_IND 0xd */ m2ua_recv_cong_ind, /* M2UA_MAUP_CONG_IND 0xe */ m2ua_recv_data_ack /* M2UA_MAUP_DATA_ACK 0xf */ }; static int (*m2ua_rkmm[]) (sgp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ m2ua_recv_reg_req, /* UA_RKMM_REG_REQ 0x1 */ m2ua_recv_reg_rsp, /* UA_RKMM_REG_RSP 0x2 */ m2ua_recv_dereg_req, /* UA_RKMM_DEREG_REQ 0x3 */ m2ua_recv_dereg_rsp /* UA_RKMM_DEREG_RSP 0x4 */ }; static struct msg_class msg_decode[] = { {ua_sgp_mgmt, UA_MGMT_LAST}, /* UA_CLASS_MGMT 0x0 */ {NULL, 0}, /* UA_CLASS_XFER 0x1 */ {NULL, 0}, /* UA_CLASS_SNMM 0x2 */ {ua_sgp_asps, UA_ASPS_LAST}, /* UA_CLASS_ASPS 0x3 */ {ua_sgp_aspt, UA_ASPT_LAST}, /* UA_CLASS_ASPT 0x4 */ {NULL, 0}, /* UA_CLASS_Q921 0x5 */ {m2ua_maup, M2UA_MAUP_LAST}, /* UA_CLASS_MAUP 0x6 */ {NULL, 0}, /* UA_CLASS_CNLS 0x7 */ {NULL, 0}, /* UA_CLASS_CONS 0x8 */ {m2ua_rkmm, UA_RKMM_LAST}, /* UA_CLASS_RKMM 0x9 */ {NULL, 0}, /* UA_CLASS_TDHM 0xa */ {NULL, 0} /* UA_CLASS_TCHM 0xb */ }; int m2ua_sgp_recv_msg(sgp_t * sgp, mblk_t * msg) { return ua_recv_msg(q, msg, msg_decode); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |