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/slsi/sls_codec.c#ident "@(#) $Id: sls_codec.c,v 0.8.2.1 2002/10/18 02:40:37 brian Exp $" /* * This is a decoder (parser) and encoder (builder) for SS7 MTP messages. It * is used to abstract the actual line coding of the SS7 message by placing * it into a common internal representation in a message buffer. */ static int ss7_itut_build(mblk_t *) { mblk_t *md = mp->b_cont; union SL_primitives *p = (union SL_primitives *) mp->b_rptr; ss7mtp_msg *m = (ss7mtp_msg *) md->b_rptr; m->itut.mh.ni = p->msu.ls_rl.ni; m->itut.mh.mp = p->msu.ls_rl.mp; m->itut.mh.si = p->msu.ls_rl.si; m->itut.mh.rl.dpc = p->msu.ls_rl.dpc; m->itut.mh.rl.ops = p->msu.ls_rl.opc; m->itut.mh.rl.sls = p->msu.ls_rl.sls; switch (p->msu.ls_rl.si) { case 0x0: /* snmm */ m->itut.mh.h0 = p->msu.ls_mh.h0; m->itut.mh.h1 = p->msu.ls_mh.h1; switch (p->msu.ls_mh.h0) { case 0x1: /* chm */ switch (p->msu.ls_mh.h1) { case 0x1: /* coo - changeover-order */ m->itut.coo.fsnl = p->coo.ls_fsnl; md->b_wptr = md->b_rptr + sizeof(m->itut.coo); break; case 0x2: /* coa - changeover-ack */ m->itut.coa.fsnl = p->coa.ls_fsnl; md->b_wptr = md->b_rptr + sizeof(m->itut.coa); break; case 0x5: /* cbd - changeback-declaration */ m->itut.cbd.cbc = p->cbd.ls_cbc; md->b_wptr = md->b_rptr + sizeof(m->itut.cbd); break; case 0x6: /* cba - changeback-ack */ m->itut.cba.cbc = p->cba.ls_cbc; md->b_wptr = md->b_rptr + sizeof(m->itut.cba); break; default: return -EINVAL; } break; case 0x2: /* ecm */ switch (p->msu.ls_mh.h1) { case 0x1: /* eco - emergency-changeover-order */ md->b_wptr = md->b_rptr + sizeof(m->itut.eco); break; case 0x2: /* eca - emergency-changeover-ack */ md->b_wptr = md->b_rptr + sizeof(m->itut.eca); break; default: return -EINVAL; } break; case 0x3: /* fcm */ switch (p->msu.ls_mh.h1) { case 0x1: /* rct - signalling-route-set-congestion-test */ md->b_wptr = md->b_rptr + sizeof(m->itut.rct); break; case 0x2: /* tfc - transfer-controlled */ m->itut.tfc.dest = p->tfc.ls_dest; m->itut.tfc.stat = p->tfc.ls_stat; md->b_wptr = md->b_rptr + sizeof(m->itut.tfc); break; default: return -EINVAL; } break; case 0x4: /* tfm */ switch (p->msu.ls_mh.h1) { case 0x1: /* tfp - transfer prohibited */ m->itut.tfp.dest = p->tfp.ls_dest; md->b_wptr = md->b_rptr + sizeof(m->itut.tfp); break; case 0x3: /* tfr - transfer-restricted */ m->itut.tfr.dest = p->tfr.ls_dest; md->b_wptr = md->b_rptr + sizeof(m->itut.tfr); break; case 0x5: /* tfa - transfer-allowed */ m->itut.tfa.dest = p->tfa.ls_dest; md->b_wptr = md->b_rptr + sizeof(m->itut.tfa); break; default: return -EINVAL; } break; case 0x5: /* rsm */ switch (p->msu.ls_mh.h1) { case 0x1: /* rsp - signalling-route-set-test-prohibited */ m->itut.rsp.dest = p->rsp.ls_dest; md->b_wptr = md->b_rptr + sizeof(m->itut.rsp); break; case 0x2: /* rsr - signalling-route-set-test-restricted */ m->itut.rsr.dest = p->rsr.ls_dest; md->b_wptr = md->b_rptr + sizeof(m->itut.rsr); break; default: return -EINVAL; } break; case 0x6: /* mim */ switch (p->msu.ls_mh.h1) { case 0x1: /* lin - link-inhibit */ md->b_wptr = md->b_rptr + sizeof(m->itut.lin); break; case 0x2: /* lun - link-uninhibit */ md->b_wptr = md->b_rptr + sizeof(m->itut.lun); break; case 0x3: /* lia - link-inhibit-ack */ md->b_wptr = md->b_rptr + sizeof(m->itut.lia); break; case 0x4: /* lua - link-uninhibit-ack */ md->b_wptr = md->b_rptr + sizeof(m->itut.lua); break; case 0x5: /* lid - link-inhibit-denied */ md->b_wptr = md->b_rptr + sizeof(m->itut.lid); break; case 0x6: /* lfu - force-uninhibit */ md->b_wptr = md->b_rptr + sizeof(m->itut.lfu); break; case 0x7: /* llt - local-inhibit-test */ md->b_wptr = md->b_rptr + sizeof(m->itut.llt); break; case 0x8: /* lrt - remote-inhibit-test */ md->b_wptr = md->b_rptr + sizeof(m->itut.lrt); break; default: return -EINVAL; } break; case 0x7: /* trm */ switch (p->msu.ls_mh.h1) { case 0x1: /* tra - traffic-restart-allowed */ md->b_wptr = md->b_rptr + sizeof(m->itut.tra); break; default: return -EINVAL; } break; case 0x8: /* dlm */ switch (p->msu.ls_mh.h1) { case 0x1: /* dlc - signalling-data-link-connection-order */ m->itut.dlc.sdli = p->dlc.ls_sdli; md->b_wptr = md->b_rptr + sizeof(m->itut.dlc); break; case 0x2: /* css - connection-successful */ md->b_wptr = md->b_rptr + sizeof(m->itut.css); break; case 0x3: /* cns - connection-not-successful */ md->b_wptr = md->b_rptr + sizeof(m->itut.cns); break; case 0x4: /* cnp - connection-not-possible */ md->b_wptr = md->b_rptr + sizeof(m->itut.cnp); break; default: return -EINVAL; } break; case 0xa: /* ufc */ switch (p->msu.ls_mh.h1) { case 0x1: /* upu - user part unavailable */ m->itut.upu.dest = p->upu.ls_dest; m->itut.upu.upi = p->upu.ls_upi; md->b_wptr = md->b_rptr + sizeof(m->itut.upu); break; default: return -EINVAL; } break; default: return -EINVAL; } break; case 0x1: /* sltc */ m->itut.mh.h0 = p->msu.ls_mh.h0; m->itut.mh.h1 = p->msu.ls_mh.h1; switch (p->ls_mh.h0) { case 0x1: switch (p->msu.ls_mh.h1) { case 0x1: /* sltm */ m->itut.sltm.tli = p->sltm.ls_tli & 0xf; bcopy(p->sltm.ls_tmsx, m->itut.sltm.tmsx, p->sltm.ls.tli & 0xf); md->b_wptr = md->b_rptr + sizeof(m->itut.sltm) - 15 + p->sltm.ls.tli & 0xf; break; case 0x2: /* slta */ m->itut.slta.tli = p->slta.ls_tli & 0xf; bcopy(p->slta.ls_tmsx, m->itut.slta.tmsx, p->slta.ls.tli & 0xf); md->b_wptr = md->b_rptr + sizeof(m->itut.slta) - 15 + p->slta.ls.tli & 0xf; break; default: return -EINVAL; } default: return -EINVAL; } break; case 0x2: /* ssltc */ m->itut.mh.h0 = p->msu.ls_mh.h0; m->itut.mh.h1 = p->msu.ls_mh.h1; switch (p->ls_mh.h0) { case 0x1: switch (p->msu.ls_mh.h1) { case 0x1: /* ssltm */ m->itut.ssltm.tli = p->ssltm.ls_tli & 0xf; bcopy(p->ssltm.ls_tmsx, m->itut.ssltm.tmsx, p->ssltm.ls.tli & 0xf); md->b_wptr = md->b_rptr + sizeof(m->itut.ssltm) - 15 + p->ssltm.ls.tli & 0xf; break; case 0x2: /* sslta */ m->itut.sslta.tli = p->sslta.ls_tli & 0xf; bcopy(p->sslta.ls_tmsx, m->itut.sslta.tmsx, p->sslta.ls.tli & 0xf); md->b_wptr = md->b_rptr + sizeof(m->itut.sslta) - 15 + p->sslta.ls.tli & 0xf; break; default: return -EINVAL; } default: return -EINVAL; } break; default: /* user */ md->b_wptr = md->b_rptr + sizeof(m->itut.mh) - 1; return (0); } mp->b_wptr = mp->b_rptr + sizeof(p->ls_primitive); p->ls_primitive = LS_MESSAGE_SIGNAL_UNIT; return (0); } static int ss7_ansi_build(mblk_t *) { } int ss7_msg_build(mblk_t * mp, int pvar[4]) { /* * Takes the message (M_PROTO) as provided for in the message block in mp * and encodes it into an MSU frame in attached (M_DATA). Attached * M_DATA must be large enough to hold the resulting frame. The M_PROTO * message block is converted to a generic MSU primitive block. * * Get it right: send a M_PROTO block followed by an M_DATA block. I do * very little error checking here for speed. * * The array of protocol variants (pvar[4]) is used to determine which * protocol variant to use for which network indicators. */ int var; mblk_t *md; if (!(md = mp->b_cont)) return -EINVAL; var = pvar[((union SL_primitives *) mp->b_rptr)->msu.rl.ni]; switch (var) { case SS7_PVAR_ITUT_88: case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: case SS7_PVAR_ITUT_00: case SS7_PVAR_ETSI_88: case SS7_PVAR_ETSI_93: case SS7_PVAR_ETSI_96: case SS7_PVAR_ETSI_00: return ss7_itut_build(mp); case SS7_PVAR_ANSI_88: case SS7_PVAR_ANSI_92: case SS7_PVAR_ANSI_96: case SS7_PVAR_ANSI_00: case SS7_PVAR_JTTC_94: return ss7_ansi_build(mp); } return -EINVAL; } static int ss7_itut_parse(mblk_t * mp) { mblk_t *md = mp->b_cont; union SL_primitives *p = (union SL_primitives *) mp->b_rptr; ss7mtp_msg *m = (ss7mtp_msg *) md->b_rptr; p->msu.ls_rl.ni = m->itut.mh.ni; p->msu.ls_rl.mp = m->itut.mh.mp; p->msu.ls_rl.si = m->itut.mh.si; p->msu.ls_rl.dpc = m->itut.mh.rl.dpc; p->msu.ls_rl.opc = m->itut.mh.rl.opc; p->msu.ls_rl.sls = m->itut.mh.rl.sls; switch (p->msu.ls_rl.si) { case 0x0: /* snmm */ p->msu.ls_mh.h0 = m->itut.mh.h0; p->msu.ls_mh.h1 = m->itut.mh.h1; switch (p->msu.ls_mh.h0) { case 0x1: /* chm */ switch (p->msu.ls_mh.h1) { case 0x1: /* coo - changeover-order */ p->coo.ls_fsnl = m->itut.coo.fsnl; mp->b_wptr = mp->b_rptr + LS_COO_SIG_SIZE; p->ls_primitive = LS_COO_SIG; break; case 0x2: /* coa - changeover-ack */ p->coa.ls_fsnl = m->itut.coa.fsnl; mp->b_wptr = mp->b_rptr + LS_COA_SIG_SIZE; p->ls_primitive = LS_COA_SIG; break; case 0x5: /* cbd - changeback-declaration */ p->cbd.ls_cbc = m->itut.cbd.cbc; mp->b_wptr = mp->b_rptr + LS_CBD_SIG_SIZE; p->ls_primitive = LS_CBD_SIG; break; case 0x6: /* cba - changeback-ack */ p->cba.ls_cbc = m->itut.cba.cbc; mp->b_wptr = mp->b_rptr + LS_CBA_SIG_SIZE; p->ls_primitive = LS_CBA_SIG; break; default: return -EINVAL; } break; case 0x2: /* ecm */ switch (p->msu.ls_mh.h1) { case 0x1: /* eco - emergency-changeover-order */ mp->b_wptr = mp->b_rptr + LS_ECO_SIG_SIZE; p->ls_primitive = LS_ECO_SIG; break; case 0x2: /* eca - emergency-changeover-ack */ mp->b_wptr = mp->b_rptr + LS_ECA_SIG_SIZE; p->ls_primitive = LS_ECA_SIG; break; default: return -EINVAL; } break; case 0x3: /* fcm */ switch (p->msu.ls_mh.h1) { case 0x1: /* rct - signalling-route-set-congestion-test */ mp->b_wptr = mp->b_rptr + LS_RCT_SIG_SIZE; p->ls_primitive = LS_RCT_SIG; break; case 0x2: /* tfc - transfer-controlled */ p->tfc.ls_dest = m->itut.tfc.dest; p->tfc.ls_stat = m->itut.tfc.stat; mp->b_wptr = mp->b_rptr + LS_TFC_SIG_SIZE; p->ls_primitive = LS_TFC_SIG; break; default: return -EINVAL; } break; case 0x4: /* tfm */ switch (p->msu.ls_mh.h1) { case 0x1: /* tfp - transfer prohibited */ p->tfp.ls_dest = m->itut.tfp.dest; mp->b_wptr = mp->b_rptr + LS_TFP_SIG_SIZE; p->ls_primitive = LS_TFP_SIG; break; case 0x3: /* tfr - transfer-restricted */ p->tfr.ls_dest = m->itut.tfr.dest; mp->b_wptr = mp->b_rptr + LS_TFR_SIG_SIZE; p->ls_primitive = LS_TFR_SIG; break; case 0x5: /* tfa - transfer-allowed */ p->tfa.ls_dest = m->itut.tfa.dest; mp->b_wptr = mp->b_rptr + LS_TFA_SIG_SIZE; p->ls_primitive = LS_TFA_SIG; break; default: return -EINVAL; } break; case 0x5: /* rsm */ switch (p->msu.ls_mh.h1) { case 0x1: /* rsp - signalling-route-set-test-prohibited */ p->rsp.ls_dest = m->itut.rsp.dest; mp->b_wptr = mp->b_rptr + LS_RSP_SIG_SIZE; p->ls_primitive = LS_TFA_SIG; break; case 0x2: /* rsr - signalling-route-set-test-restricted */ p->rsr.ls_dest = m->itut.rsr.dest; mp->b_wptr = mp->b_rptr + LS_RSR_SIG_SIZE; p->ls_primitive = LS_RSR_SIG; break; default: return -EINVAL; } break; case 0x6: /* mim */ switch (p->msu.ls_mh.h1) { case 0x1: /* lin - link-inhibit */ mp->b_wptr = mp->b_rptr + LS_LIN_SIG_SIZE; p->ls_primitive = LS_LIN_SIG; break; case 0x2: /* lun - link-uninhibit */ mp->b_wptr = mp->b_rptr + LS_LUN_SIG_SIZE; p->ls_primitive = LS_LUN_SIG; break; case 0x3: /* lia - link-inhibit-ack */ mp->b_wptr = mp->b_rptr + LS_LIA_SIG_SIZE; p->ls_primitive = LS_LIA_SIG; break; case 0x4: /* lua - link-uninhibit-ack */ mp->b_wptr = mp->b_rptr + LS_LUA_SIG_SIZE; p->ls_primitive = LS_LUA_SIG; break; case 0x5: /* lid - link-inhibit-denied */ mp->b_wptr = mp->b_rptr + LS_LID_SIG_SIZE; p->ls_primitive = LS_LID_SIG; break; case 0x6: /* lfu - force-uninhibit */ mp->b_wptr = mp->b_rptr + LS_LFU_SIG_SIZE; p->ls_primitive = LS_LFU_SIG; break; case 0x7: /* llt - local-inhibit-test */ mp->b_wptr = mp->b_rptr + LS_LLT_SIG_SIZE; p->ls_primitive = LS_LLT_SIG; break; case 0x8: /* lrt - remote-inhibit-test */ mp->b_wptr = mp->b_rptr + LS_LRT_SIG_SIZE; p->ls_primitive = LS_LRT_SIG; break; default: return -EINVAL; } break; case 0x7: /* trm */ switch (p->msu.ls_mh.h1) { case 0x1: /* tra - traffic-restart-allowed */ mp->b_wptr = mp->b_rptr + LS_TRA_SIG_SIZE; break; default: return -EINVAL; } break; case 0x8: /* dlm */ switch (p->msu.ls_mh.h1) { case 0x1: /* dlc - signalling-data-link-connection-order */ p->dlc.ls_slc = 0; p->dlc.ls_sdli = m->itut.dlc.sdli; mp->b_wptr = mp->b_rptr + LS_DLC_SIG_SIZE; p->ls_primitive = LS_DLC_SIG; break; case 0x2: /* css - connection-successful */ mp->b_wptr = mp->b_rptr + LS_CSS_SIG_SIZE; p->ls_primitive = LS_CSS_SIG; break; case 0x3: /* cns - connection-not-successful */ mp->b_wptr = mp->b_rptr + LS_CNS_SIG_SIZE; p->ls_primitive = LS_CNS_SIG; break; case 0x4: /* cnp - connection-not-possible */ mp->b_wptr = mp->b_rptr + LS_CNP_SIG_SIZE; p->ls_primitive = LS_CNP_SIG; break; default: return -EINVAL; } break; case 0xa: /* ufc */ switch (p->msu.ls_mh.h1) { case 0x1: /* upu - user part unavailable */ p->upu.ls_dest = m->itut.upu.dest; p->upu.ls_upi = m->itut.upu.upi; mp->b_wptr = mp->b_rptr + LS_UPU_SIG_SIZE; p->ls_primitive = LS_UPU_SIG; break; default: return -EINVAL; } break; default: return -EINVAL; } break; case 0x1: /* sltc */ p->msu.ls_mh.h0 = m->itut.mh.h0; p->msu.ls_mh.h1 = m->itut.mh.h1; switch (p->ls_mh.h0) { case 0x1: switch (p->msu.ls_mh.h1) { case 0x1: /* sltm */ p->sltm.ls_slc = 0; p->sltm.ls_tli = m->itut.sltm.tli; bcopy(m->itut.sltm.tmsx, p->sltm.ls_tmsx, p->sltm.ls.tli); mp->b_wptr = mp->b_rptr + LS_SLTM_SIG_SIZE - 15 + p->sltm.ls.tli; p->ls_primitive = LS_SLTM_SIG; break; case 0x2: /* slta */ p->slta.ls_slc = 0; p->slta.ls_tli = m->itut.slta.tli; bcopy(m->itut.slta.tmsx, p->slta.ls_tmsx, p->slta.ls.tli); mp->b_wptr = mp->b_rptr + LS_SLTM_SIG_SIZE - 15 + p->slta.ls.tli; p->ls_primitive = LS_SLTA_SIG; break; default: return -EINVAL; } default: return -EINVAL; } break; case 0x2: /* ssltc */ p->msu.ls_mh.h0 = m->itut.mh.h0; p->msu.ls_mh.h1 = m->itut.mh.h1; switch (p->msu.ls_mh.h0) { switch (p->msu.ls_mh.h1) { case 0x1: /* ssltm */ p->ssltm.ls_slc = 0; p->ssltm.ls_tli = m->itut.ssltm.tli; bcopy(m->itut.ssltm.tmsx, p->ssltm.ls_tmsx, p->ssltm.ls.tli); mp->b_wptr = mp->b_rptr + LS_SLTM_SIG_SIZE - 15 + p->ssltm.ls.tli; p->ls_primitive = LS_SSLTM_SIG; break; case 0x2: /* sslta */ p->sslta.ls_slc = 0; p->sslta.ls_tli = m->itut.sslta.tli; bcopy(m->itut.sslta.tmsx, p->sslta.ls_tmsx, p->sslta.ls.tli); mp->b_wptr = mp->b_rptr + LS_SLTM_SIG_SIZE - 15 + p->sslta.ls.tli; p->ls_primitive = LS_SSLTA_SIG; break; default: return -EINVAL; } default: return -EINVAL; } break; default: mp->b_wptr = mp->b_rptr + LS_USER_SIG_SIZE; md->b_rptr += sizeof(m->itut.mh) - 1; /* strip MTP header */ p->ls_primitive = LS_USER_SIG; return (0); } mp->b_data->db_type = M_PROTO; md = unlinkb(mp); freemsg(md); return (0); } int ss7_msg_parse(mblk_t * mp, int pvar[4]) { /* * Takes the MSU (M_DATA) as provided for in the message block (M_DATA) * and decodes it into a message block in mp (M_PROTO). * * Get it right: send a M_PROTO block followed by an M_DATA block. I do * very little error checking here for speed. * * The array of protocol variants (pvar[4]) is used to determine which * protocol variant to use for which network indicators. */ int var; mblk_t *md; if (!(md = mp->b_cont)) return -EINVAL; var = pvar[((ss7mtp_msg *) md->b_rptr)->itut.mh.ni]; switch (var) { case SS7_PVAR_ITUT_88: case SS7_PVAR_ITUT_93: case SS7_PVAR_ITUT_96: case SS7_PVAR_ITUT_00: case SS7_PVAR_ETSI_88: case SS7_PVAR_ETSI_93: case SS7_PVAR_ETSI_96: case SS7_PVAR_ETSI_00: return ss7_itut_parse(mp); case SS7_PVAR_ANSI_88: case SS7_PVAR_ANSI_92: case SS7_PVAR_ANSI_96: case SS7_PVAR_ANSI_00: case SS7_PVAR_JTTC_94: return ss7_ansi_parse(mp); } return -EINVAL; }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |