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/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} };
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |