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/tcap/tcap_pdu.c#ident "@(#) $RCSfile: tcap_pdu.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:40 $" static char const ident[] = "$RCSfile: tcap_pdu.c,v $ $Name: $($Revision: 0.8.2.2 $) $Date: 2003/04/03 19:51:40 $"; #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 "tcap.h" #include "tcap_data.h" #include "tcap_msgs.h" #include "tcap_ctrl.h" #include "tcap_prov.h" #include "../sccpi/sccp_user.h" /* * ========================================================================= * * TCAP RECV Peer Messages (Component (TC) Sub-Layer) * * ========================================================================= * * ANSI PRIVATE-TCAP version of Components. * * ------------------------------------------------------------------------- * * UNPACK ANSI Correlation Ids. */ static inline int unpack_priv_corids(unsigned char **p, unsigned char *e, tc_msg_t * m, const uint ctype) { int err; uint tag; if ((err = unpack_priv_prim(p, &e, &tag))) return (err); if (tag != TCAP_TAG_PRIV_CORID) return (-EINVAL); switch (e - *p) { case 0: /* no ids */ switch (ctype) { case TCAP_CT_INVOKE_L: case TCAP_CT_INVOKE_NL: case TCAP_CT_REJECT: return (0); } return (-EPROTO); case 1: /* invoke id */ switch (ctype) { default: case TCAP_CT_INVOKE_L: case TCAP_CT_INVOKE_NL: case TCAP_CT_RESULT_L: case TCAP_CT_RESULT_NL: case TCAP_CT_REJECT: case TCAP_CT_ERROR: if (*p >= e) return (-EMSGSIZE); m->iid = *(*p)++; m->parms |= TCAP_PTF_IID; break; } return (-EPROTO); case 2: /* invoke id and correlation id */ switch (ctype) { case TCAP_CT_INVOKE_L: case TCAP_CT_INVOKE_NL: if (*p >= e) return (-EMSGSIZE); m->iid = *(*p)++; m->parms |= TCAP_PTF_IID; if (*p >= e) return (-EMSGSIZE); m->lid = *(*p)++; m->parms |= TCAP_PTF_LID; return (0); } return (-EPROTO); } return (-EINVAL); } /* * UNPACK ANSI Opcodes */ static inline int unpack_priv_opcode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_priv_prim(p, &e, &tag))) return (err); if (e - *p != 2) return (-EMSGSIZE); switch (tag) { case TCAP_TAG_PRIV_NOPCO: if ((err = unpack_implicit_int(p, e, &m->opcode))) return (err); m->parms |= TCAP_PTF_NOPCO; return (0); case TCAP_TAG_PRIV_POPCO: if ((err = unpack_implicit_int(p, e, &m->opcode))) return (err); m->parms |= TCAP_PTF_POPCO; return (0); } return (-EPROTO); } /* * UNPACK ANSI Error Codes */ static inline int unpack_priv_ecode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_priv_prim(p, &e, &tag))) return (err); switch (tag) { case TCAP_TAG_PRIV_NECODE: if ((err = unpack_explicit_int(p, e, &m->ecode))) return (err); m->parms |= TCAP_PTF_NECODE; return (0); case TCAP_TAG_PRIV_PECODE: if ((err = unpack_explicit_int(p, e, &m->ecode))) return (err); m->parms |= TCAP_PTF_PECODE; return (0); } return (-EPROTO); } /* * UNPACK ANSI Problem Codes */ static inline int unpack_priv_pcode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_priv_prim(p, &e, &tag))) return (err); if ((err = unpack_implicit_int(p, e, &m->pcode))) return (err); m->parms |= TCAP_PTF_PCODE; return (0); } /* * UNPACK ANSI Component Parameter Sets */ static inline int unpack_priv_pset(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_priv_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_PRIV_PSET && tag != TCAP_TAG_PRIV_PSEQ) return (-EINVAL); m->prm_beg = *p; m->prm_end = e; *p = e; m->parms |= TCAP_PTF_PSEQ; return (0); } /* * ANSI INVOKE (LAST) * ------------------------------------------------------------------------ */ static int tcap_priv_dec_inkl(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_INVOKE_L; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_INVOKE_L))) return (err); if ((err = unpack_priv_opcode(p, e, m))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI INVOKE (NOT LAST) * ------------------------------------------------------------------------ */ static int tcap_priv_dec_ink(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_INVOKE_NL; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_INVOKE_NL))) return (err); if ((err = unpack_priv_opcode(p, e, m))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI RETURN RESULT (LAST) * ------------------------------------------------------------------------ */ static int tcap_priv_dec_rrl(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_RESULT_L; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_RESULT_L))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI RETURN RESULT (NOT LAST) * ------------------------------------------------------------------------ */ static int tcap_priv_dec_rr(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_RESULT_NL; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_RESULT_NL))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI RETURN ERROR * ------------------------------------------------------------------------ */ static int tcap_priv_dec_rer(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_ERROR; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_ERROR))) return (err); if ((err = unpack_priv_ecode(p, e, m))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI REJECT * ------------------------------------------------------------------------ */ static int tcap_priv_dec_rej(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_REJECT; if ((err = unpack_priv_corids(p, e, m, TCAP_CT_REJECT))) return (err); if ((err = unpack_priv_pcode(p, e, m))) return (err); if ((err = unpack_priv_pset(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ANSI Component Decoder * ------------------------------------------------------------------------ */ int tcap_priv_dec_comp(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if (!(err = unpack_appl_cons(p, &e, &tag))) switch (tag) { case TCAP_TAG_PRIV_INKL: /* Invoke (Last) */ if (!(err = tcap_priv_dec_inkl(p, e, m))) return (0); break; case TCAP_TAG_PRIV_INK: /* Invoke (Not Last) */ if (!(err = tcap_priv_dec_ink(p, e, m))) return (0); break; case TCAP_TAG_PRIV_RRL: /* Return Result (Last) */ if (!(err = tcap_priv_dec_rrl(p, e, m))) return (0); break; case TCAP_TAG_PRIV_RR: /* Return Result (Not Last) */ if (!(err = tcap_priv_dec_rr(p, e, m))) return (0); break; case TCAP_TAG_PRIV_RER: /* Return Error */ if (!(err = tcap_priv_dec_rer(p, e, m))) return (0); break; case TCAP_TAG_PRIV_REJ: /* Reject */ if (!(err = tcap_priv_dec_rej(p, e, m))) return (0); break; default: err = -EINVAL; break; } return (err); } /* * ------------------------------------------------------------------------- * * ITUT APPLICATION-TCAP version of Components. * * ------------------------------------------------------------------------- * * UNPACK ITUT Correlation Ids. */ static inline int unpack_univ_iid(unsigned char **p, unsigned char *e, tc_msg_t * m) { (void) p; (void) e; (void) m; /* FIXME */ return (-EFAULT); } static inline int unpack_univ_lid(unsigned char **p, unsigned char *e, tc_msg_t * m) { (void) p; (void) e; (void) m; /* FIXME */ return (-EFAULT); } static inline int unpack_univ_corids(unsigned char **p, unsigned char *e, tc_msg_t * m, const uint ctype) { int err; switch (ctype) { case TCAP_CT_INVOKE_L: if ((err = unpack_univ_iid(p, e, m))) return (err); m->parms |= TCAP_PTF_IID; if ((err = unpack_univ_lid(p, e, m))) /* optional */ return (err); m->parms |= TCAP_PTF_LID; return (0); case TCAP_CT_RESULT_L: case TCAP_CT_RESULT_NL: case TCAP_CT_ERROR: if ((err = unpack_univ_iid(p, e, m))) return (err); m->parms |= TCAP_PTF_IID; return (0); case TCAP_CT_REJECT: /* could be NULL */ if ((err = unpack_univ_iid(p, e, m))) return (err); m->parms |= TCAP_PTF_IID; return (0); } return (-EFAULT); } /* * UNPACK ITUT Opcodes */ static inline int unpack_univ_opcode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_univ_prim(p, &e, &tag))) return (err); if (tag == TCAP_TAG_UNIV_OID) /* 6 */ return (-EOPNOTSUPP); /* we don't support OID opcodes */ if (tag != TCAP_TAG_UNIV_INT) /* 2 */ return (-EPROTO); if ((err = unpack_implicit_int(p, e, &m->opcode))) return (err); m->parms |= TCAP_PTF_LOPCO; return (0); } /* * UNPACK ITUT Parameter Sequences */ static inline int unpack_univ_pseq(unsigned char **p, unsigned char *e, tc_msg_t * m, const uint opt) { int err; uint tag; if (opt) { if (*p >= e) return (0); if (**p != (0x20 | TCAP_TAG_UNIV_SEQ)) return (0); } if ((err = unpack_univ_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_UNIV_SEQ) return (-EINVAL); m->prm_beg = *p; m->prm_end = e; *p = e; m->parms |= TCAP_PTF_PSEQ; return (0); } /* * UNPACK ITUT Result Opcode and Parameter Sequences */ static inline int unpack_univ_rseq(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if (*p >= e) return (0); if (**p != (0x20 | TCAP_TAG_UNIV_SEQ)) return (0); if ((err = unpack_univ_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_UNIV_SEQ) return (-EINVAL); if ((err = unpack_univ_opcode(p, e, m))) return (err); if ((err = unpack_univ_pseq(p, e, m, 0))) return (err); return (0); } /* * UNPACK ITUT Error Codes */ static inline int unpack_univ_ecode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if ((err = unpack_univ_prim(p, &e, &tag))) return (err); switch (tag) { case TCAP_TAG_UNIV_INT: if ((err = unpack_implicit_int(p, e, &m->ecode))) return (err); m->parms |= TCAP_PTF_LECODE; return (0); case TCAP_TAG_UNIV_OID: return (-EOPNOTSUPP); /* don't support global error codes */ } return (-EPROTO); } /* * UNPACK ITUT Problem Codes */ static inline int unpack_ctxt_pcode(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; uint ptype; if ((err = unpack_ctxt_prim(p, &e, &tag))) return (err); ptype = tag; if ((err = unpack_implicit_int(p, e, &m->pcode))) return (err); m->pcode |= ptype << 16; m->parms |= TCAP_PTF_PCODE; return (0); } /* * ITUT INVOKE (LAST) * ------------------------------------------------------------------------ */ static int tcap_ctxt_dec_inkl(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_INVOKE_L; if ((err = unpack_univ_corids(p, e, m, TCAP_CT_INVOKE_L))) return (err); if ((err = unpack_univ_opcode(p, e, m))) return (err); if ((err = unpack_univ_pseq(p, e, m, 1))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ITUT RETURN RESULT (LAST) * ------------------------------------------------------------------------ */ static int tcap_ctxt_dec_rrl(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_RESULT_L; if ((err = unpack_univ_corids(p, e, m, TCAP_CT_RESULT_L))) return (err); if ((err = unpack_univ_rseq(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ITUT RETURN RESULT (NOT LAST) * ------------------------------------------------------------------------ */ static int tcap_ctxt_dec_rr(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_RESULT_NL; if ((err = unpack_univ_corids(p, e, m, TCAP_CT_RESULT_NL))) return (err); if ((err = unpack_univ_rseq(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ITUT RETURN ERROR * ------------------------------------------------------------------------ */ static int tcap_ctxt_dec_rer(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_ERROR; if ((err = unpack_univ_corids(p, e, m, TCAP_CT_ERROR))) return (err); if ((err = unpack_univ_ecode(p, e, m))) return (err); if ((err = unpack_univ_pseq(p, e, m, 1))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ITUT REJECT * ------------------------------------------------------------------------ */ static int tcap_ctxt_dec_rej(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; m->type = TCAP_CT_REJECT; if ((err = unpack_univ_corids(p, e, m, TCAP_CT_REJECT))) return (err); if ((err = unpack_ctxt_pcode(p, e, m))) return (err); if (*p != e) return (-EMSGSIZE); return (0); } /* * ITUT Component Decoder * ------------------------------------------------------------------------ */ int tcap_appl_dec_comp(unsigned char **p, unsigned char *e, tc_msg_t * m) { int err; uint tag; if (!(err = unpack_ctxt_cons(p, &e, &tag))) switch (tag) { case TCAP_TAG_CNTX_INK: /* Invoke */ if (!(err = tcap_ctxt_dec_inkl(p, e, m))) return (0); break; case TCAP_TAG_CNTX_RRL: /* Return Result (Last) */ if (!(err = tcap_ctxt_dec_rrl(p, e, m))) return (0); break; case TCAP_TAG_CNTX_RER: /* Return Error */ if (!(err = tcap_ctxt_dec_rer(p, e, m))) return (0); break; case TCAP_TAG_CNTX_REJ: /* Reject */ if (!(err = tcap_ctxt_dec_rej(p, e, m))) return (0); break; case TCAP_TAG_CNTX_RR: /* Return Result (Not Last) */ if (!(err = tcap_ctxt_dec_rr(p, e, m))) return (0); break; default: err = -EINVAL; break; } return (err); } /* * ========================================================================= * * TCAP RECV Peer Messages (Transaction (TR) Sub-Layer) * * ========================================================================= */ /* * PRIVATE-TCAP version of Packages. (Used by the TR sub-layer.) * ------------------------------------------------------------------------- */ static inline int unpack_priv_trsid(unsigned char **p, unsigned char *e, tr_msg_t * m, const uint mtype) { int err; uint tag; if ((err = unpack_priv_prim(p, &e, &tag))) return (err); if (tag != TCAP_TAG_PRIV_TRSID) return (-EINVAL); switch (e - *p) { case 0: /* no transaction ids */ switch (mtype) { case TCAP_MT_UNI: return (0); } return (-EPROTO); case 4: /* orig or dest transaction id */ switch (mtype) { case TCAP_MT_QWP: case TCAP_MT_QWOP: case TCAP_MT_RESP: case TCAP_MT_ABORT: unpack_implicit_int(p, e, &m->origid); m->parms |= TCAP_PTF_ORIGID; return (0); } return (-EPROTO); case 8: /* orig and dest transaction id */ switch (mtype) { case TCAP_MT_CWP: case TCAP_MT_CWOP: unpack_implicit_int(p, e - 4, &m->origid); m->parms |= TCAP_PTF_ORIGID; unpack_implicit_int(p, e, &m->destid); m->parms |= TCAP_PTF_DESTID; return (0); } return (-EPROTO); } return (-EMSGSIZE); } /* ANSI dialog portion */ static int unpack_priv_dialog_portion(unsigned char **p, unsigned char *e, tr_msg_t * m) { uint err; uint tag; if (*p >= e) return (0); if (**p != (0xc0 | TCAP_TAG_PRIV_DIALOG)) return (0); if ((err = unpack_priv_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_PRIV_DIALOG) return (-EINVAL); m->dlg_beg = *p; m->dlg_end = e; *p = e; m->parms |= TCAP_PTF_DLGP; return (0); } /* ANSI component portion */ static int unpack_priv_component_portion(unsigned char **p, unsigned char *e, tr_msg_t * m, uint opt) { uint err; uint tag; if (opt) { if (*p >= e) return (0); if (**p != (0xc0 | TCAP_TAG_PRIV_CSEQ)) return (0); } if ((err = unpack_priv_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_PRIV_CSEQ) return (-EINVAL); m->cmp_beg = *p; m->cmp_end = e; *p = e; m->parms |= TCAP_PTF_CSEQ; return (0); } /* ANSI abort cause information */ static int unpack_priv_cause_info(unsigned char **p, unsigned char *e, tr_msg_t * m) { (void) p; (void) e; (void) m; /* FIXME */ return (-EFAULT); } static int tcap_priv_dec_uni(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_UNI; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_UNI))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 0))) return (err); return (0); } static int tcap_priv_dec_qwp(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_QWP; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_QWP))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_priv_dec_qwop(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_QWOP; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_QWOP))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_priv_dec_cwp(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_CWP; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_CWP))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_priv_dec_cwop(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_CWOP; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_CWOP))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_priv_dec_resp(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_RESP; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_RESP))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_priv_dec_abt(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_ABORT; if ((err = unpack_priv_trsid(&p, e, m, TCAP_MT_ABORT))) return (err); if ((err = unpack_priv_dialog_portion(&p, e, m))) return (err); if ((err = unpack_priv_cause_info(&p, e, m))) return (err); return (0); } /* * APPLICATION-TCAP version of Packages. (Used by the TR sub-layer.) * ------------------------------------------------------------------------- */ static inline int unpack_appl_origid(unsigned char **p, unsigned char *e, tr_msg_t * m) { uint err; uint tag; if ((err = unpack_appl_prim(p, &e, &tag))) return (err); if (tag != TCAP_TAG_APPL_ORIGID) return (-EPROTO); if (4 < e - *p || e - *p < 1) return (-EPROTO); unpack_implicit_int(p, e, &m->origid); m->parms |= TCAP_PTF_ORIGID; return (0); } static inline int unpack_appl_destid(unsigned char **p, unsigned char *e, tr_msg_t * m) { uint err; uint tag; if ((err = unpack_appl_prim(p, &e, &tag))) return (err); if (tag != TCAP_TAG_APPL_DESTID) return (-EPROTO); if (4 < e - *p || e - *p < 1) return (-EPROTO); unpack_implicit_int(p, e, &m->destid); m->parms |= TCAP_PTF_DESTID; return (0); } static inline int unpack_appl_trsid(unsigned char **p, unsigned char *e, tr_msg_t * m, const uint mtype) { uint err; switch (mtype) { case TCAP_MT_UNI: return (0); case TCAP_MT_QWP: if ((err = unpack_appl_origid(p, e, m))) return (err); return (0); case TCAP_MT_CWP: if ((err = unpack_appl_origid(p, e, m))) return (err); if ((err = unpack_appl_destid(p, e, m))) return (err); return (0); case TCAP_MT_RESP: case TCAP_MT_ABORT: if ((err = unpack_appl_destid(p, e, m))) return (err); return (0); } return (-EFAULT); } /* ITU-T dialog portion */ static int unpack_appl_dialog_portion(unsigned char **p, unsigned char *e, tr_msg_t * m) { uint err; uint tag; if (*p >= e) return (0); if (**p != (0x60 | TCAP_TAG_APPL_DIALOG)) return (0); if ((err = unpack_appl_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_APPL_DIALOG) return (-EINVAL); m->dlg_beg = *p; m->dlg_end = e; *p = e; m->parms |= TCAP_PTF_DLGP; return (0); } /* ITU-T component portion */ static int unpack_appl_component_portion(unsigned char **p, unsigned char *e, tr_msg_t * m, uint opt) { uint err; uint tag; if (opt) { if (*p >= e) return (0); if (**p != (0x60 | TCAP_TAG_APPL_CSEQ)) return (0); } if ((err = unpack_appl_cons(p, &e, &tag))) return (err); if (tag != TCAP_TAG_APPL_CSEQ) return (-EINVAL); m->cmp_beg = *p; m->cmp_end = e; *p = e; m->parms |= TCAP_PTF_CSEQ; return (0); } /* ITU-T abort cause information */ static int unpack_appl_cause_info(unsigned char **p, unsigned char *e, tr_msg_t * m) { (void) p; (void) e; (void) m; /* FIXME */ return (-EFAULT); } static int tcap_appl_dec_uni(unsigned char *p, unsigned char *e, tr_msg_t * m) { /* Application Context, Component Sequence */ int err; m->type = TCAP_MT_UNI; if ((err = unpack_appl_trsid(&p, e, m, TCAP_MT_UNI))) return (err); if ((err = unpack_appl_dialog_portion(&p, e, m))) return (err); if ((err = unpack_appl_component_portion(&p, e, m, 0))) return (err); return (0); } static int tcap_appl_dec_beg(unsigned char *p, unsigned char *e, tr_msg_t * m) { /* Originating Transaction Id, Application Context, Component Sequence */ int err; m->type = TCAP_MT_QWP; /* Query with permission to release */ if ((err = unpack_appl_trsid(&p, e, m, TCAP_MT_QWP))) return (err); if ((err = unpack_appl_dialog_portion(&p, e, m))) return (err); if ((err = unpack_appl_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_appl_dec_cnt(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; m->type = TCAP_MT_CWP; /* Conversation with permission to release */ if ((err = unpack_appl_trsid(&p, e, m, TCAP_MT_CWP))) return (err); if ((err = unpack_appl_dialog_portion(&p, e, m))) return (err); if ((err = unpack_appl_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_appl_dec_end(unsigned char *p, unsigned char *e, tr_msg_t * m) { /* Dest Transaction Id, Application Context, Component Sequence */ int err; m->type = TCAP_MT_RESP; /* Response */ if ((err = unpack_appl_trsid(&p, e, m, TCAP_MT_RESP))) return (err); if ((err = unpack_appl_dialog_portion(&p, e, m))) return (err); if ((err = unpack_appl_component_portion(&p, e, m, 1))) return (err); return (0); } static int tcap_appl_dec_abt(unsigned char *p, unsigned char *e, tr_msg_t * m) { /* Dest Transaction Id, P-Abort-Cause prim or U-Abort-Info const */ int err; if ((err = unpack_appl_trsid(&p, e, m, TCAP_MT_ABORT))) return (err); if ((err = unpack_appl_dialog_portion(&p, e, m))) return (err); if ((err = unpack_appl_cause_info(&p, e, m))) return (err); return (0); } /* * TCAP Package decoder. (Only decodes TR Sub-Layer.) * ------------------------------------------------------------------------- */ int tcap_dec_msg(unsigned char *p, unsigned char *e, tr_msg_t * m) { int err; uint tag; uint cls; if ((err = unpack_taglen(&p, &e, &tag, &cls))) return (err); if ((cls & 0xe0) == 0xe0) { /* private constructor */ switch (tag) { case TCAP_TAG_PRIV_UNI: /* Unidirectional */ return tcap_priv_dec_uni(p, e, m); case TCAP_TAG_PRIV_QWP: /* Begin or Query w/ permission */ return tcap_priv_dec_qwp(p, e, m); case TCAP_TAG_PRIV_QWOP: /* Query w/o permission */ return tcap_priv_dec_qwop(p, e, m); case TCAP_TAG_PRIV_RESP: /* End or Response */ return tcap_priv_dec_resp(p, e, m); case TCAP_TAG_PRIV_CWP: /* Continue or Conversation w/ permission */ return tcap_priv_dec_cwp(p, e, m); case TCAP_TAG_PRIV_CWOP: /* Conversation w/o permission */ return tcap_priv_dec_cwop(p, e, m); case TCAP_TAG_PRIV_ABORT: /* Abort */ return tcap_priv_dec_abt(p, e, m); } } if ((cls & 0xe0) == 0xa0) { /* application-wide constructor */ switch (tag) { case TCAP_TAG_APPL_UNI: /* Unidirectional */ return tcap_appl_dec_uni(p, e, m); case TCAP_TAG_APPL_BEGIN: /* Begin */ return tcap_appl_dec_beg(p, e, m); case TCAP_TAG_APPL_END: /* End */ return tcap_appl_dec_end(p, e, m); case TCAP_TAG_APPL_CONT: /* Continue */ return tcap_appl_dec_cnt(p, e, m); case TCAP_TAG_APPL_ABORT: /* Abort */ return tcap_appl_dec_abt(p, e, m); } } return (-EINVAL); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |