/************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 1986 - 2005, All Rights Reserved. */ /* */ /* PROPRIETARY AND CONFIDENTIAL */ /* */ /* MODULE NAME : mms_aref.c */ /* PRODUCT(S) : MMS-EASE */ /* */ /* MODULE DESCRIPTION : */ /* This module contains functions for encoding and decoding and the */ /* general manipulation of Application References. */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ ------------------------------------------- */ /* 04/04/05 EJV 07 MMSEASE: needs suicscse.h. */ /* 02/28/05 EJV 05 Elim Linux warnings in if (a=b) */ /* 03/28/05 JRB 05 Del suicacse header. */ /* 03/11/04 GLB 04 Cleaned up "thisFileName" */ /* 12/20/01 JRB 03 Converted to use ASN1R (re-entrant ASN1) */ /* 09/13/99 MDE 02 Added SD_CONST modifiers */ /* 07/29/97 DSF 01 Moved some of this functionality to SUIC */ /* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */ /* history. */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #include "glbsem.h" #include "mmsdefs.h" #include "mms_pcon.h" #include "asn1defs.h" #ifndef MMS_LITE #include "suicacse.h" #endif /************************************************************************/ /* For debug version, use a static pointer to avoid duplication of */ /* __FILE__ strings. */ #if defined(DEBUG_SISCO) && defined(S_MT_SUPPORT) SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; #endif static APP_REF *ar_fill_ptr; static ST_VOID ap_title_strt (ASN1_DEC_CTXT *aCtx); static ST_VOID ap_invoke_strt (ASN1_DEC_CTXT *aCtx); static ST_VOID ae_qual_strt (ASN1_DEC_CTXT *aCtx); static ST_VOID ae_invoke_strt (ASN1_DEC_CTXT *aCtx); static ST_VOID ar_ref_asn1_decode_done (ASN1_DEC_CTXT *aCtx); static ST_VOID ae_invoke_get (ASN1_DEC_CTXT *aCtx); static ST_VOID ae_qual_cnstr_done (ASN1_DEC_CTXT *aCtx); static ST_VOID ae_qual_get (ASN1_DEC_CTXT *aCtx); static ST_VOID ap_invoke_cnstr_done (ASN1_DEC_CTXT *aCtx); static ST_VOID ap_invoke_get (ASN1_DEC_CTXT *aCtx); static ST_VOID ap_cnstr_done (ASN1_DEC_CTXT *aCtx); static ST_VOID ap_title_get (ASN1_DEC_CTXT *aCtx); static ST_VOID ar_cnstr_done (ASN1_DEC_CTXT *aCtx); static ST_VOID ar_ref_strt (ASN1_DEC_CTXT *aCtx); /**************************************************************************/ /* ms_appref_to_asn1 */ /* Function to convert from an intermediate for of an ApplicationReference*/ /* to ASN.1. Function only supports FORM_2 of and ApplicationReference */ /**************************************************************************/ ST_RET ms_appref_to_asn1 (APP_REF *ar_ref_ptr, ST_UCHAR *build_buf_ptr, ST_INT build_buf_len, ST_UCHAR **ret_ptr, ST_INT *ret_len) { ST_INT ret_val; ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/ ASN1_ENC_CTXT *aCtx = &localEncCtx; S_LOCK_COMMON_RESOURCES (); if (ar_ref_ptr->form == APP_REF_FORM2) { asn1r_strt_asn1_bld (aCtx, build_buf_ptr,build_buf_len); asn1r_strt_constr (aCtx); if (ar_ref_ptr->ae_invoke_pres) { asn1r_strt_constr (aCtx); asn1r_wr_i32 (aCtx, ar_ref_ptr->ae_invoke); asn1r_fin_prim (aCtx, INT_CODE,UNI); asn1r_fin_constr (aCtx, 3,CTX,DEF); } if (ar_ref_ptr->ae_qual_pres) { asn1r_strt_constr (aCtx); asn1r_wr_i32 (aCtx, ar_ref_ptr->ae_qual.form_2); asn1r_fin_prim (aCtx, INT_CODE,UNI); asn1r_fin_constr (aCtx, 2,CTX,DEF); } if (ar_ref_ptr->ap_invoke_pres) { asn1r_strt_constr (aCtx); asn1r_wr_i32 (aCtx, ar_ref_ptr->ap_invoke); asn1r_fin_prim (aCtx, INT_CODE,UNI); asn1r_fin_constr (aCtx, 1,CTX,DEF); } if ((ar_ref_ptr->ap_title.form_2.num_comps) && (ar_ref_ptr->ap_title_pres)) { asn1r_strt_constr (aCtx); asn1r_wr_objid (aCtx, &ar_ref_ptr->ap_title.form_2.comps[0], ar_ref_ptr->ap_title.form_2.num_comps); asn1r_fin_prim (aCtx, OBJ_ID_CODE,UNI); asn1r_fin_constr (aCtx, 0,CTX,DEF); } asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); *ret_ptr = aCtx->asn1r_field_ptr+1; *ret_len = (&build_buf_ptr[build_buf_len] - aCtx->asn1r_field_ptr -1) & 0xffff; ret_val = SD_SUCCESS; } else /* not form 2 */ ret_val = MVE_BAD_APP_REF_FORM; /* Check for encode overrun */ if (aCtx->asn1r_encode_overrun) ret_val = ME_ASN1_ENCODE_OVERRUN; S_UNLOCK_COMMON_RESOURCES (); return (ret_val); } /************************************************************************/ /* DECODE FUNCTIONS FOR APPLICATION REFERENCE */ /* ms_asn1_to_appref */ /* Function to convert an ASN.1 encoded ApplicationReference to an */ /* intermediate form. These decode functions only support FORM_2 */ /************************************************************************/ ST_RET ms_asn1_to_appref (APP_REF *ar_ref_ptr, ST_UCHAR *buf_ptr, ST_INT buf_len) { ST_RET ret; ASN1_DEC_CTXT localDecCtx; /* For readability, use "aCtx" to access this.*/ ASN1_DEC_CTXT *aCtx = &localDecCtx; memset (aCtx, 0, sizeof (ASN1_DEC_CTXT)); /* CRITICAL: start clean. */ S_LOCK_COMMON_RESOURCES (); ar_fill_ptr = ar_ref_ptr; if (*buf_ptr == (CONSTR | SEQ_CODE)) ar_fill_ptr->form = APP_REF_FORM2; else ar_fill_ptr->form = APP_REF_FORM1; ar_fill_ptr->ap_title.form_2.num_comps = 0; ar_fill_ptr->ap_invoke_pres = SD_FALSE; ar_fill_ptr->ae_qual_pres = SD_FALSE; ar_fill_ptr->ae_invoke_pres = SD_FALSE; aCtx->asn1r_decode_method = ASN1_TAG_METHOD; ASN1R_TAG_ADD (aCtx, UNI|CONSTR,SEQ_CODE,ar_ref_strt); aCtx->asn1r_decode_done_fun = asn1r_done_err; aCtx->asn1r_err_fun = NULL; asn1r_decode_asn1 (aCtx, buf_ptr,buf_len); if (aCtx->asn1r_pdu_dec_err == NO_DECODE_ERR) ret = SD_SUCCESS; else ret = SD_FAILURE; S_UNLOCK_COMMON_RESOURCES (); return (ret); } static ST_VOID ar_ref_strt (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,ap_title_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,1,ap_invoke_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,ae_qual_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,3,ae_invoke_strt); aCtx->asn1r_decode_done_fun = ar_ref_asn1_decode_done; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ar_cnstr_done; } static ST_VOID ar_cnstr_done (ASN1_DEC_CTXT *aCtx) { } static ST_VOID ap_title_strt (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, UNI,OBJ_ID_CODE,ap_title_get); aCtx->asn1r_decode_done_fun = asn1r_done_err; } static ST_VOID ap_title_get (ASN1_DEC_CTXT *aCtx) { asn1r_get_objid (aCtx, &ar_fill_ptr->ap_title.form_2.comps[0], &ar_fill_ptr->ap_title.form_2.num_comps); if (ar_fill_ptr->ap_title.form_2.num_comps) ar_fill_ptr->ap_title_pres = SD_TRUE; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ap_cnstr_done; } static ST_VOID ap_cnstr_done (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, CTX|CONSTR,1,ap_invoke_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,ae_qual_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,3,ae_invoke_strt); aCtx->asn1r_decode_done_fun = ar_ref_asn1_decode_done; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ar_cnstr_done; } static ST_VOID ap_invoke_strt (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,ap_invoke_get); aCtx->asn1r_decode_done_fun = asn1r_done_err; } static ST_VOID ap_invoke_get (ASN1_DEC_CTXT *aCtx) { if (!asn1r_get_i32 (aCtx, &ar_fill_ptr->ap_invoke)) ar_fill_ptr->ap_invoke_pres = SD_TRUE; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ap_invoke_cnstr_done; } static ST_VOID ap_invoke_cnstr_done (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,ae_qual_strt); ASN1R_TAG_ADD (aCtx, CTX|CONSTR,3,ae_invoke_strt); aCtx->asn1r_decode_done_fun = ar_ref_asn1_decode_done; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ar_cnstr_done; } static ST_VOID ae_qual_strt (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,ae_qual_get); aCtx->asn1r_decode_done_fun = asn1r_done_err; } static ST_VOID ae_qual_get (ASN1_DEC_CTXT *aCtx) { if (!asn1r_get_i32 (aCtx, &ar_fill_ptr->ae_qual.form_2)) ar_fill_ptr->ae_qual_pres = SD_TRUE; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ae_qual_cnstr_done; } static ST_VOID ae_qual_cnstr_done (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, CTX|CONSTR,3,ae_invoke_strt); aCtx->asn1r_decode_done_fun = ar_ref_asn1_decode_done; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ar_cnstr_done; } static ST_VOID ae_invoke_strt (ASN1_DEC_CTXT *aCtx) { ASN1R_TAG_ADD (aCtx, UNI,INT_CODE,ae_invoke_get); aCtx->asn1r_decode_done_fun = asn1r_done_err; } static ST_VOID ae_invoke_get (ASN1_DEC_CTXT *aCtx) { if (!asn1r_get_i32 (aCtx, &ar_fill_ptr->ae_invoke)) ar_fill_ptr->ae_invoke_pres = SD_TRUE; aCtx->asn1r_decode_done_fun = ar_ref_asn1_decode_done; aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = ar_cnstr_done; } static ST_VOID ar_ref_asn1_decode_done (ASN1_DEC_CTXT *aCtx) { } /************************************************************************/ #ifndef MMS_LITE /************************************************************************/ /************************************************************************/ /* ms_arname_to_asn1 */ /* Function to convert from an arname to the ASN.1 encoded equivalent of*/ /* the ApplicationReference that corresponds to it. Returns SD_SUCCESS or */ /* ERROR CODE. */ /************************************************************************/ ST_RET ms_arname_to_asn1 (ST_CHAR *arname, ST_UCHAR *buf_ptr, ST_INT buf_len, ST_UCHAR **ret_ptr_addr, ST_INT *ret_len_addr) { ST_RET ret_val; APP_REF *app_ref_ptr; S_LOCK_COMMON_RESOURCES (); ret_val = MVE_DATA_CONVERT; if (!(ret_val = ms_arname_to_appref (arname, &app_ref_ptr))) { ret_val = ms_appref_to_asn1(app_ref_ptr, buf_ptr, buf_len, ret_ptr_addr, ret_len_addr); } S_UNLOCK_COMMON_RESOURCES (); return (ret_val); } /************************************************************************/ /* ms_asn1_to_arname */ /* Function to convert from an ASN.1 encoded application reference to */ /* the arname that corresponds to it. Return SD_SUCCESS or ERROR CODE. */ /************************************************************************/ ST_RET ms_asn1_to_arname (ST_CHAR *arname, ST_UCHAR *asn1_ptr, ST_INT asn1_len) { ST_RET ret_val; APP_REF app_reference; S_LOCK_COMMON_RESOURCES (); ret_val = MVE_ASN1_DECODE_ERR; if (!(ret_val = ms_asn1_to_appref (&app_reference, asn1_ptr, asn1_len))) { ret_val = ms_appref_to_arname (arname, &app_reference); } S_UNLOCK_COMMON_RESOURCES (); return (ret_val); } /************************************************************************/ /* ms_arname_to_appref */ /* Function to convert from the C representation of an arname to the C */ /* representation of an ApplicationReference. Returns SD_SUCCESS or */ /* ERROR CODE. */ /************************************************************************/ ST_RET ms_arname_to_appref (ST_CHAR *arname, APP_REF **appref_ptr_addr) { ST_RET ret_val; S_LOCK_COMMON_RESOURCES (); ret_val = MVE_DATA_CONVERT; if (arname) { if ((*appref_ptr_addr = s_find_proc (arname)) != NULL) ret_val = SD_SUCCESS; } else *appref_ptr_addr = NULL; S_UNLOCK_COMMON_RESOURCES (); return (ret_val); } /************************************************************************/ /* ms_appref_to_arname */ /* Function to convert from the C representation of an ApplicationRef. */ /* to the C representation of an arname. Returns SD_SUCCESS or ERROR CODE.*/ /* The argument arname has to be a pointer to a place big enough to */ /* hold the arname (MAX_AR_LEN+1). */ /************************************************************************/ ST_RET ms_appref_to_arname (ST_CHAR *arname, APP_REF *appref_addr) { ST_RET ret; S_LOCK_COMMON_RESOURCES (); ret = MVE_DATA_CONVERT; if (arname && appref_addr) { /* match the AE-Qualifier */ if (s_find_arname (appref_addr, appref_addr->ae_qual_pres, arname)) ret = SD_SUCCESS; } S_UNLOCK_COMMON_RESOURCES (); return (ret); } /************************************************************************/ #endif /* end ifndef MMS_LITE */ /************************************************************************/