|
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. |
|||||||||||||||||||||||||||