OpenSS7
SS7 for the
Common Man

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified:

Home Overview Status News Documentation Resources About
   
 Overview
 Status
 News
 Documentation
 Resources
 About

   
Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/sigtran/m2ua.c


File /code/strss7/drivers/sigtran/m2ua.c


#ident "@(#) $RCSfile: m2ua.c,v $ $Name:  $($Revision: 0.8.2.3 $) $Date: 2003/04/03 19:51:06 $"

static char const ident[] =
    "$RCSfile: m2ua.c,v $ $Name:  $($Revision: 0.8.2.3 $) $Date: 2003/04/03 19:51:06 $";

#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 <sys/dki.h>

#include "../debug.h"
#include "../bufq.h"

#include "ua.h"
#include "ua_data.h"
#include "ua_msgs.h"
#include "m2ua_msgs.h"

#ifndef INT
#define INT void
#endif

/*
 *  =========================================================================
 *
 *  OUTPUT Events
 *
 *  =========================================================================
 */
/*
 *  M2UA --> LM Primitives
 *  -----------------------------------
 */
static int lm_ok_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lm_ok_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_OK_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lm_error_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lm_error_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_ERROR_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lm_reg_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lm_reg_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_REG_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int lm_dereg_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lm_dereg_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_DEREG_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int lm_error_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lm_error_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->prim = LM_ERROR_IND;

		putq(q, mp);
	}
	return (rtn);
}

/*
 *  M2UA --> SLP Primitives
 *  -----------------------------------
 *  These are primitives that the M2UA layer sends to the SLP (Signalling Link
 *  Provider) at the SGP as part of the NIF (Nodal Interworking Function).
 *  All of these functions take the WR(q) for the SLP plus a mblk that might
 *  possibly be reused.  Most of these functions attempt to reuse the mblk (if
 *  provided) for speed.
 */
static int lmi_info_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_info_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_INFO_REQ;

		putq(q, mp);
	}
	return (rtn);
}

#if 0
/* these are done by the layer manager when linking */
static int lmi_attach_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_attach_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_ATTACH_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_detach_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_detach_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_INFO_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_enable_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_enable_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_ENABLE_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_disable_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_disable_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_DISABLE_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_optmgmt_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_optmgmt_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_OPTMGMT_REQ;

		putq(q, mp);
	}
	return (rtn);
}
#endif
static int sl_pdu_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_pdu_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_emergency_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_emergency_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_EMERGENCY_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_emergency_ceases_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_emergency_ceases_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_EMERGENCY_CEASES_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_start_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_start_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_START_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_stop_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_stop_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_STOP_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_retrieve_bsnt_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_retrieve_bsnt_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVE_BSNT_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_retrieval_request_and_fsnc_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_retrieval_request_and_fsnc_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVAL_REQUEST_AND_FSNC_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_resume_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_resume_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RESUME_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_clear_buffers_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_clear_buffers_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_CLEAR_BUFFERS_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_clear_rtb_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_clear_rtb_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_CLEAR_RTB_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_local_processor_outage_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_local_processor_outage_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_LOCAL_PROCESSOR_OUTAGE_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_congestion_discard_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_congestion_discard_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_CONGESTION_DISCARD_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_congestion_accept_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_congestion_accept_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_CONGESTION_ACCEPT_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_no_congestion_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_no_congestion_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_NO_CONGESTION_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_power_on_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_power_on_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_POWER_ON_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_optmgmt_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_optmgmt_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_OPTMGMT_REQ;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_notify_req(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_notify_req_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_NOTIFY_REQ;

		putq(q, mp);
	}
	return (rtn);
}

/*
 *  M2UA --> SLU Primitives
 *  -----------------------------------
 *  These are primitives that are sent from M2UA at the ASP to the SLU
 *  (Signalling Link User) at the ASP.
 */
static int lmi_info_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_info_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_INFO_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_ok_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_ok_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_OK_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_error_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_error_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_ERROR_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_enable_con(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_enable_con_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_ENABLE_CON;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_disable_con(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_disable_con_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_DISABLE_CON;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_optmgmt_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_optmgmt_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_OPTMGMT_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_error_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_info_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_ERROR_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_stats_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_stats_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_STATS_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int lmi_event_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	lmi_event_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->lmi_primitive = LMI_EVENT_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_pdu_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_pdu_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_link_congested_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_link_congested_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_LINK_CONGESTED_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_link_congestion_ceased_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_link_congestion_ceased_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_LINK_CONGESTION_CEASED_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_retrieved_message_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_retrieved_message_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVED_MESSAGE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_retrieval_complete_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_retrieval_complete_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVAL_COMPLETE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_rb_cleared_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_rb_cleared_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RB_CLEARED_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_bsnt_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_bsnt_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_BSNT_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_in_service_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_in_service_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_IN_SERVICE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_out_of_service_ind {
	int rtn;
	sl_out_of_service_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_OUT_OF_SERVICE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_remote_processor_outage_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_remote_processor_outage_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_REMOTE_PROCESSOR_OUTAGE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_remote_processor_recovered_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_remote_processor_recovered_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_REMOTE_PROCESSOR_RECOVERED_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_rtb_cleared_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_rtb_cleared_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RTB_CLEARED_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_retrieval_not_possible_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_retrieval_not_possible_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVAL_NOT_POSSIBLE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_bsnt_not_retrievable_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_bsnt_not_retrievable_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_BSNT_NOT_RETRIEVABLE_IND;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_optmgmt_ack(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_optmgmt_ack_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_OPTMGMT_ACK;

		putq(q, mp);
	}
	return (rtn);
}
static int sl_notify_ind(queue_t * q, mblk_t * mp)
{
	int rtn;
	sl_notify_ind_t *p;
	if ((rtn = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_NOTIFY_IND;

		putq(q, mp);
	}
	return (rtn);
}

/*
 *  =========================================================================
 *
 *  STREAMS Message Handling
 *
 *  =========================================================================
 *
 *  Signalling Link User (SLU) Stream Message Handling
 *
 *  -------------------------------------------------------------------------
 *
 *  SL User --> M2UA Primitives
 *  -----------------------------------
 *  This is the SLU upper write routines.  This takes SLU primitives and
 *  converts them to M2UA M_DATA and M_CTL messages, if required.  If the
 *  provider is a local SG, then the primitives are forwarded as is.
 *
 *  These are primitives sent from a local SL user to the M2UA layer on the
 *  upper mux stream.  This is part of the Adaptation Layer at an ASP
 *  (Application Server Process).  Each message is converted from an SLU
 *  request or reqponse primitive to an M2UA message.  These functions are
 *  pure translation only.  When they return zero, they return the SL
 *  primitive translated in `mpp'.  When they return non-zero, they return an
 *  error and `mpp' is untouched.
 */
static int slu_info_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_info_req_t *p = (lmi_info_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_INFO_REQ, err);
}
static int slu_attach_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_attach_req_t *p = (lmi_attach_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
			if (dp->l.state == LMI_UNATTACHED) {
			}
			err = LMI_OUTSTATE;
			break;	/* interface out of state */
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_ATTACH_REQ, err);
}
static int slu_detach_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_detach_req_t *p = (lmi_detach_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
			if (dp->l.state == LMI_DISABLED) {
			}
			err = LMI_OUTSTATE;
			break;	/* interface out of state */
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_DETACH_REQ, err);
}
static int slu_enable_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_enable_req_t *p = (lmi_enable_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
			if (dp->l.state == LMI_DISABLED) {
			}
			err = LMI_OUTSTATE;
			break;	/* interface out of state */
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_ENABLE_REQ, err);
}
static int slu_disable_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_disable_req_t *p = (lmi_disable_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
			if (dp->l.state == LMI_ENABLED) {
			}
			err = LMI_OUTSTATE;
			break;	/* interface out of state */
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_DISABLE_REQ, err);
}
static int slu_optmgmt_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	lmi_optmgmt_req_t *p = (lmi_optmgmt_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, LMI_OPTMGMT_REQ, err);
}

static int slu_pdu_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 7 * sizeof(uint32_t);
	size_t dlen = msgdsize((*mpp)->b_cont);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_DATA;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen + PAD4(dlen));
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_CORR_ID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->cid++);
		fixme(("Make choice of DATA1 or DATA 2 based on protocol variant\n"));
		*((uint32_t *) mp->b_wptr)++ = UA_PHDR(M2UA_MAUP_DATA1, dlen);
		fixme(("Pad data buffer\n"));
		mp->b_cont = *mpp->b_cont;
		*mpp->b_cont = NULL;
		*mpp = mp;
		fixme(("Place a copy in the rtb for the as until acked\n"));
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_emergency_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_EMER_SET);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_emergency_ceases_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_EMER_CLEAR);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_start_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_ESTAB_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_stop_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_REL_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_retrieve_bsnt_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_ACTION;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_ACTION_RTRV_BSN);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_retrieval_request_and_fsnc_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 8 * sizeof(uint32_t);
	sl_retrieval_req_and_fsnc_t *p = (sl_retrieval_req_and_fsnc_t *) (*mpp)->b_rptr;
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_ACTION;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_ACTION_RTRV_MSGS);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_SEQNO;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_fsnc);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_resume_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CONTINUE);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_clear_buffers_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_FLUSH_BUFFERS);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_clear_rtb_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CLEAR_RTB);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_local_processor_outage_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_LPO_SET);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_congestion_discard_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CONG_DISCARD);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_congestion_accept_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CONG_ACCEPT);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}
static int slu_no_congestion_req(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_CTL;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_REQ;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b - wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CONG_CLEAR);
		*mpp = mp;
		return (0);
	}
	return (-ENOBUFS);
}

static int slu_xlat(as_t * as, mblk_t ** mpp)
{
	swtich(*((long *) (*mpp)->b_rptr)) {
case SL_PDU_REQ:
		return slu_pdu_req(as, mpp);
case SL_EMERGENCY_REQ:
		return slu_emergency_req(as, mpp);
		case SL_EMERGENCY_CEASES_REQ::return slu_emergency_ceases_req(as, mpp);
case SL_START_REQ:
		return slu_start_req(as, mpp);
case SL_STOP_REQ:
		return slu_stop_req(as, mpp);
case SL_RETRIEVE_BSNT_REQ:
		return slu_retrieve_bsnt_req(as, mpp);
case SL_RETRIEVAL_REQUEST_AND_FSNC_REQ:
		return slu_retrieval_request_and_fsnc_req(as, mpp);
case SL_RESUME_REQ:
		return slu_resume_req(as, mpp);
case SL_CLEAR_BUFFERS_REQ:
		return slu_clear_buffers_req(as, mpp);
case SL_CLEAR_RTB_REQ:
		return slu_clear_rtb_req(as, mpp);
case SL_LOCAL_PROCESSOR_OUTAGE_REQ:
		return slu_local_processor_outage_req(as, mpp);
case SL_CONGESTION_DISCARD_REQ:
		return slu_congestion_discard_req(as, mpp);
case SL_CONGESTION_ACCEPT_REQ:
		return slu_congestion_accept_req(as, mpp);
case SL_NO_CONGESTION_REQ:
		return slu_no_congestion_req(as, mpp);
case SL_POWER_ON_REQ:
		return slu_power_on_req(as, mpp);
case SL_OPTMGMT_REQ:
		return slu_optmgmt_req(as, mpp);
case SL_NOTIFY_REQ:
		return slu_notify_req(as, mpp);
	}
	return (-EOPNOTSUPP);
}
static int slu_xlat_prim(queue_t * q, mblk_t * mp)
{
	int err;
	xp_t *xp;
	pp_t *pp;
	as_t *as;
	dp_t *dp = (dp_t *) q->q_ptr;
	ensure(q, return (-EFAULT));
	ensure(dp, return (-EFAULT));
	if (dp->l.state != LMI_ENABLED)
		return (0);
	if (!(as = ua_pp_route(dp)))
		return (0);
	if ((pp = ua_as_route_loc(as))) {
		if (mp->b_datap->db_type < QPCTL && !canput(pp->wq))
			return (-EBUSY);
		putq(pp->wq, mp);
		return (1);
	}
	if ((xp = ua_as_route_rem(as))) {
		if (!(pp = xp->pp.pp)) {
			ptrace(("Have route to XP but no LP\n"));
			return (-EFAULT);
		}
		if (mp->b_datap->db_type < QPCTL && !canput(pp->wq))
			return (-EBUSY);
		if ((err = slu_xlat(as, &mp)))
			return (err);
		putq(pp->wq, mp);
		return (1);
	}
	ptrace(("AS-U marked active but no active AS-P\n"));
	return (-EFAULT);
}
static int slu_power_on_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	sl_power_on_req_t *p = (sl_power_on_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
			if (dp->l.state == LMI_ENABLED) {
				if (as && as->as && as->asac_count) {
				}
				return (0);	/* ignore unless active */
			}
			return (0);	/* ignore unless enabled */
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, SL_POWER_ON_REQ, err);
}
static int slu_optmgmt_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	sl_optmgmt_req_t *p = (sl_optmgmt_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, SL_OPTMGMT_REQ, err);
}
static int slu_notify_req(queue_t * q, mblk_t * mp)
{
	dp_t *dp = (dp_t *) q->q_ptr;
	as_t *as = dp->u.as;
	size_t mlen = mp->b_wptr - mp->b_rptr;
	sl_notify_req_t *p = (sl_notify_req_t *) mp->b_rptr;
	do {
		if (mlen >= sizeof(*p)) {
		}
		err = -EMSGSIZE;
		break;		/* the message size is invalid */
	} while (0);
	return lmi_error_ack_reply(q, mp, SL_NOTIFY_REQ, err);
}
static int m2ua_u_w_ioctl(queue_t * q, mblk_t * mp)
{
}
static int m2ua_u_w_data(queue_t * q, mblk_t * dp)
{
	/* 
	 *  Need to convert data to SL_PDU_REQ.
	 */
	int rtn;
	mblk_t *mp;
	sl_pdu_req_t *p;
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_REQ;
		mp->b_cont = dp;
		switch ((rtn = slu_pdu_req(q, mp))) {
		}
		return (1);
	}
	return (-ENOBUFS);
}
static int m2ua_u_w_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case LMI_INFO_REQ:
		return slu_info_req(q, mp);
	case LMI_ATTACH_REQ:
		return slu_attach_req(q, mp);
	case LMI_DETACH_REQ:
		return slu_detach_req(q, mp);
	case LMI_ENABLE_REQ:
		return slu_enable_req(q, mp);
	case LMI_DISABLE_REQ:
		return slu_disable_req(q, mp);
	case LMI_OPTMGMT_REQ:
		return slu_optmgmt_req(q, mp);
	case SL_PDU_REQ:
	case SL_EMERGENCY_REQ:
	case SL_EMERGENCY_CEASES_REQ::case SL_START_REQ:
	case SL_STOP_REQ:
	case SL_RETRIEVE_BSNT_REQ:
	case SL_RETRIEVAL_REQUEST_AND_FSNC_REQ:
	case SL_RESUME_REQ:
	case SL_CLEAR_BUFFERS_REQ:
	case SL_CLEAR_RTB_REQ:
	case SL_LOCAL_PROCESSOR_OUTAGE_REQ:
	case SL_CONGESTION_DISCARD_REQ:
	case SL_CONGESTION_ACCEPT_REQ:
	case SL_NO_CONGESTION_REQ:
		return slu_xlat_prim(q, mp);
	case SL_POWER_ON_REQ:
		return slu_power_on_req(q, mp);
	case SL_OPTMGMT_REQ:
		return slu_optmgmt_req(q, mp);
	case SL_NOTIFY_REQ:
		return slu_notify_req(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int m2ua_u_w_pcproto(queue_t * q, mblk_t * mp)
{
	return m2ua_u_w_proto(q, mp);
}
static int m2ua_u_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return m2ua_u_w_data(q, mp);
	case M_PROTO:
		return m2ua_u_w_proto(q, mp);
	case M_PCPROTO:
		return m2ua_u_w_pcproto(q, mp);
	case M_IOCTL:
		return m2ua_u_w_ioctl(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

/*
 *  M2UA --> SL User Primitives
 *  -------------------------------------------------------------------------
 *  This is the SLU upper read primitive routines.  This takes M2UA M_DATA and
 *  M_CTL blocks and converts them to SL User primitives.
 *
 *  These are primitives sent to a local SL User from the M2UA layer on the
 *  upper mux stream.  This is part of the Adaptation Layer at an ASP
 *  (Application Server Process).  Each message is converted from an M2UA
 *  message to an SL indication or confirmation primitive.  These functions
 *  are pure translation functions.  When they return zero, they return the
 *  M2UA message translated in `mpp'.  When they return negative, they return
 *  an error and `mpp' is untouched.
 */
static int m2ua_mgmt_err(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received MGMT ERR at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_mgmt_ntfy(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received MGMT NTFY at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_asps_aspup_ack(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received ASPUP ACK at upper RD(q)\n"));
	return (-EFAULT);

}
static int m2ua_asps_aspdn_ack(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received ASPDN ACK at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_asps_r_hbeat_req(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received HBEAT REQ at upper RD(q)\n"));
	fixme(("This might not be an error\n"));
	return (-EFAULT);
}
static int m2ua_asps_r_hbeat_ack(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received HBEAT ACK at upper RD(q)\n"));
	fixme(("This might not be an error\n"));
	return (-EFAULT);
}
static int m2ua_aspt_aspac_ack(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received ASPAC ACK at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_aspt_aspia_ack(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received ASPIA ACK at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_maup_r_data(queue_t * q, mblk_t * dp)
{
	mblk_t *mp;
	sl_dpu_ind_t *p;
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_IND;
		fixme(("Trim to just data\n"));
		mp->b_cont = dp;
		putq(q, mp);
		return (1);
	}
	return (-ENOBUFS);
}
static int m2ua_maup_r_data_ack(queue_t * q, mblk_t * dp)
{
}
static int m2ua_maup_estab_con(queue_t * q, mblk_t * mp)
{
	int err;
	sl_in_service_ind_t *p;
	if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_IN_SERVICE_IND;
		putq(q, mp);
	}
	return (err);
}
static int m2ua_maup_rel_con(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	return (0);
}
static int m2ua_maup_rel_ind(queue_t * q, mblk_t * mp)
{
	int err;
	sl_out_of_service_ind_t *p;
	if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_OUT_OF_SERVICE_IND;
		p->sl_timestamp = jiffies;
		p->sl_reason = 0;
		putq(q, mp);
	}
	return (err);
}
static int m2ua_maup_state_con(queue_t * q, mblk_t * mp)
{
	switch (status) {
	case M2UA_STATUS_FLUSH_BUFFERS:
	{
		int err;
		sl_rb_cleared_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_RB_CLEARED_IND;
			putq(q, mp);
		}
		return (err);
	}
	case M2UA_STATUS_CLEAR_RTB:
	{
		int err;
		sl_rtb_cleared_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_RTB_CLEARED_IND;
			putq(q, mp);
		}
		return (err);
	}
	default:
	case M2UA_STATUS_LPO_SET:
	case M2UA_STATUS_LPO_CLEAR:
	case M2UA_STATUS_EMER_SET:
	case M2UA_STATUS_EMER_CLEAR:
	case M2UA_STATUS_CONTINUE:
	case M2UA_STATUS_AUDIT:
	case M2UA_STATUS_CONG_CLEAR:
	case M2UA_STATUS_CONG_ACCEPT:
	case M2UA_STATUS_CONG_DISCARD:
		return (0);
	}
	return (-EFAULT);
}
static int m2ua_maup_state_ind(queue_t * q, mblk_t * mp)
{
	switch (event) {
	case M2UA_EVENT_RPO_ENTER:
	{
		int err;
		sl_rem_proc_out_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, *mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_REMOTE_PROCESSOR_OUTAGE_IND;
			putq(q, mp);
		}
		return (err);
	}
	case M2UA_EVENT_RPO_EXIT:
	{
		int err;
		sl_rem_proc_recovered_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, *mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_REMOTE_PROCESSOR_RECOVERED_IND;
			putq(q, mp);
		}
		return (err);
	}
	case M2UA_EVENT_LPO_ENTER:
	{
		int err;
		sl_loc_proc_out_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, *mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_LOCAL_PROCESSOR_OUTAGE_IND;
			putq(q, mp);
		}
		return (err);
	}
	case M2UA_EVENT_LPO_EXIT:
	{
		int err;
		sl_loc_proc_recovered_ind_t *p;
		if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, *mp)) >= 0) {
			mp->b_datap->db_type = M_PROTO;
			p = ((typeof(p)) mp->b_wptr)++;
			p->sl_primitive = SL_LOCAL_PROCESSOR_RECOVERED_IND;
			putq(q, mp);
		}
		return (err);
	}
	}
	return (-EFAULT);
}
static int m2ua_maup_retr_con(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	return (0);
}
static int m2ua_maup_retr_ind(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("We don't do retrieval\n"));
	return (-EFAULT);
}
static int m2ua_maup_retr_comp_ind(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("We don't do retrieval\n"));
	return (-EFAULT);
}
static int m2ua_maup_cong_ind(queue_t * q, mblk_t * mp)
{
	int err;
	sl_congestion_ind_t *p;
	if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, *mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_CONGESTION_IND;
		p->sl_cong_level = cong;
		p->sl_disc_level = disc;
		putq(q, mp);
	}
	return (err);
}
static int m2ua_rkmm_reg_rsp(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received REG RSP at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_rkmm_dereg_rsp(queue_t * q, mblk_t * dp)
{
	(void) q;
	(void) dp;
	ptrace(("Received DEREG RSP at upper RD(q)\n"));
	return (-EFAULT);
}
static int m2ua_r_msg(queue_t * q, mblk_t * mp)
{
	uint32_t mhdr = *((uint32_t *) mp->b_rptr);
	switch (UA_MSG_CLAS(mhdr)) {
	case UA_CLASS_MGMT:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_MGMT_ERR):
			return m2ua_mgmt_err(q, mp);
		case UA_MSG_TYPE(UA_MGMT_NTFY):
			return m2ua_mgmt_ntfy(q, mp);
		}
		ptrace(("Unexpected MGMT message\n"));
		break;
	case UA_CLASS_XFER:
		ptrace(("Unexpected XFER message\n"));
		break;
	case UA_CLASS_SNMM:
		ptrace(("Unexpected SNMM message\n"));
		break;
	case UA_CLASS_ASPS:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_ASPS_ASPUP_REQ):
		case UA_MSG_TYPE(UA_ASPS_ASPDN_REQ):
			break;
		case UA_MSG_TYPE(UA_ASPS_ASPUP_ACK):
			return m2ua_asps_aspup_ack(q, mp);
		case UA_MSG_TYPE(UA_ASPS_ASPDN_ACK):
			return m2ua_asps_aspdn_ack(q, mp);
		case UA_MSG_TYPE(UA_ASPS_HBEAT_REQ):
			return m2ua_asps_r_hbeat_req(q, mp);
		case UA_MSG_TYPE(UA_ASPS_HBEAT_ACK):
			return m2ua_asps_r_hbeat_ack(q, mp);
		}
		ptrace(("Unexpected ASPS message\n"));
		break;
	case UA_CLASS_ASPT:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_ASPT_ASPAC_REQ):
		case UA_MSG_TYPE(UA_ASPT_ASPIA_REQ):
			break;
		case UA_MSG_TYPE(UA_ASPT_ASPAC_ACK):
			return m2ua_aspt_aspac_ack(q, mp);
		case UA_MSG_TYPE(UA_ASPT_ASPIA_ACK):
			return m2ua_aspt_aspia_ack(q, mp);
		default:
		}
		ptrace(("Unexpected ASPS message\n"));
		break;
	case UA_CLASS_Q921:
		ptrace(("Unexpected Q921 message\n"));
		break;
	case UA_CLASS_MAUP:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(M2UA_MAUP_ESTAB_REQ):
		case UA_MSG_TYPE(M2UA_MAUP_REL_REQ):
		case UA_MSG_TYPE(M2UA_MAUP_STATE_REQ):
		case UA_MSG_TYPE(M2UA_MAUP_RETR_REQ):
			break;
		case UA_MSG_TYPE(M2UA_MAUP_DATA):
			return m2ua_maup_r_data(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_DATA_ACK):
			return m2ua_maup_r_data_ack(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_ESTAB_CON):
			return m2ua_maup_estab_con(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_REL_CON):
			return m2ua_maup_rel_con(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_REL_IND):
			return m2ua_maup_rel_ind(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_STATE_CON):
			return m2ua_maup_state_con(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_STATE_IND):
			return m2ua_maup_state_ind(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_RETR_CON):
			return m2ua_maup_retr_con(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_RETR_IND):
			return m2ua_maup_retr_ind(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_RETR_COMP_IND):
			return m2ua_maup_retr_comp_ind(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_CONG_IND):
			return m2ua_maup_cong_ind(q, mp);
		}
		ptrace(("Unexpected MAUP message\n"));
		break;
	case UA_CLASS_CNLS:
		ptrace(("Unexpected CNLS message\n"));
		break;
	case UA_CLASS_CONS:
		ptrace(("Unexpected CONS message\n"));
		break;
	case UA_CLASS_RKMM:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_RKMM_REG_REQ):
		case UA_MSG_TYPE(UA_RKMM_DEREG_REQ):
			break;
		case UA_MSG_TYPE(UA_RKMM_REG_RSP):
			return m2ua_rkmm_reg_rsp(q, mp);
		case UA_MSG_TYPE(UA_RKMM_DEREG_RSP):
			return m2ua_rkmm_dereg_rsp(q, mp);
		}
		ptrace(("Unexpected RKMM message\n"));
		break;
	case UA_CLASS_TDHM:
		ptrace(("Unexpected TDHM message\n"));
		break;
	case UA_CLASS_TCHM:
		ptrace(("Unexpected TCHM message\n"));
		break;
	default:
		ptrace(("Unexpected message class %x\n", mhdr));
		break;
	}
	fixme(("Return error message\n"));
	return (-EPROTO);
}
static int m2ua_u_r_data(queue_t * q, mblk_t * mp)
{
	return m2ua_r_msg(q, mp);
}
static int m2ua_u_r_ctl(queue_t * q, mblk_t * mp)
{
	return m2ua_r_msg(q, mp);
}
static int m2ua_u_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return m2ua_u_r_data(q, mp);
	case M_CTL:
		return m2ua_u_r_ctl(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (5);
}

/*
 *  -------------------------------------------------------------------------
 *
 *  Signalling Link Provider (SLP) Stream Message Handling
 *
 *  -------------------------------------------------------------------------
 *
 *  M2UA --> SL Provider Primitives
 *  -------------------------------------------------------------------------
 *  This is the SLP lower write routine.  This takes M2UA M_DATA and M_CTL
 *  messages and converts them to SL Primitives.
 *
 *  These are primitive sent to a local SL Provider from the M2UA layer on the
 *  lower mux stream.  This is part of the NIF (Nodal Interworking FUnction)
 *  at an SGP (Signalling Gateway Process).  Each message is converted from an
 *  M2UA message to an SL request or response primitive.  These functions are
 *  pure translation functions.  When they return zero, they return the M2UA
 *  message translated in `mpp'.  When they return negative, they return an
 *  error and `mpp' is untouched.
 */
static int m2ua_asps_aspup_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received ASPUP REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_asps_aspdn_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received ASPDN REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_asps_w_hbeat_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received HBEAT REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_asps_w_hbeat_ack(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received HBEAT ACK at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_aspt_aspac_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received ASPAC REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_aspt_aspia_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received ASPIA REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_maup_w_data(queue_t * q, mblk_t * dp)
{
	mblk_t *mp;
	sl_pdu_req_t *p;
	parm_t data;
	fixme(("Make sure that we haven't already written this correlation id first\n"));
	if (!ua_find_parm(dp, M2UA_PARM_DATA1, &data)
	    && !ua_find_parm(dp, M2UA_PARM_DATA2, &data))
		return (-EPROTO);
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_REQ;
		dp->b_rptr = (unsigned char *) data.cptr;
		dp->b_wptr = dp->b_rptr + data.len;
		mp->b_cont = dp;
		putq(q, mp);
		return (1);
	}
	return ua_bufcall(q, sizeof(*p));
}
static int m2ua_maup_w_data_ack(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	fixme(("Make this do something\n"));
	return (-EFAULT);
}
static int m2ua_maup_estab_req(queue_t * q, mblk_t * mp)
{
	int err;
	sl_start_req_t *p;
	if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_START_REQ;
		putq(q, mp);
	}
	return (err);
}
static int m2ua_maup_rel_req(queue_t * q, mblk_t * mp)
{
	int err;
	sl_stop_req_t *p;
	if ((err = ua_reuseb(q, sizeof(*p), BPRI_MED, &mp)) >= 0) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_STOP_REQ;
		putq(q, mp);
	}
	return (err);
}
static int m2ua_maup_state_req(queue_t * q, mblk_t * pdu)
{
	mblk_t *mp;
	union SL_primitives *p;
	if (!(mp = allocb(sizeof(*p), BPRI_MED)))
		return ua_bufcall(q, sizeof(*p));
	mp->b_datap->db_type = M_PROTO;
	p = (typeof(p)) mp->b_wptr;
	switch (status) {
	case __constant_ntohl(STATUS_LPO_SET):
	{
		mp->b_wptr += sizeof(p->loc_proc_out_req);
		p->sl_primitive = SL_LOCAL_PROCESSOR_OUTAGE_REQ;
		break;
	}
	case __constant_ntohl(STATUS_LPO_CLEAR):
	{
		mp->b_wptr += sizeof(p->loc_proc_recovered_req);
		p->sl_primitive = SL_LOCAL_PROCESSOR_RECOVERED_IND;
		break;
	}
	case __constant_ntohl(STATUS_EMER_SET):
	{
		mp->b_wptr += sizeof(p->emergency_req);
		p->sl_primitive = SL_EMERGENCY_REQ;
		break;
	}
	case __constant_ntohl(STATUS_EMER_CLEAR):
	{
		mp->b_wptr += sizeof(p->emergency_ceases_req);
		p->sl_primitive = SL_EMERGENCY_CEASES_REQ;
		break;
	}
	case __constant_ntohl(STATUS_FLUSH_BUFFERS):
	{
		mp->b_wptr += sizeof(p->clear_buffers_req);
		p->sl_primitive = SL_CLEAR_BUFFERS_REQ;
		break;
	}
	case __constant_ntohl(STATUS_CONTINUE):
	{
		mp->b_wptr += sizeof(p->resume_req);
		p->sl_primitive = SL_RESUME_REQ;
		break;
	}
	case __constant_ntohl(STATUS_CLEAR_RTB):
	{
		mp->b_wptr += sizeof(p->clear_rtb_req);
		p->sl_primitive = SL_CLEAR_RTB_REQ;
		break;
	}
	case __constant_ntohl(STATUS_AUDIT):
	{
		p->sl_primitive =;
		break;
	}
	case __constant_ntohl(STATUS_CONG_CLEAR):
	{
		mp->b_wptr += sizeof(p->no_congestion_req);
		p->sl_primitive = SL_NO_CONGESTION_REQ;
		break;
	}
	case __constant_ntohl(STATUS_CONG_ACCEPT):
	{
		mp->b_wptr += sizeof(p->congestion_accept_req);
		p->sl_primitive = SL_CONGESTION_ACCETP_REQ;
		break;
	}
	case __constant_ntohl(STATUS_CONG_DISCARD):
	{
		mp->b_wptr += sizeof(p->congestion_discard_req);
		p->sl_primitive = SL_CONGESTION_DISCARD_REQ;
		break;
	}
	default:
		fixme(("Send an ERR message\n"));
		return (-EPROTO);
	}
	putq(q, mp);
	*((uint32_t *) pdu->b_rptr) = M2UA_MAUP_STATE_CON;
	fixme(("Reply with state confirmation\n"));
	return (1);
}
static int m2ua_maup_retr_req(queue_t * q, mblk_t * pdu)
{
	mblk_t *mp;
	sl_retrieval_req_and_fsnc_req_t *p;
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_RETRIEVAL_REQUEST_AND_FSNC_REQ;
		p->sl_fsnc = fsnc;
		putq(q, mp);
		*((uint32_t *) pdu->b_rptr) = M2UA_MAUP_RETR_CON;
		fixme(("Reply with retrieval confirmation\n"));
		return (1);
	}
	return ua_bufcall(q, sizeof(*p));
}
static int m2ua_rkmm_reg_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received REG REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_rkmm_dereg_req(queue_t * q, mblk_t * mp)
{
	(void) q;
	(void) mp;
	ptrace(("Received DEREG REQ at SLP WR(q)\n"));
	return (-EFAULT);
}
static int m2ua_w_msg(queue_t * q, mblk_t * mp)
{
	uint32_t mhdr = *((uint32_t *) mp->b_rptr);
	switch (UA_MSG_CLAS(mhdr)) {
	case UA_CLASS_MGMT:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_MGMT_ERR):
			/* never return error to error */
			return (0);
		case UA_MSG_TYPE(UA_MGMT_NTFY):
			break;
		}
		ptrace(("Unexpected MGMT message\n"));
		break;
	case UA_CLASS_XFER:
		ptrace(("Unexpected XFER message\n"));
		break;
	case UA_CLASS_SNMM:
		ptrace(("Unexpected SNMM message\n"));
		break;
	case UA_CLASS_ASPS:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_ASPS_ASPUP_ACK):
		case UA_MSG_TYPE(UA_ASPS_ASPDN_ACK):
			break;
		case UA_MSG_TYPE(UA_ASPS_ASPUP_REQ):
			return m2ua_asps_aspup_req(q, mp);
		case UA_MSG_TYPE(UA_ASPS_ASPDN_REQ):
			return m2ua_asps_aspdn_req(q, mp);
		case UA_MSG_TYPE(UA_ASPS_HBEAT_REQ):
			return m2ua_asps_w_hbeat_req(q, mp);
		case UA_MSG_TYPE(UA_ASPS_HBEAT_ACK):
			return m2ua_asps_w_hbeat_ack(q, mp);
		}
		ptrace(("Unexpected ASPS message\n"));
		break;
	case UA_CLASS_ASPT:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_ASPT_ASPAC_ACK):
		case UA_MSG_TYPE(UA_ASPT_ASPIA_ACK):
			break;
		case UA_MSG_TYPE(UA_ASPT_ASPAC_REQ):
			return m2ua_aspt_aspac_req(q, mp);
		case UA_MSG_TYPE(UA_ASPT_ASPIA_REQ):
			return m2ua_aspt_aspia_req(q, mp);
		}
		ptrace(("Unexpected ASPT message\n"));
		break;
	case UA_CLASS_Q921:
		ptrace(("Unexpected Q921 message\n"));
		break;
	case UA_CLASS_MAUP:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(M2UA_MAUP_ESTAB_CON):
		case UA_MSG_TYPE(M2UA_MAUP_REL_CON):
		case UA_MSG_TYPE(M2UA_MAUP_REL_IND):
		case UA_MSG_TYPE(M2UA_MAUP_STATE_CON):
		case UA_MSG_TYPE(M2UA_MAUP_STATE_IND):
		case UA_MSG_TYPE(M2UA_MAUP_RETR_CON):
		case UA_MSG_TYPE(M2UA_MAUP_RETR_IND):
		case UA_MSG_TYPE(M2UA_MAUP_RETR_COMP_IND):
		case UA_MSG_TYPE(M2UA_MAUP_CONG_IND):
			break;
		case UA_MSG_TYPE(M2UA_MAUP_DATA):
			return m2ua_maup_w_data(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_DATA_ACK):
			return m2ua_maup_w_data_ack(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_ESTAB_REQ):
			return m2ua_maup_estab_req(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_REL_REQ):
			return m2ua_maup_rel_req(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_STATE_REQ):
			return m2ua_maup_state_req(q, mp);
		case UA_MSG_TYPE(M2UA_MAUP_RETR_REQ):
			return m2ua_maup_retr_req(q, mp);
		}
		ptrace(("Unexpected MAUP message\n"));
		break;
	case UA_CLASS_CNLS:
		ptrace(("Unexpected CNLS message\n"));
		break;
	case UA_CLASS_CONS:
		ptrace(("Unexpected CONS message\n"));
		break;
	case UA_CLASS_RKMM:
		switch (UA_MSG_TYPE(mhdr)) {
		case UA_MSG_TYPE(UA_RKMM_REG_RSP):
		case UA_MSG_TYPE(UA_RKMM_DEREG_RSP):
			break;
		case UA_MSG_TYPE(UA_RKMM_REG_REQ):
			return m2ua_rkmm_reg_req(q, mp);
		case UA_MSG_TYPE(UA_RKMM_DEREG_REQ):
			return m2ua_rkmm_dereg_req(q, mp);
		}
		ptrace(("Unexpected RKMM message\n"));
		break;
	case UA_CLASS_TDHM:
		ptrace(("Unexpected TDHM message\n"));
		break;
	case UA_CLASS_TCHM:
		ptrace(("Unexpected TCHM message\n"));
		break;
	default:
		ptrace(("Unexpected message class %x\n", mhdr));
		break;
	}
	fixme(("Return error message\n"));
	return (-EPROTO);
}
static int m2ua_l_w_data(queue_t * q, mblk_t * mp)
{
	return m2ua_w_msg(q, mp);
}
static int m2ua_l_w_ctl(queue_t * q, mblk_t * mp)
{
	return m2ua_w_msg(q, mp);
}
static int m2ua_l_w_error(queue_t * q, mblk_t * mp)
{
}
static int m2ua_l_w_hangup(queue_t * q, mblk_t * mp)
{
}
static int m2ua_l_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return m2ua_l_w_data(q, mp);
	case M_CTL:
		return m2ua_l_w_ctl(q, mp);
	case M_ERROR:
		return m2ua_l_w_error(q, mp);
	case M_HANGUP:
		return m2ua_l_w_hangup(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (5);
}

/*
 *  SL Provider --> M2UA Primitives
 *  -------------------------------------------------------------------------
 *  This is the SLP lower read routine.  This takes SL primitives and and
 *  converts them to M2UA M_DATA and M_CTL messages, if required.  If the user
 *  is a local AS, then the primitives are forwarded as is.
 *
 *  These are primitives received by the M2UA layer from the SLP (Signalling
 *  Link Provider) lower mux stream.  This is part of the NIF (Nodal
 *  Interworking Function) at an SGP (Signalling Gateway Process).  Each
 *  message is converted from an SLP indication or confirmation primitive to
 *  an M2UA (SGP->ASP) message.  These functions are pure translation
 *  functions.  When they return zero, they return the SLP primitive
 *  translated into an M2UA message in `mpp'.  When they return negative, they
 *  return an error number and `mpp' is untouched.
 */
static int slp_info_ack(queue_t * q, mblk_t * mp)
{
}
static int slp_ok_ack(queue_t * q, mblk_t * mp)
{
}
static int slp_error_ack(queue_t * q, mblk_t * mp)
{
}
static int slp_enable_con(queue_t * q, mblk_t * mp)
{
}
static int slp_disable_con(queue_t * q, mblk_t * mp)
{
}
static int slp_optmgmt_ack(queue_t * q, mblk_t * mp)
{
}
static int slp_error_ind(queue_t * q, mblk_t * mp)
{
}
static int slp_stats_ind(queue_t * q, mblk_t * mp)
{
}
static int slp_event_ind(queue_t * q, mblk_t * mp)
{
}

static int slp_pdu_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 7 * sizeof(uint32_t);
	size_t dlen = msgdsize((*mpp)->b_cont);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_DATA;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen + PAD4(dlen));
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_CORR_ID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->cid++);
		fixme(("Make choice of DATA1 or DATA2 based on protocol variant\n"));
		*((uint32_t *) mp->b_wptr)++ = UA_PDHR(M2UA_MAUP_DATA1, dlen);
		fixme(("Pad data buffer\n"));
		mp->b_cont = *mpp->b_cont;
		*mpp->b_cont = NULL;
		*mpp = mp;
		fixme(("Place a copy in the rtb for the as until acked\n"));
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen)
}
static int slp_link_congested_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 8 * sizeof(uint32_t);
	sl_link_congested_ind_t *p = ((typeof(p)) (*mpp)->b_rptr);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_CONG_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_CONG_STATUS;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_cong_status);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_DISC_STATUS;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_disc_status);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen)
}
static int slp_link_congestion_ceased_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 8 * sizeof(uint32_t);
	sl_link_congestion_ceased_ind_t *p = ((typeof(p)) (*mpp)->b_rptr);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_CONG_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_CONG_STATUS;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_cong_status);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_DISC_STATUS;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_disc_status);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen)
}
static int slp_retrieved_message_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 5 * sizeof(uint32_t);
	size_t dlen = msgdsize((*mpp)->b_cont);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen + PAD4(dlen));
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		fixme(("Make choice of DATA1 or DATA2 based on protocol variant\n"));
		*((uint32_t *) mp->b_wptr)++ = UA_PDHR(M2UA_MAUP_DATA1, dlen);
		fixme(("Pad data buffer\n"));
		mp->b_cont = *mpp->b_cont;
		*mpp->b_cont = NULL;
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_retrieval_complete_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_COMP_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_rb_cleared_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		fixme(("Is this the correct status?\n"));
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_FLUSH_BUFFERS);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_bsnt_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 10 * sizeof(uint32_t);
	sl_bsnt_ind_t *p = ((typeof(p)) (*mpp)->b_rptr);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_ACTION;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_ACTION_RTR_BSN);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_RETR_RESULT;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_RESULT_SUCCESS);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_SEQNO;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_bsnt);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_in_service_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_ESTAB_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_out_of_service_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 4 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_REL_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*mpp = mp;
		return (0);
	}
	return ua_bufcall(as->ss7->rq, mlen);
}
static int slp_remote_processor_outage_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_EVENT;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_EVENT_RPO_ENTER);
		*mpp = mp;
		return (0);
	}
}
static int slp_remote_processor_recovered_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_IND;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_EVENT;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_EVENT_RPO_EXIT);
		*mpp = mp;
		return (0);
	}
}
static int slp_rtb_cleared_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 6 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_STATE_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_STATE_REQUEST;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_STATUS_CLEAR_RTB);
		*mpp = mp;
		return (0);
	}
}
static int slp_retrieval_not_possible_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 10 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_ACTION;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_ACTION_RTRV_MSGS);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_RETR_RESULT;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_RESULT_FAILURE);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_SEQNO;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_bsnt);
		*mpp = mp;
		return (0);
	}
}
static int slp_bsnt_not_retrievable_ind(as_t * as, mblk_t ** mpp)
{
	mblk_t *mp;
	size_t mlen = 10 * sizeof(uint32_t);
	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M2UA_MAUP_RETR_CON;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen);
		*((uint32_t *) mp->b_wptr)++ = UA_PARM_IID;
		*((uint32_t *) mp->b_wptr)++ = htonl(as->l.id.iid);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_ACTION;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_ACTION_RTRV_BSN);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_RETR_RESULT;
		*((uint32_t *) mp->b_wptr)++ = __constant_htonl(M2UA_RESULT_FAILURE);
		*((uint32_t *) mp->b_wptr)++ = M2UA_PARM_SEQNO;
		*((uint32_t *) mp->b_wptr)++ = htonl(p->sl_bsnt);
		*mpp = mp;
		return (0);
	}
}

