/************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 1986 - 2002, All Rights Reserved. */ /* */ /* PROPRIETARY AND CONFIDENTIAL */ /* */ /* MODULE NAME : mms_ced.c */ /* PRODUCT(S) : MMSEASE, MMSEASE-LITE */ /* */ /* MODULE DESCRIPTION : */ /* This module contains common primitive encode/decode functions. */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ ------------------------------------------- */ /* 01/22/02 JRB 05 Add _ms_fin_pdu & _ms_fin_pdu_log (these */ /* replace functionality of _ms_fin_pdu_debug). */ /* Use new "asn1r_buf_end" instead of globals. */ /* 12/20/01 JRB 04 Converted to use ASN1R (re-entrant ASN1) */ /* 04/28/00 JRB 03 Lint cleanup */ /* 09/13/99 MDE 02 Added SD_CONST modifiers */ /* 03/23/99 MDE 01 Changes to decode buffer allocation scheme */ /* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */ /* history. */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #include "mmsdefs.h" #include "asn1defs.h" /************************************************************************/ /************************************************************************/ /* For debug version, use a static pointer to avoid duplication of */ /* __FILE__ strings. */ /************************************************************************/ #ifdef DEBUG_SISCO SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; #endif /************************************************************************/ /* COMPANION STANDARD INFO DECODE FUNCTIONS */ /************************************************************************/ #ifdef CS_SUPPORT static ST_VOID mms_cs_start (ASN1_DEC_CTXT *aCtx); static ST_VOID mms_cs_cstr_done (ASN1_DEC_CTXT *aCtx); #endif /************************************************************************/ /************************************************************************/ /* _ms_set_cs_check */ /* This function is used to check for CS info after rest of PDU has */ /* been decoded. */ /************************************************************************/ ST_VOID _ms_set_cs_check (ASN1_DEC_CTXT *aCtx) { aCtx->asn1r_decode_done_fun = _mms_dec_done_ok; _ms_set_cs_check2 (aCtx); } /************************************************************************/ /* _ms_set_cs_check2 */ /* use this function to avoid setting the aCtx->asn1r_decode_done_fun */ /************************************************************************/ ST_VOID _ms_set_cs_check2 (ASN1_DEC_CTXT *aCtx) { aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* need to use TAG method */ #ifdef CS_SUPPORT #ifndef MMS_LITE if (mms_chan_info[_mmsdechan].version) /* IS only */ ASN1R_TAG_ADD (aCtx, CTX|CONSTR,79,mms_cs_start); /* need to check for CS */ #else if (mmsl_version) /* IS only */ ASN1R_TAG_ADD (aCtx, CTX|CONSTR,79,mms_cs_start); /* need to check for CS */ #endif #endif /* in case this is cstr done */ if (!aCtx->asn1r_msg_level) aCtx->asn1r_c_done_fun[1] = NULL; /* OK for all to be complete */ else /* need to go through all upper levels */ aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = _ms_set_cs_check2; } #ifdef CS_SUPPORT /************************************************************************/ /* mms_cs_start */ /************************************************************************/ static ST_VOID mms_cs_start (ASN1_DEC_CTXT *aCtx) { _mmsdec_rslt->cs.cs_ptr = aCtx->asn1r_field_ptr; /* start of CS info */ asn1r_set_all_cstr_done (aCtx); /* clear up all cstr done's */ asn1r_parse_cstr_contents (aCtx, mms_cs_cstr_done); /* verify ASN.1 */ } /************************************************************************/ /* mms_cs_cstr_done */ /************************************************************************/ static ST_VOID mms_cs_cstr_done (ASN1_DEC_CTXT *aCtx) { _mmsdec_rslt->cs.cs_pres = SD_TRUE; /* CS info was OK */ _mmsdec_rslt->cs.cs_len = aCtx->asn1r_field_ptr - _mmsdec_rslt->cs.cs_ptr; aCtx->asn1r_decode_done = SD_TRUE; } #endif /************************************************************************/ /************************************************************************/ /* EXTERNAL decode functions */ /************************************************************************/ /************************************************************************/ /* _ms_chk_for_extern */ /************************************************************************/ /* This function is called when adding tags when an EXTERNAL may be */ /* encountered. Pass in the destination and the constructor done fun */ /* Currently do not parse EXTERNAL itself, allow user to do this. */ static ST_VOID (*ext_done_fun)(ASN1_DEC_CTXT *aCtx); static ST_VOID ext_seq_start (ASN1_DEC_CTXT *aCtx); static ST_INT *ext_len_ptr; /* save in case EXTERNAL found */ static ST_UCHAR **ext_buf_ptr_ptr; ST_VOID _ms_chk_for_extern (ASN1_DEC_CTXT *aCtx, ST_INT *len_ptr, ST_UCHAR **buf_ptr_ptr, ST_VOID (*done_fun)(ASN1_DEC_CTXT *aCtx)) { ASN1R_TAG_ADD (aCtx, UNI|CONSTR,EXTERN_CODE,ext_seq_start); /* get the EXT seq*/ ext_done_fun = done_fun; ext_len_ptr = len_ptr; ext_buf_ptr_ptr = buf_ptr_ptr; } /************************************************************************/ /* ext_seq_start */ /* External encountered */ /************************************************************************/ static ST_VOID ext_seq_start (ASN1_DEC_CTXT *aCtx) { MLOG_CDEC0 ("ext_seq_start"); /* save pointer and length of the external data element */ *ext_len_ptr = aCtx->asn1r_elmnt_len + (aCtx->asn1r_field_ptr - aCtx->asn1r_field_start); *ext_buf_ptr_ptr = aCtx->asn1r_field_start; asn1r_parse_cstr_contents (aCtx, ext_done_fun); } /************************************************************************/ /************************************************************************/ /* GENERAL DECODE FUNCTIONS */ /************************************************************************/ /* mms_req_not_supp */ /************************************************************************/ ST_VOID mms_req_not_supp (ASN1_DEC_CTXT *aCtx) { MLOG_CDEC0 ("mms_req_not_supp"); if (_mmsdec_rslt->op == MMSOP_INFO_RPT || _mmsdec_rslt->op == MMSOP_USTATUS || _mmsdec_rslt->op == MMSOP_EVENT_NOT) asn1r_set_dec_err (aCtx, UNCONF_UNREC_SERV); else asn1r_set_dec_err (aCtx, REQ_UNREC_SERV); } /************************************************************************/ /* mms_rsp_not_supp */ /************************************************************************/ ST_VOID mms_rsp_not_supp (ASN1_DEC_CTXT *aCtx) { MLOG_CDEC0 ("mms_rsp_not_supp "); asn1r_set_dec_err (aCtx, RESP_UNREC_SERV); } /************************************************************************/ /************************************************************************/ /* _mms_null_pdu_dec */ /* This function is called from MMSDEC when the opcode for a NULL PDU */ /* is being decoded. */ /************************************************************************/ ST_VOID _mms_null_pdu_dec (ASN1_DEC_CTXT *aCtx) { MLOG_CDEC0 ("Decoding Null PDU (examine opcode for service)"); _ms_set_cs_check (aCtx); /* check to see of CS info pres */ } /************************************************************************/ /* _mms_dec_done_ok */ /* general decode done function, used for most primitive decodes */ /************************************************************************/ ST_VOID _mms_dec_done_ok (ASN1_DEC_CTXT *aCtx) { _mmsdec_rslt->data_pres = _mms_dec_info_pres; /* write data pres flag */ _mmsdec_rslt->data_ptr = _mms_dec_info; /* write pointer */ } /************************************************************************/ /* _mms_dec_buf_free */ /* error decoding the request: free allocated storage. */ /************************************************************************/ ST_VOID _mms_dec_buf_free (ASN1_DEC_CTXT *aCtx, ST_RET err) { (*m_free_os_fun)(_mms_dec_info); } /************************************************************************/ /* _ms_fin_pdu */ /* User passes ptr to PDU len pPduLen, this function sets (*pPduLen). */ /* RETURNS: pointer to MMS PDU */ /************************************************************************/ ST_UCHAR *_ms_fin_pdu (ASN1_ENC_CTXT *aCtx, ST_INT type, ST_INT *pPduLen) { asn1r_fin_constr (aCtx, (ST_INT16)type, CTX,DEF); *pPduLen = aCtx->asn1r_buf_end - aCtx->asn1r_field_ptr; return (aCtx->asn1r_field_ptr + 1); } #ifdef DEBUG_SISCO /************************************************************************/ /* _ms_fin_pdu_log */ /* Write complete MMS PDU to log. */ /************************************************************************/ ST_VOID _ms_fin_pdu_log (ST_INT type, ST_CHAR *msg_ptr, ST_UCHAR *pduPtr, ST_INT pduLen) { /* Do PDU Encode logging */ if (type == MMSRESP) { MLOG_ENC2 ("%s Response built : len = %d",msg_ptr, pduLen); } else { MLOG_ENC2 ("%s Request built : len = %d",msg_ptr, pduLen); } MLOG_ENCH (pduLen,pduPtr); return; } #endif /* DEBUG_SISCO */