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_sgp.c#ident "@(#) $RCSfile: ua_sgp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $" static char const ident[] = "$RCSfile: ua_sgp.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:46 $"; #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 "../ua/ua_data.h" #include "../ua/ua_msg.h" //#include "../ua/ua_sm.h" /* * ========================================================================= * * UA Peer --> UA (SGP) Received Messages * * ========================================================================= * * These are procedures for common UA received messages at the SGP. */ /* * ASPS ASPUP * ------------------------------------------------------------------------- * ASP Identifier Optional (But must be used sometimes) * ASP Capabilities Optional * Info String Optional */ static int ua_recv_aspup_req(sgp_t * sgp, mblk_t * mp) { pp_t *pp = (pp_t *) q->q_ptr; sp_t *sp = pp->u.sp; mblk_t *rp; struct ua_parm *aspid = &ua_parm_results.aspid; struct ua_parm *asp_caps = &ua_parm_results.asp_caps; ua_decode_parms(mp); if (!aspid->u.wptr) { if (!sp || !sp->aspid) { if (!(rp = ua_mgmt_err(SUA_ECODE_REFUSED_ASP_IDENTIFIER_REQUIRED))) return (-ENOBUFS); qreply(q, rp); return (-EINVAL); } } else { if (sp) { if (sp->lp || (sp->aspid && sp->aspid != aspid->val)) { if (!(rp = ua_mgmt_err(SUA_ECODE_ERROR_INVALID_ASP_IDENTIFIER))) return (-ENOBUFS); qreply(q, rp); return (-EINVAL); } } else { for (sp = asp_head; sp && sp->aspid != aspid->val; sp = sp->next); if (!sp) for (sp = sgp_head; sp && sp->aspid != aspid->val; sp = sp->next); if (!sp) for (sp = spp_head; sp && sp->aspid != aspid->val; sp = sp->next); if (!sp || sp->lp) { if (!(rp = ua_mgmt_err(SUA_ECODE_ERROR_INVALID_ASP_IDENTIFIER))) return (-ENOBUFS); qreply(q, rp); return (-EINVAL); } pp->u.sp = sp; sp->lp = pp; } sp->aspid = aspid->val; } if (!asp_caps->u.wptr) { if (sp->asp_caps) *(asp_caps->u.wptr) = htonl(sp->asp_caps); } else { if (sp->asp_caps) { if (sp->asp_caps != asp_caps->val) *(asp_caps->u.wptr) = htonl(sp->asp_caps); } else sp->asp_caps = asp_caps->val; } sp->state = ASP_STATE_INACTIVE; if ((err = asp_recalc_as_state(sp))) return (err); *((long *) mp->b_rptr) = SUA_ASPS_ASPUPAC; qreply(q, mp); return (0); } /* * ASPS ASPDN * ------------------------------------------------------------------------- */ static int ua_recv_aspdn_req(sgp_t * sgp, mblk_t * mp) { /* * This ASP is toast. Return ASPDN Ack and mark ASP_STATE_DOWN. * Recalculate AS status. */ freemsg(mp); return (0); } /* * ASPS HBEAT * ------------------------------------------------------------------------- * Heartbeat Data Optional */ static int ua_recv_hbeat_req(sgp_t * sgp, mblk_t * mp) { /* * This is a simple matter of turning around the heartbeat request. * We can just jam the message type and send it back. Don't even * pull out the parameters. */ (void) q; (void) mp; return (-EOPNOTSUPP); } /* * ASPS HBEAT Ack * ------------------------------------------------------------------------- * Heartbeat Data Optional */ static int ua_recv_hbeat_ack(sgp_t * sgp, mblk_t * mp) { /* * Check the heartbeat data. There are a number of occasions for * which we send heartbeats. There is a process waiting for the * response based on the heartbeat data or there is not. This needs * be done in parallel for some applications (changeback). We should * have a process list with ids from the data. That way we could use * the data to index the function to call here... * * Well..., normally we do this to flush an routing context traffic * flow. If there is heartbeat data, extract the routing contexts * out of the heartbeat data and find AS in the AS_WACK_BEAT state. */ (void) q; (void) mp; return (-EOPNOTSUPP); } /* * ASPT ASPAC * ------------------------------------------------------------------------- * Traffic Mode Type Mandatory * Routing Context Optional * INFO String Optional */ static int ua_recv_aspac_req(sgp_t * sgp, mblk_t * mp) { int i; struct ua_parm *rc = &ua_parm_results.rc; ua_decode_parm_results(mp); if (rc->u.wptr && rc->len > 4) { int i; uint32_t *p = rc->u.wptr; for (i = 0, p = rc->u.wptr; i < (rc->len / 4) - 1; i++, p++) { uint32_t rcval = ntohl(*p++); /* * Perform the ASPAC procedures. Traffic Mode is * mandatory, but I don't care when I know the mode * of the AS from configuration data. We must return * either en ASPAC Ack or an ERR. Move the ASP to * active in the indicated AS. Well..., just move * the ASP to the ASP-ACTIVE state and make sure that * we have the AS in the ASPs AS list. Do a state * recalc on all the AS in the AS list. */ } } else { } freemsg(mp); return (0); } /* * ASPT ASPIA * ------------------------------------------------------------------------- * Routing Context Optional * INFO String Optional */ static int ua_recv_aspia_req(sgp_t * sgp, mblk_t * mp) { int i; struct ua_parm *rc = &ua_parms.rc; ua_decode_parms(mp); if (rc->u.wptr && rc->len > 4) { int i; uint32_t *p = rc->u.wptr; for (i = 0, p = rc->u.wptr; i < (rc->len / 4) - 1; i++, p++) { uint32_t rcval = ntohl(*p++); /* * Check for AS which belong to the ASP by routing * context. Place them in the state * AS_STATE_INACTIVE. ALWAYS respond with an ASPIA * Ack. Put it back if we can't. */ } } else { } freemsg(mp); return (0); } /* * MGMT ERR * ------------------------------------------------------------------------- * Error Code Mandatory * Diagnostic Info Optional */ static int ua_recv_err(sgp_t * sgp, mblk_t * mp) { sp_t *sp = ((pp_t *) q->q_ptr)->u.sp; ua_decode_parms(mp); if (!ua_parms.ecode.u.wptr) return -EINVAL; switch (ua_parms.ecode.val) { /* * These values are from ua-07. */ case 0x01: /* Invalid Version */ case 0x05: /* Unsupported Traffic Handling Mode */ case 0x08: /* Invalid Routing Context */ /* * If I am trying something, give up. */ case 0x0c: /* Unexpected Parameter */ /* * TODO: Might be because we a using an extension * that the other end doesn't recognize. Go after * the diagnostics parameter and see if we get the * parameter. Then see if we can discover features * of the other end from which parameter was * unexpected. */ default: case 0x02: /* n/a */ case 0x03: /* Unexpected Message Class */ case 0x04: /* Invalid Message Type Class */ case 0x06: /* Unexpected Message */ case 0x07: /* Protocol Error */ case 0x09: /* Invalid Stream Identifier */ case 0x0b: /* Parameter Field Error */ case 0x0d: /* Duplicated Parameter */ case 0x0e: /* Error - ASP Identifier Required */ case 0x0f: /* Error - Invalid ASP Identifier */ case 0x10: /* Refused - ASP Identifier Required */ /* * Some of these can't happen (we always send * optional fields). Don't give up. */ } /* * TODO: Notify management. */ freemsg(mp); return (0); } /* * MGMT ERR * ------------------------------------------------------------------------- * IMPLEMENTATION NOTE:- We want to report all errors to management. Some * errors are considered fatal errors. That is we will stop all processes, * and put everything associated with the ASP/SGP/SP into the Down state, * even drop the SCTP association. */ static int m3ua_err(sgp_t * sgp, mblk_t * mp) { m3ua_parms_t parms; parm_t *ecode = &parms->common.ecode; parm_t *diag = &parms->common.diag; m3ua_decode_parms(msg, &parms); if (!ecode->u.wptr) { /* missing mandatory parameter */ return (-EINVAL); } switch (*ecode->u.wptr) { case UA_ECODE_INVALID_VERSION: case UA_ECODE_INVALID_IID_OR_NTWK_APP: case UA_ECODE_UNSUPPORTED_MESSAGE_CLASS: case UA_ECODE_UNSUPPORTED_MESSAGE_TYPE: case UA_ECODE_UNSUPPORTED_TRAFFIC_MODE: case UA_ECODE_UNEXPECTED_MESSAGE: case UA_ECODE_PROTOCOL_ERROR: case UA_ECODE_INVALID_ROUTING_CONTEXT: case UA_ECODE_INVALID_STREAM_IDENTIFIER: case UA_ECODE_INVALID_PARAMETER_VALUE: case M3UA_ECODE_REFUSED_MANAGEMENT_BLOCKING: case M3UA_ECODE_UNKNOWN_ROUTING_CONTEXT: case M3UA_ECODE_INVALID_ASPID: default: /* error invalid error???? */ return (-EINVAL); } return (-EOPNOTSUPP); } int (*ua_sgp_mgmt[]) (sgp_t *, mblk_t *) = { ua_recv_err, /* UA_MGMT_ERR 0x0 */ NULL /* UA_MGMT_NTFY 0x1 */ }; int (*ua_sgp_asps[]) (sgp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ ua_recv_aspup_req, /* UA_ASPS_ASPUP_REQ 0x1 */ ua_recv_aspdn_req, /* UA_ASPS_ASPDN_REQ 0x2 */ ua_recv_beat_req, /* UA_ASPS_HBEAT_REQ 0x3 */ NULL, /* UA_ASPS_ASPUP_ACK 0x4 */ NULL, /* UA_ASPS_ASPDN_ACK 0x5 */ ua_recv_beat_ack /* UA_ASPS_HBEAT_ACK 0x6 */ }; int (*ua_sgp_aspt[]) (sgp_t *, mblk_t *) = { NULL, /* (reserved) 0x0 */ ua_recv_aspac_req, /* UA_ASPT_ASPAC_REQ 0x1 */ ua_recv_aspia_req, /* UA_ASPT_ASPIA_REQ 0x2 */ NULL, /* UA_ASPT_ASPAC_ACK 0x3 */ NULL /* UA_ASPT_ASPIA_ACK 0x4 */ };
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |