935 lines
30 KiB
C
935 lines
30 KiB
C
/************************************************************************/
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
|
/************************************************************************/
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
|
/* 1986 - 2006, All Rights Reserved. */
|
|
/* */
|
|
/* PROPRIETARY AND CONFIDENTIAL */
|
|
/* */
|
|
/* MODULE NAME : mms_alta.c */
|
|
/* PRODUCT(S) : MMSEASE */
|
|
/* */
|
|
/* MODULE DESCRIPTION : */
|
|
/* Function to decode ASN.1 type definitions into Runtime typedefs */
|
|
/* */
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
|
/* */
|
|
/* MODIFICATION LOG : */
|
|
/* Date Who Rev Comments */
|
|
/* -------- --- ------ ------------------------------------------- */
|
|
/* 08/09/06 JRB 20 Add ms_aa_to_asn1_2. */
|
|
/* 02/22/05 JRB 19 Make "sp" local to avoid VXWORKS conflict. */
|
|
/* 02/06/02 JRB 18 Move ms_mk_rt_aa* to new mms_rtaa.c. */
|
|
/* 12/20/01 JRB 17 Converted to use ASN1R (re-entrant ASN1) */
|
|
/* 11/15/01 EJV 16 Added support for new MMS type UtcTime: */
|
|
/* find_named_comp: added case for RT_UTC_TIME; */
|
|
/* _ms_log_runtime_aa: add case for RT_UTC_TIME;*/
|
|
/* 09/26/00 JRB 15 Add SD_CONST on ms_mk_rt_aa* */
|
|
/* 07/28/00 JRB 14 Use ms_comp_name_find for everyone. */
|
|
/* 07/13/00 JRB 13 Use new ms_comp_name_find for MMS LITE. */
|
|
/* 04/28/00 JRB 12 Lint cleanup */
|
|
/* 09/13/99 RKR 11 Respaced a macro for the install utility */
|
|
/* 09/13/99 MDE 10 Added SD_CONST modifiers */
|
|
/* 07/30/99 MDE 09 Replaced CSTR_DONE_FUN macro use */
|
|
/* 09/21/98 MDE 08 Minor lint cleanup */
|
|
/* 09/10/98 MDE 07 Changes to work better with MMS-LITE */
|
|
/* 06/15/98 MDE 06 Changes to allow compile under C++ */
|
|
/* 03/12/98 MDE 05 '_ms_m_get_rt_info' use change */
|
|
/* 03/11/98 MDE 04 Removed NEST_RT_TYPES */
|
|
/* 02/10/98 MDE 03 No longer use runtime type 'loops' element */
|
|
/* rearranged for MMS-LITE (MMS_ALTA_DATA) */
|
|
/* 12/29/97 MDE 02 Corrected LOCK/UNLOCK problems */
|
|
/* 06/09/97 MDE 01 Modified Runtime Type handling */
|
|
/* 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_pvar.h"
|
|
#include "mms_vvar.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
|
|
|
|
/************************************************************************/
|
|
|
|
static ST_RET wr_altAcc (ASN1_ENC_CTXT *aCtx, ALT_ACC_EL **aap, ALT_ACC_EL *last_aa);
|
|
static ST_RET wr_altAccSel (ASN1_ENC_CTXT *aCtx, ALT_ACC_EL **aap, ALT_ACC_EL *last_aa);
|
|
static ALT_ACC_EL *find_start_aa_nest (ALT_ACC_EL *aa, ALT_ACC_EL *last_aa);
|
|
static ST_VOID alt_acc_seq_start (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID alt_acc_seq_cstr_done (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID add_alt_acc_tags (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID named_start (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID get_component_name (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID named_cstr_done (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_comp (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_index (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_index_range (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_ir_low (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_ir_num (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_ir_cstr_done (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_acc_all (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_cstr_done (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_comp (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_index (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_index_range (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_ir_low (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_ir_num (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_ir_cstr_done (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID sel_alt_acc_all (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID alt_acc_dec_done_ok (ASN1_DEC_CTXT *aCtx);
|
|
static ST_VOID inc_dest_aa (ASN1_DEC_CTXT *aCtx);
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* Static internal variables, used during decode */
|
|
|
|
static ALT_ACC_EL *dest_aa;
|
|
static ALT_ACC_EL *end_dest_aa;
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* ms_asn1_to_aa */
|
|
/* Convert an ASN.1 encoded AA to an array of 'ALT_ACC_EL' */
|
|
/* Allocates an array of 'm_max_dec_aa' elements, using chk_calloc, */
|
|
/* does not realloc to correct size. */
|
|
/************************************************************************/
|
|
|
|
|
|
ST_RET ms_asn1_to_aa (ST_UCHAR *asn1ptr, ST_INT asn1len, ALT_ACCESS *alt_acc_out)
|
|
{
|
|
ALT_ACC_EL *dest_aa_head;
|
|
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 ();
|
|
|
|
/* Allocate the output AA array */
|
|
dest_aa = (ALT_ACC_EL *) chk_calloc (m_max_dec_aa, sizeof (ALT_ACC_EL));
|
|
end_dest_aa = dest_aa + (m_max_dec_aa -1);
|
|
dest_aa_head = dest_aa;
|
|
|
|
/* Set up ASN.1 decode tools */
|
|
aCtx->asn1r_decode_method = ASN1_TAG_METHOD; /* select tag method */
|
|
aCtx->asn1r_decode_done_fun = asn1r_done_err;/* not legal to be done at this time */
|
|
aCtx->asn1r_err_fun = NULL;
|
|
|
|
/* We are using an alternate entry point into the ASN.1 decode, where */
|
|
/* the outer tag is not required. */
|
|
|
|
add_alt_acc_tags (aCtx);
|
|
aCtx->asn1r_c_done_fun[0] = NULL;
|
|
aCtx->asn1r_decode_done_fun = alt_acc_dec_done_ok;
|
|
asn1r_decode_asn1_seq (aCtx, asn1ptr, asn1len); /* decode ASN.1 'Data' entity */
|
|
|
|
if (aCtx->asn1r_pdu_dec_err != NO_DECODE_ERR) /* check for sucess or return error */
|
|
{
|
|
chk_free (dest_aa_head);
|
|
MLOG_NERR0 ("ASN.1 to AA Decode Error");
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
|
return (MVE_DATA_CONVERT);
|
|
}
|
|
|
|
alt_acc_out->aa = dest_aa_head;
|
|
alt_acc_out->num_aa = dest_aa - dest_aa_head;
|
|
|
|
/* Log the alternate access, if selected */
|
|
if (mms_debug_sel & MMS_LOG_AA)
|
|
ms_log_alt_access (alt_acc_out);
|
|
|
|
/* save the high water mark */
|
|
if (alt_acc_out->num_aa > m_hw_dec_aa)
|
|
m_hw_dec_aa = alt_acc_out->num_aa;
|
|
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* alt_acc_seq_start */
|
|
/* This function is called whe the outer UNI SEQ constructor of the */
|
|
/* AlternateAcess is found. Used only for continuing the decode for a */
|
|
/* nested AA spec, as the outer constructor is stripped */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID alt_acc_seq_start (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
add_alt_acc_tags (aCtx);
|
|
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = alt_acc_seq_cstr_done;
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* alt_acc_seq_cstr_done */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID alt_acc_seq_cstr_done (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("alt_acc_seq_cstr_done");
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* add_alt_acc_tags */
|
|
/* Add appropriate tags for the outer 'AlternateAccess' */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID add_alt_acc_tags (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 0, sel_alt_acc);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 1, sel_acc_comp);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 2, sel_acc_index);
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 3, sel_acc_index_range);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 4, sel_acc_all);
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 5, named_start);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* named_start */
|
|
/* Constructor for the 'named' element of the 'AlternateAccess' */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID named_start (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("named_start");
|
|
ASN1R_TAG_ADD (aCtx, CTX, 0, get_component_name);
|
|
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = named_cstr_done;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* get_component_name */
|
|
/* The 'componentName' element of the 'named' element */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID get_component_name (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("get_component_name");
|
|
if (asn1r_get_identifier (aCtx, dest_aa->comp_name))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
dest_aa->comp_name_pres = SD_TRUE;
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 0, sel_alt_acc);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 1, sel_acc_comp);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 2, sel_acc_index);
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 3, sel_acc_index_range);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 4, sel_acc_all);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* named_cstr_done */
|
|
/* End of 'named' constructor */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID named_cstr_done (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("named_cstr_done");
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_comp */
|
|
/* The 'component' of the 'selectAccess' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_comp (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_comp");
|
|
if (asn1r_get_identifier (aCtx, dest_aa->u.component))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
dest_aa->sel_type = AA_COMP;
|
|
inc_dest_aa (aCtx);
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_index */
|
|
/* The 'index' of the 'selectAccess' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_index (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_index");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.index))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
dest_aa->sel_type = AA_INDEX;
|
|
inc_dest_aa (aCtx);
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_index_range */
|
|
/* The 'indexRange' of the 'selectAccess' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_index_range (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_index_range");
|
|
|
|
dest_aa->sel_type = AA_INDEX_RANGE;
|
|
ASN1R_TAG_ADD (aCtx, CTX,0, sel_acc_ir_low);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_ir_low */
|
|
/* The 'low_index' of the 'indexRange' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_ir_low (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_ir_low");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.ir.low_index))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
ASN1R_TAG_ADD (aCtx, CTX, 1, sel_acc_ir_num);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_ir_num */
|
|
/* The 'numberOfElements' of the 'indexRange' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_ir_num (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_ir_num");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.ir.num_elmnts))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = sel_acc_ir_cstr_done;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_ir_cstr_done */
|
|
/* End of the 'indexRange' constructor */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_ir_cstr_done (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_ir_cstr_done");
|
|
inc_dest_aa (aCtx);
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_acc_all */
|
|
/* The 'allElements' of the 'selectAccess' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_acc_all (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_acc_all");
|
|
dest_aa->sel_type = AA_ALL;
|
|
inc_dest_aa (aCtx);
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* sel_alt_acc */
|
|
/* The 'selectAlternateAccess' constructor has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc");
|
|
|
|
ASN1R_TAG_ADD (aCtx, CTX, 0, sel_alt_acc_comp);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 1, sel_alt_acc_index);
|
|
ASN1R_TAG_ADD (aCtx, CTX | CONSTR, 2, sel_alt_acc_index_range);
|
|
ASN1R_TAG_ADD (aCtx, CTX, 3, sel_alt_acc_all);
|
|
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = sel_alt_acc_cstr_done;
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_cstr_done */
|
|
/* End of the 'selectAlternateAccess' constructor */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_cstr_done (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_cstr_done");
|
|
dest_aa->sel_type = AA_END_NEST;
|
|
inc_dest_aa (aCtx);
|
|
add_alt_acc_tags (aCtx);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_comp */
|
|
/* The 'component' of the 'selectAlternateAccesss' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_comp (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_comp");
|
|
if (asn1r_get_identifier (aCtx, dest_aa->u.component))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
dest_aa->sel_type = AA_COMP_NEST;
|
|
inc_dest_aa (aCtx);
|
|
ASN1R_TAG_ADD (aCtx, UNI | CONSTR, SEQ_CODE, alt_acc_seq_start);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_index */
|
|
/* The 'index' of the 'selectAlternateAccesss' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_index (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_index");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.index))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
dest_aa->sel_type = AA_INDEX_NEST;
|
|
inc_dest_aa (aCtx);
|
|
ASN1R_TAG_ADD (aCtx, UNI | CONSTR, SEQ_CODE, alt_acc_seq_start);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_index_range */
|
|
/* The 'indexRange' of 'selectAlternateAccesss' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_index_range (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_index_range");
|
|
dest_aa->sel_type = AA_INDEX_RANGE_NEST;
|
|
ASN1R_TAG_ADD (aCtx, CTX,0, sel_alt_acc_ir_low);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_ir_low */
|
|
/* The 'low_index' of the 'indexRange' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_ir_low (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_ir_low");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.ir.low_index))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
ASN1R_TAG_ADD (aCtx, CTX, 1, sel_alt_acc_ir_num);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_ir_num */
|
|
/* The 'numberOfElements' of the 'indexRange' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_ir_num (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_ir_num");
|
|
if (asn1r_get_u32 (aCtx, &dest_aa->u.ir.num_elmnts))
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
else
|
|
{
|
|
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = sel_alt_acc_ir_cstr_done;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_ir_cstr_done */
|
|
/* End of the 'indexRange' constructor */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_ir_cstr_done (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_ir_cstr_done");
|
|
inc_dest_aa (aCtx);
|
|
ASN1R_TAG_ADD (aCtx, UNI | CONSTR, SEQ_CODE, alt_acc_seq_start);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* sel_alt_acc_all */
|
|
/* The 'allElements' of 'selectAlternateAccesss' has been encountered */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID sel_alt_acc_all (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("sel_alt_acc_all");
|
|
dest_aa->sel_type = AA_ALL_NEST;
|
|
inc_dest_aa (aCtx);
|
|
ASN1R_TAG_ADD (aCtx, UNI | CONSTR, SEQ_CODE, alt_acc_seq_start);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* inc_dest_aa */
|
|
/* Increment the destination AA pointer, verify no overrun */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID inc_dest_aa (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
if (++dest_aa > end_dest_aa)
|
|
asn1r_set_dec_err (aCtx, RESP_BAD_VALUE);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* alt_acc_dec_done_ok */
|
|
/* 'decode done fun' for the ASN.1 to AA decode */
|
|
/************************************************************************/
|
|
|
|
static ST_VOID alt_acc_dec_done_ok (ASN1_DEC_CTXT *aCtx)
|
|
{
|
|
MLOG_CDEC0 ("alt_dec_done_ok");
|
|
}
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* ms_aa_to_asn1 */
|
|
/* Encode Alternate Access, assume that the encode tools have been */
|
|
/* initalized */
|
|
/* NOTE: The higher level function "ms_aa_to_asn1_2" is more convenient.*/
|
|
/* Call this directly only if "AA" encode is in the middle of a */
|
|
/* larger encode. */
|
|
/************************************************************************/
|
|
|
|
static ST_INT encodeDone;
|
|
|
|
ST_RET ms_aa_to_asn1 (ASN1_ENC_CTXT *aCtx, ALT_ACCESS *alt_acc)
|
|
{
|
|
ALT_ACC_EL *aa;
|
|
ALT_ACC_EL *last_aa;
|
|
ST_RET ret;
|
|
|
|
S_LOCK_COMMON_RESOURCES ();
|
|
aa = alt_acc->aa;
|
|
last_aa = aa; /* save pointer to aa[0] */
|
|
aa += (alt_acc->num_aa-1); /* go from bottom to top */
|
|
|
|
/* Write the AlternateAccess 'Seq Of Choice' elements until we have */
|
|
/* gone through all AA elements */
|
|
ret = SD_SUCCESS;
|
|
encodeDone = SD_FALSE;
|
|
while (!encodeDone && ret == SD_SUCCESS)
|
|
{
|
|
if (aa == last_aa)
|
|
encodeDone = SD_TRUE;
|
|
ret = wr_altAcc (aCtx, &aa, last_aa);
|
|
}
|
|
|
|
/* Verify no asn.1 encode buffer overrun */
|
|
if (aCtx->asn1r_encode_overrun)
|
|
{
|
|
MLOG_NERR0 ("AA to ASN.1 : buffer overrun");
|
|
ret = ME_ASN1_ENCODE_OVERRUN;
|
|
}
|
|
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
|
return (ret);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* wr_altAcc */
|
|
/************************************************************************/
|
|
|
|
/* NOTE : This function is entered recursively to encode parts of the */
|
|
/* AlternateAccess */
|
|
|
|
static ST_RET wr_altAcc (ASN1_ENC_CTXT *aCtx, ALT_ACC_EL **aap, ALT_ACC_EL *last_aa)
|
|
{
|
|
ALT_ACC_EL *aa;
|
|
ALT_ACC_EL *aa_start_nest;
|
|
ST_RET ret;
|
|
|
|
/* get a working pointer */
|
|
aa = *aap;
|
|
|
|
/* Write the AlternateAccess sequence of choice element */
|
|
|
|
/* First need to see if this is the start of a named component, so */
|
|
/* we can start the constructor if so */
|
|
|
|
/* If this is a nested AA element, need to find the start element */
|
|
if (aa->sel_type == AA_END_NEST)
|
|
{
|
|
aa_start_nest = find_start_aa_nest (aa, last_aa);
|
|
if (!aa_start_nest)
|
|
{
|
|
MLOG_NERR0 ("AA to ASN.1 : Bad AA");
|
|
return (MVE_AA_SELECT);
|
|
}
|
|
|
|
if (aa_start_nest->comp_name_pres)
|
|
asn1r_strt_constr (aCtx); /* Start 'named' seq cstr */
|
|
}
|
|
else /* not the start of a nested */
|
|
{
|
|
if (aa->comp_name_pres)
|
|
asn1r_strt_constr (aCtx); /* Start 'named' seq cstr */
|
|
}
|
|
|
|
/* OK, if this was a named component, the constructor has been started */
|
|
/* Go ahead and write the AlternateAccessSelection element */
|
|
|
|
ret = wr_altAccSel (aCtx, &aa, last_aa); /* write the altAccSel */
|
|
|
|
*aap = aa;
|
|
return (ret);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* wr_altAccSel */
|
|
/************************************************************************/
|
|
|
|
/* NOTE : This function is entered recursively to encode parts of the */
|
|
/* AlternateAccess */
|
|
|
|
static ST_RET wr_altAccSel (ASN1_ENC_CTXT *aCtx, ALT_ACC_EL **aap, ALT_ACC_EL *last_aa)
|
|
{
|
|
ALT_ACC_EL *aa;
|
|
ALT_ACC_EL *aa_start_nest;
|
|
ST_RET ret;
|
|
|
|
ret = SD_SUCCESS;
|
|
aa = *aap; /* get working pointer */
|
|
switch (aa->sel_type)
|
|
{
|
|
case AA_COMP :
|
|
asn1r_wr_vstr (aCtx, aa->u.component);
|
|
asn1r_fin_prim (aCtx, 1,CTX);
|
|
break;
|
|
|
|
case AA_INDEX :
|
|
asn1r_wr_u32 (aCtx, aa->u.index);
|
|
asn1r_fin_prim (aCtx, 2,CTX);
|
|
break;
|
|
|
|
case AA_INDEX_RANGE :
|
|
asn1r_strt_constr (aCtx);
|
|
asn1r_wr_u32 (aCtx, aa->u.ir.num_elmnts);
|
|
asn1r_fin_prim (aCtx, 1,CTX);
|
|
asn1r_wr_u32 (aCtx, aa->u.ir.low_index);
|
|
asn1r_fin_prim (aCtx, 0,CTX);
|
|
asn1r_fin_constr (aCtx, 3,CTX,DEF);
|
|
break;
|
|
|
|
case AA_ALL :
|
|
asn1r_fin_prim (aCtx, 4,CTX);
|
|
break;
|
|
|
|
case AA_END_NEST :
|
|
|
|
/* First we need to find the NEST START element so that we can */
|
|
/* encode all elements on this level before returning, so that we */
|
|
/* can add the outer constructor */
|
|
|
|
aa_start_nest = find_start_aa_nest (aa, last_aa);
|
|
if (!aa_start_nest)
|
|
{
|
|
MLOG_NERR0 ("AA to ASN.1 : Bad AA");
|
|
return (MVE_AA_SELECT);
|
|
}
|
|
|
|
asn1r_strt_constr (aCtx); /* Start SelectAlternateAccess constructor */
|
|
asn1r_strt_constr (aCtx); /* Start outer AlternateAccess constructor */
|
|
--aa; /* Begin with next element */
|
|
while (aa != aa_start_nest)
|
|
{
|
|
ret = wr_altAcc (aCtx, &aa, last_aa); /* wr_altAcc will decrement aa */
|
|
if (aa == last_aa)
|
|
encodeDone = SD_TRUE;
|
|
|
|
if (ret != SD_SUCCESS)
|
|
return (ret);
|
|
}
|
|
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* Outer AlternateAccess cstr */
|
|
|
|
/* Now write the accessSelection */
|
|
switch (aa->sel_type)
|
|
{
|
|
case AA_COMP_NEST :
|
|
asn1r_wr_vstr (aCtx, aa->u.component);
|
|
asn1r_fin_prim (aCtx, 0,CTX);
|
|
break;
|
|
|
|
case AA_INDEX_NEST :
|
|
asn1r_wr_u32 (aCtx, aa->u.index);
|
|
asn1r_fin_prim (aCtx, 1,CTX);
|
|
break;
|
|
|
|
case AA_INDEX_RANGE_NEST :
|
|
asn1r_strt_constr (aCtx);
|
|
asn1r_wr_u32 (aCtx, aa->u.ir.num_elmnts);
|
|
asn1r_fin_prim (aCtx, 1,CTX);
|
|
asn1r_wr_u32 (aCtx, aa->u.ir.low_index);
|
|
asn1r_fin_prim (aCtx, 0,CTX);
|
|
asn1r_fin_constr (aCtx, 2,CTX,DEF);
|
|
break;
|
|
|
|
case AA_ALL_NEST :
|
|
asn1r_fin_prim (aCtx, 3,CTX);
|
|
break;
|
|
}
|
|
|
|
/* Finish the accessSelection constructor */
|
|
asn1r_fin_constr (aCtx, 0,CTX,DEF);
|
|
break;
|
|
|
|
/* These should never be encountered at this level */
|
|
case AA_COMP_NEST :
|
|
case AA_INDEX_NEST :
|
|
case AA_INDEX_RANGE_NEST :
|
|
case AA_ALL_NEST :
|
|
default :
|
|
MLOG_NERR0 ("AA to ASN.1 : Bad AA sel_type value");
|
|
return SD_FAILURE;
|
|
break;
|
|
}
|
|
|
|
|
|
/* For the elements that are not 'end nest', add the 'named' element */
|
|
/* as required */
|
|
|
|
if (aa->sel_type != AA_END_NEST)
|
|
{
|
|
if (aa->comp_name_pres)
|
|
{
|
|
asn1r_wr_vstr (aCtx, aa->comp_name); /* Write the name */
|
|
asn1r_fin_prim (aCtx, 0,CTX);
|
|
asn1r_fin_constr (aCtx, 5,CTX,DEF); /* Finish the 'named' cstr */
|
|
}
|
|
}
|
|
|
|
if (aa > last_aa)
|
|
--aa;
|
|
*aap = aa;
|
|
return (ret);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* find_start_aa_nest */
|
|
/************************************************************************/
|
|
|
|
static ALT_ACC_EL *find_start_aa_nest (ALT_ACC_EL *aa,
|
|
ALT_ACC_EL *last_aa)
|
|
{
|
|
ALT_ACC_EL *aa2;
|
|
ST_INT nest;
|
|
|
|
aa2 = aa-1; /* Start with the element above */
|
|
nest = 0; /* keep track of nesting level */
|
|
while (SD_TRUE)
|
|
{
|
|
if (aa2->sel_type == AA_COMP_NEST ||
|
|
aa2->sel_type == AA_INDEX_NEST ||
|
|
aa2->sel_type == AA_INDEX_RANGE_NEST ||
|
|
aa2->sel_type == AA_ALL_NEST)
|
|
{
|
|
if (nest == 0) /* we found the matching start nest */
|
|
break;
|
|
|
|
--nest; /* point to the next above element */
|
|
if (nest < 0) /* sanity check - users make this tbl */
|
|
{
|
|
return (NULL);
|
|
}
|
|
}
|
|
else /* not a start nest element, check to */
|
|
{ /* see if we are nesting further */
|
|
if (aa2->sel_type == AA_END_NEST)
|
|
nest++;
|
|
}
|
|
|
|
/* OK, we did not find the start element for the end nest, look */
|
|
/* some more */
|
|
if (aa2 == last_aa) /* sanity check - users make this tbl */
|
|
{
|
|
MLOG_NERR0 ("AA to ASN.1 : Bad AA");
|
|
return (NULL);
|
|
}
|
|
--aa2;
|
|
}
|
|
return (aa2);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* ms_log_alt_access */
|
|
/************************************************************************/
|
|
|
|
ST_VOID ms_log_alt_access (ALT_ACCESS *alt_acc)
|
|
{
|
|
#ifdef DEBUG_SISCO
|
|
ALT_ACC_EL *aa;
|
|
ST_INT num_aa;
|
|
ST_INT i;
|
|
ST_INT indent;
|
|
/* Use these strings to keep logging aligned and indented as desired */
|
|
#define MAX_INDENT 5
|
|
SD_CONST ST_CHAR *sp[MAX_INDENT] =
|
|
{
|
|
" ",
|
|
" ",
|
|
" ",
|
|
" ",
|
|
" ",
|
|
};
|
|
SD_CONST ST_CHAR *sp2[MAX_INDENT] =
|
|
{
|
|
" ",
|
|
" ",
|
|
" ",
|
|
" ",
|
|
"",
|
|
};
|
|
|
|
S_LOCK_COMMON_RESOURCES ();
|
|
aa = alt_acc->aa;
|
|
num_aa = alt_acc->num_aa;
|
|
indent = 0;
|
|
MLOG_ALWAYS1 ("Alternate Access : %d elements", num_aa);
|
|
|
|
for (i = 0; i < num_aa; ++i, ++aa)
|
|
{
|
|
if (aa->comp_name_pres)
|
|
{
|
|
MLOG_CALWAYS3 ("%sNamed %s: %s",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->comp_name);
|
|
}
|
|
|
|
switch (aa->sel_type)
|
|
{
|
|
case AA_COMP :
|
|
MLOG_CALWAYS3 ("%sComp %s: %s",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.component);
|
|
break;
|
|
case AA_INDEX :
|
|
MLOG_CALWAYS3 ("%sIndex %s: %ld",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.index);
|
|
if (--indent < 0)
|
|
indent++;
|
|
break;
|
|
case AA_INDEX_RANGE :
|
|
MLOG_CALWAYS4 ("%sIndex Range%s: Low = %ld, Num = %ld",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.ir.low_index,
|
|
aa->u.ir.num_elmnts);
|
|
if (--indent < 0)
|
|
indent++;
|
|
break;
|
|
case AA_ALL :
|
|
MLOG_CALWAYS2 ("%sAll %s:",
|
|
sp[indent],
|
|
sp2[indent]);
|
|
if (--indent < 0)
|
|
indent++;
|
|
break;
|
|
case AA_ALL_NEST :
|
|
MLOG_CALWAYS2 ("%sAll Nest %s:",
|
|
sp[indent],
|
|
sp2[indent]);
|
|
if (++indent >= MAX_INDENT)
|
|
indent--;
|
|
break;
|
|
case AA_COMP_NEST :
|
|
MLOG_CALWAYS3 ("%sComp Nest %s: %s",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.component);
|
|
if (++indent >= MAX_INDENT)
|
|
indent--;
|
|
break;
|
|
case AA_INDEX_NEST :
|
|
MLOG_CALWAYS3 ("%sIndex Nest %s: %ld",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.index);
|
|
if (++indent >= MAX_INDENT)
|
|
indent--;
|
|
break;
|
|
case AA_INDEX_RANGE_NEST :
|
|
MLOG_CALWAYS4 ("%sRange Nest %s: Low = %ld, Num = %ld",
|
|
sp[indent],
|
|
sp2[indent],
|
|
aa->u.ir.low_index,
|
|
aa->u.ir.num_elmnts);
|
|
if (++indent >= MAX_INDENT)
|
|
indent--;
|
|
break;
|
|
case AA_END_NEST :
|
|
MLOG_CALWAYS2 ("%sEnd Nest %s:",
|
|
sp[indent],
|
|
sp2[indent]);
|
|
if (--indent < 0)
|
|
indent++;
|
|
break;
|
|
|
|
default : /* should not be any other tag */
|
|
MLOG_CALWAYS1 (" **** UNKNOWN ELEMENT %02d ",i);
|
|
break;
|
|
}
|
|
}
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
|
#endif
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* ms_aa_to_asn1_2 */
|
|
/************************************************************************/
|
|
ST_RET ms_aa_to_asn1_2 (ALT_ACCESS *alt_acc, /* info to be encoded */
|
|
ST_UCHAR *buf_ptr, /* buffer in which to encode */
|
|
ST_INT buf_len, /* buffer length */
|
|
ST_UCHAR **asn1_ptr_out, /* ptr to ptr to encoded data */
|
|
ST_INT *asn1_len_out) /* ptr to encoded length */
|
|
{
|
|
ASN1_ENC_CTXT aCtx;
|
|
ST_RET retcode;
|
|
|
|
asn1r_strt_asn1_bld (&aCtx, buf_ptr, buf_len); /* start build*/
|
|
retcode = ms_aa_to_asn1 (&aCtx, alt_acc);
|
|
if (retcode == SD_SUCCESS)
|
|
{
|
|
*asn1_ptr_out = ASN1_ENC_PTR(&aCtx);
|
|
*asn1_len_out = ASN1_ENC_LEN(&aCtx);
|
|
}
|
|
return (retcode);
|
|
}
|