static int slp_xlat(as_t * as, mblk_t ** mpp)
{
	switch (*((long *) (*mpp)->b_rptr)) {
	case SL_PDU_IND:
		return slp_pdu_ind(as, mpp);
	case SL_LINK_CONGESTED_IND:
		return slp_link_congested_ind(as, mpp);
	case SL_LINK_CONGESTION_CEASED_IND:
		return slp_link_contestion_ceased_ind(as, mpp);
	case SL_RETRIEVED_MESSAGE_IND:
		return slp_retrieved_message_ind(as, mpp);
	case SL_RETRIEVAL_COMPLETE_IND:
		return slp_retrieval_complete_ind(as, mpp);
	case SL_RB_CLEARED_IND:
		return slp_rb_cleared_ind(as, mpp);
	case SL_BSNT_IND:
		return slp_bsnt_ind(as, mpp);
	case SL_IN_SERVICE_IND:
		return slp_in_service_ind(as, mpp);
	case SL_OUT_OF_SERVICE_IND:
		return slp_out_of_service_ind(as, mpp);
	case SL_REMOTE_PROCESSOR_OUTAGE_IND:
		return slp_remote_processor_outage_ind(as, mpp);
	case SL_REMOTE_PROCESSOR_RECOVERED_IND:
		return slp_remote_processor_recovered_ind(as, mpp);
	case SL_RTB_CLEARED_IND:
		return slp_rtb_cleared_ind(as, mpp);
	case SL_RETRIEVAL_NOT_POSSIBLE:
		return slp_retrieval_not_possible_ind(as, mpp);
	case SL_BSNT_NOT_RETRIEVABLE:
		return slp_bsnt_not_retrievable_ind(as, mpp);
	}
	return (-EOPNOTSUPP);
}
static int slp_xlat_prim(queue_t * q, mblk_t * mp)
{
	int err;
	xp_t *xp;
	pp_t *pp;
	as_t *as;
	lp_t *lp = (lp_t *) q->q_ptr;
	ensure(q, return (-EFAULT));
	ensure(lp, return (-EFAULT));
	if (lp->l.state != LMI_ENABLED)
		return (0);
	if (!(as = ua_pp_route(lp)))
		return (0);
	if ((pp = ua_as_route_loc(as))) {
		if (mp->b_datap->db_type < QPCTL && !canput(pp->rq))
			return (-EBUSY);
		putq(pp->rq, mp);
		return (1);
	}
	if ((xp = ua_as_route_rem(as))) {
		if (!(pp = xp->pp.pp)) {
			ptrace(("Have route to XP but no LP\n"));
			return (-EFAULT);
		}
		if (mp->b_datap->db_type < QPCTL && !canput(pp->wq))
			return (-EBUSY);
		if ((err = slp_xlat(as, &mp)))
			return (err);
		putq(pp->rq, mp);
		return (1);
	}
	ptrace(("AS-P marked active but no active AS-P\n"));
	return (-EFAULT);
}

static int slp_optmgmt_ack(queue_t * q, mblk_t * mp)
{
}
static int slp_notify_ind(queue_t * q, mblk_t * mp)
{
}
static int m2ua_l_r_data(queue_t * q, mblk_t * dp)
{
	/* 
	 *  Need to convert data to SL_PDU_IND.
	 */
	int rtn;
	mblk_t *mp;
	sl_pdu_ind_t *p;
	if ((mp = allocb(sizeof(*p), BPRI_MED))) {
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->sl_primitive = SL_PDU_IND;
		mp->b_cont = dp;
		switch ((rtn = sl_pdu_ind(q, mp))) {
		}
		return (1);
	}
	return (-ENOBUFS);
}
static int m2ua_l_r_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case LMI_INFO_ACK:
		return slp_info_ack(q, mp);
	case LMI_OK_ACK:
		return slp_ok_ack(q, mp);
	case LMI_ERROR_ACK:
		return slp_error_ack(q, mp);
	case LMI_ENABLE_CON:
		return slp_enable_con(q, mp);
	case LMI_DISABLE_CON:
		return slp_disable_con(q, mp);
	case LMI_OPTMGMT_ACK:
		return slp_optmgmt_ack(q, mp);
	case LMI_ERROR_IND:
		return slp_error_ind(q, mp);
	case LMI_STATS_IND:
		return slp_stats_ind(q, mp);
	case LMI_EVENT_IND:
		return slp_event_ind(q, mp);
	case SL_PDU_IND:
	case SL_LINK_CONGESTED_IND:
	case SL_LINK_CONGESTION_CEASED_IND:
	case SL_RETRIEVED_MESSAGE_IND:
	case SL_RETRIEVAL_COMPLETE_IND:
	case SL_RB_CLEARED_IND:
	case SL_BSNT_IND:
	case SL_IN_SERVICE_IND:
	case SL_OUT_OF_SERVICE_IND:
	case SL_REMOTE_PROCESSOR_OUTAGE_IND:
	case SL_REMOTE_PROCESSOR_RECOVERED_IND:
	case SL_RTB_CLEARED_IND:
	case SL_RETRIEVAL_NOT_POSSIBLE:
	case SL_BSNT_NOT_RETRIEVABLE:
		return slp_xlat_prim(q, mp);
	case SL_OPTMGMT_ACK:
		return slp_optmgmt_ack(q, mp);
	case SL_NOTIFY_IND:
		return slp_notify_ind(q, mp);
	}
	return (-EOPNOTSUPP);
}
static int m2ua_l_r_pcproto(queue_t * q, mblk_t * mp)
{
	return m2ua_l_r_proto(q, mp);
}
static int m2ua_l_r_error(queue_t * q, mblk_t * mp)
{
}
static int m2ua_l_r_hangup(queue_t * q, mblk_t * mp)
{
}
static int m2ua_l_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
	      return m2ua_l_r_data(q, mp):
	case M_PROTO:
		return m2ua_l_r_proto(q, mp);
	case M_PCPROTO:
		return m2ua_l_r_pcproto(q, mp);
	case M_ERROR:
		return m2ua_l_r_error(q, mp);
	case M_HANGUP:
		return m2ua_l_r_hangup(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

/*
 *  -------------------------------------------------------------------------
 *
 *  SCTP NPI Transport Message Handling
 *
 *  -------------------------------------------------------------------------
 *
 *  M2UA --> SCTP NPI Transport Primitives
 *  -------------------------------------------------------------------------
 */
static int m2ua_s_w_data(queue_t * q, mblk_t * dp)
{
	mblk_t *mp;
	N_data_req_t *p;
	N_qos_sel_data_sctp_t *q;
	if ((mp = allocb(sizeof(*p) + sizeof(*q), BPRI_MED))) {
		uint32_t mhdr = ((uint32_t *) dp->b_rptr)[0];
		mp->b_datap->db_type = M_PROTO;
		p = ((typeof(p)) mp->b_wptr)++;
		p->PRIM_type = N_DATA_REQ;
		p->DATA_xfer_flags = 0;
		q = ((typeof(q)) mp->b_wptr)++;
		q->n_qos_type = N_QOS_SEL_DATA_SCTP;
		q->ppi = M2UA_PPI;
		q->tsn = 0;
		q->ssn = 0;
		mp->b_cont = dp;
		switch (UA_MSG_CLAS(mhdr)) {
		case UA_CLASS_MGMT:
		case UA_CLASS_ASPS:
		case UA_CLASS_RKMM:
			q->sid = 0;
			break;
		case UA_CLASS_ASPT:
		case UA_CLASS_MAUP:
		{
			uint32_t iid = ((uint32_t *) dp->b_rptr)[3];
			fixme(("Map IID onto a stream id\n"));
			q->sid = iid;
			break;
		}
		default:
		case UA_CLASS_XFER:
		case UA_CLASS_SNMM:
		case UA_CLASS_Q921:
		case UA_CLASS_CNLS:
		case UA_CLASS_CONS:
		case UA_CLASS_TDHM:
		case UA_CLASS_TCHM:
			freeb(mp);
			return (-EPROTO);
		}
		putq(q, mp);
		return (1);
	}
	return (-ENOBUFS);
}
static int m2ua_s_w_ctl(queue_t * q, mblk_t * mp)
{
	return m2ua_s_w_data(q, mp);
}
static int m2ua_s_w_error(queue_t * q, mblk_t * mp)
{
	fixme(("Disconnect, deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int m2ua_s_w_hangup(queue_t * q, mblk_t * mp)
{
	fixme(("Disconnect, deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int m2ua_x_w_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_DATA:
		return m2ua_s_w_data(q, mp);
	case M_CTL:
		return m2ua_s_w_ctl(q, mp);
	case M_ERROR:
		return m2ua_s_w_error(q, mp);
	case M_HANGUP:
		return m2ua_s_w_hangup(q, mp);
	case M_FLUSH:
		return ua_w_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

/*
 *  SCTP NPI Transport --> M2UA Primitives
 *  -------------------------------------------------------------------------
 */
static int m2ua_s_data_ind(queue_t * q, mblk_t * mp)
{
}
static int m2ua_s_exdata_ind(queue_t * q, mblk_t * mp)
{
}
static int m2ua_s_other_ind(queue_t * q, mblk_t * mp)
{
}
static int m2ua_s_r_proto(queue_t * q, mblk_t * mp)
{
	switch (*((long *) mp->b_rptr)) {
	case N_DATA_IND:
		return m2ua_s_data_ind(q, mp);
	case N_EXDATA_IND:
		return m2ua_s_exdata_ind(q, mp);
	default:
		return m2ua_s_other_ind(q, mp);
	}
}
static int m2ua_s_r_pcproto(queue_t * q, mblk_t * mp)
{
	return m2ua_s_r_proto(q, mp);
}
static int m2ua_s_r_error(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int m2ua_s_r_hangup(queue_t * q, mblk_t * mp)
{
	fixme(("Deactivate and take down ASP and notify LM\n"));
	noenable(q);
	return (-EFAULT);
}
static int m2ua_x_r_prim(queue_t * q, mblk_t * mp)
{
	switch (mp->b_datap->db_type) {
	case M_PROTO:
		return m2ua_s_r_proto(q, mp);
	case M_PCPROTO:
		return m2ua_s_r_pcproto(q, mp);
	case M_ERROR:
		return m2ua_s_r_error(q, mp);
	case M_HANGUP:
		return m2ua_s_r_hangup(q, mp);
	case M_FLUSH:
		return ua_r_flush(q, mp);
	}
	return (-EOPNOTSUPP);
}

extern struct drv m2ua_driver = {
	M2UA_CMAJOR,
	M2UA_NMAJOR,
	M2UA_NMINOR,
	{&m2ua_u_r_prim, &m2ua_u_w_prim},
	{&m2ua_l_r_prim, &m2ua_l_w_prim},
	{&m2ua_x_r_prim, &m2ua_x_w_prim}
};


Home Index Prev Next More Download Info FAQ Mail   Home -> Resources -> Browse Source -> strss7/drivers/sigtran/m2ua.c

OpenSS7
SS7 for the
Common Man
Home Overview Status News Documentation Resources About

© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved.
Last modified: