401 lines
14 KiB
C
401 lines
14 KiB
C
/************************************************************************/
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
|
/************************************************************************/
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
|
/* 1994 - 2002, All Rights Reserved */
|
|
/* */
|
|
/* MODULE NAME : mvl_var.c */
|
|
/* PRODUCT(S) : MMSEASE-LITE */
|
|
/* */
|
|
/* MODULE DESCRIPTION : */
|
|
/* */
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
|
/* NONE */
|
|
/* */
|
|
/* MODIFICATION LOG : */
|
|
/* Date Who Rev Comments */
|
|
/* -------- --- ------ ------------------------------------------- */
|
|
/* 10/30/06 JRB 31 Use new mvl_vmd_* object handling functions. */
|
|
/* _mvl_objname_to_va: add args. */
|
|
/* u_mvl_get_va_aa: add args. */
|
|
/* Elim use of global var "_mvl_curr_net_info". */
|
|
/* 01/30/06 GLB 30 Integrated porting changes for VMS */
|
|
/* 02/27/04 MDE 29 Log message correct */
|
|
/* 03/13/03 JRB 28 Add mvl_scope_set function. */
|
|
/* 12/12/02 JRB 27 Add net_info arg to mvl_get_va_asn1... and */
|
|
/* elim it's use of global _mvl_curr_net... */
|
|
/* 02/25/02 MDE 26 Now get max PDU size from mvl_cfg_info */
|
|
/* 01/02/02 JRB 25 Converted to use ASN1R (re-entrant ASN1) */
|
|
/* 10/25/00 JRB 24 Del u_mvl funct ptrs. Call functs directly. */
|
|
/* Control with #ifdefs. */
|
|
/* 08/17/00 JRB 23 Don't clear va_to_free. Need value later. */
|
|
/* 03/08/00 JRB 22 Del #ifdef MVL_REQ_BUF_ENABLED: not used. */
|
|
/* 01/21/00 MDE 21 Now use MEM_SMEM for dynamic memory */
|
|
/* 01/21/00 MDE 20 Add '_mvl_get_req_buf' for MVL_REQ_BUF_EN.. */
|
|
/* 11/19/99 NAV 19 Add #ifdef MVL_REQ_BUF_ENABLED */
|
|
/* 10/22/99 NAV 18 Add a few utilities to copy structs */
|
|
/* 09/13/99 MDE 17 Added SD_CONST modifiers */
|
|
/* 09/07/99 MDE 16 Changed MVL_VA_SCOPE to MVL_SCOPE */
|
|
/* 01/20/99 JRB 15 Del mvl_find_*. Use new "bsearch" versions. */
|
|
/* Del _mvl_skip_uca_prefix (use va->flags). */
|
|
/* Del _mvl_destroy_nvl_ent.. (see mvl_nvl_de..)*/
|
|
/* 12/11/98 MDE 14 Removed scope references from VA */
|
|
/* 12/08/98 MDE 13 Added client alternate access support */
|
|
/* 11/16/98 MDE 12 Added '_mvl_destroy_nvl_entries' */
|
|
/* 11/16/98 MDE 11 Renamed internal functions (prefix '_') */
|
|
/* 11/10/98 MDE 10 Added 'mvl_get_va_asn1_data' (was in s_read) */
|
|
/* 09/21/98 MDE 09 Minor lint cleanup */
|
|
/* 07/21/98 MDE 08 Moved 'mvl_insert_nvlist' to mvl_dnvl.c */
|
|
/* 07/13/98 MDE 07 Fixed mvl_insert_nvlist bug when adding 1st */
|
|
/* 06/30/98 MDE 06 Corrected insert order for "_UCA_" names */
|
|
/* 06/15/98 MDE 05 Changes to allow compile under C++ */
|
|
/* 06/05/98 MDE 04 Added 'mvl_insert_nvlist' */
|
|
/* 01/06/98 RWM 03 Added Binary Search Capability */
|
|
/* 12/12/97 MDE 02 Moved mvl_vmd to rt_types.c */
|
|
/* 09/10/97 MDE 01 MMS-LITE V4.0 Release */
|
|
/************************************************************************/
|
|
|
|
#include "glbtypes.h"
|
|
#include "sysincs.h"
|
|
|
|
#include "mmsdefs.h"
|
|
#include "mms_pvar.h"
|
|
#include "mms_vvar.h"
|
|
#include "mvl_acse.h"
|
|
#include "mvl_log.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
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _mvl_objname_to_va */
|
|
/************************************************************************/
|
|
|
|
MVL_VAR_ASSOC *_mvl_objname_to_va (MVL_VMD_CTRL *vmd_ctrl,
|
|
MVL_NET_INFO *net_info,
|
|
ST_INT service,
|
|
OBJECT_NAME *obj,
|
|
MVL_SCOPE *va_scope_out,
|
|
ST_BOOLEAN alt_access_pres,
|
|
ALT_ACCESS *alt_acc,
|
|
ST_BOOLEAN *alt_access_done_out)
|
|
{
|
|
MVL_VAR_ASSOC *va;
|
|
|
|
/* By default, we don't modify the VA to handle alternate access */
|
|
if (alt_access_done_out != NULL)
|
|
*alt_access_done_out = SD_FALSE;
|
|
|
|
/* Let's find the variable association */
|
|
va = mvl_vmd_find_var (vmd_ctrl, obj, net_info);
|
|
if ((!va) || (va->flags & MVL_VAR_FLAG_UCA))
|
|
{
|
|
/* Could not find variable association, see if we can manufacture it */
|
|
#if defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS)
|
|
/* May be able to manufacture it */
|
|
va = u_mvl_get_va_aa (vmd_ctrl, service, obj, net_info,
|
|
alt_access_pres, alt_acc,
|
|
alt_access_done_out);
|
|
if (va != NULL) /* Manufactured it, set flag ... */
|
|
va->va_to_free = va;
|
|
#endif /* defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS) */
|
|
}
|
|
|
|
/* OK, assuming we have the VA, set it's scope appropriately */
|
|
if (va && va_scope_out)
|
|
{
|
|
va_scope_out->scope = obj->object_tag;
|
|
if (va_scope_out->scope == DOM_SPEC)
|
|
{
|
|
va_scope_out->dom = mvl_vmd_find_dom (vmd_ctrl, obj->domain_id);
|
|
if (va_scope_out->dom == NULL)
|
|
{
|
|
MVL_LOG_NERR1 ("Warning : Variable object references non-existant domain '%s'",
|
|
obj->domain_id);
|
|
}
|
|
}
|
|
}
|
|
return (va);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* mvl_scope_set */
|
|
/* Use the OBJECT_NAME info to set the scope for any MMS object. */
|
|
/* This function fills in the struct pointed to by mvl_scope_out. */
|
|
/************************************************************************/
|
|
ST_VOID mvl_scope_set (OBJECT_NAME *obj, MVL_SCOPE *mvl_scope_out)
|
|
{
|
|
mvl_scope_out->scope = obj->object_tag;
|
|
if (mvl_scope_out->scope == DOM_SPEC)
|
|
{
|
|
mvl_scope_out->dom = mvl_vmd_find_dom (&mvl_vmd, obj->domain_id);
|
|
if (mvl_scope_out->dom == NULL)
|
|
MVL_LOG_NERR1 ("Warning : MMS object references nonexistent domain '%s'",
|
|
obj->domain_id);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* mvl_get_va_asn1_data */
|
|
/************************************************************************/
|
|
|
|
ST_RET mvl_get_va_asn1_data (MVL_NET_INFO *net_info, MVL_VAR_ASSOC *va,
|
|
ST_BOOLEAN alt_access_pres,
|
|
ALT_ACCESS *alt_acc,
|
|
ST_UCHAR *asn1_dest_buffer,
|
|
ST_INT asn1_buffer_len,
|
|
ST_INT *asn1_len_out)
|
|
{
|
|
RUNTIME_TYPE *rt;
|
|
ST_INT num_rt;
|
|
ST_RET rc;
|
|
ST_UCHAR *asn1_start;
|
|
ST_INT asn1_len;
|
|
ST_INT aa_mode;
|
|
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
|
|
ASN1_ENC_CTXT *aCtx = &localEncCtx;
|
|
|
|
aa_mode = MVL_USE_UNPACKED_AA;
|
|
if (va->proc && va->proc->pre_read_aa)
|
|
{
|
|
rc = (*va->proc->pre_read_aa)(&va, alt_access_pres, alt_acc,
|
|
net_info, &aa_mode);
|
|
|
|
if (rc != SD_SUCCESS)
|
|
{
|
|
MVL_LOG_NERR1 ("Read: pre_read_aa returned %d", rc);
|
|
return (SD_FAILURE);
|
|
}
|
|
}
|
|
|
|
rc = mvl_get_runtime (va->type_id, &rt, &num_rt);
|
|
if (rc != SD_SUCCESS)
|
|
{
|
|
MVL_LOG_NERR1 ("Read: mvl_get_runtime failed, rc = %x", rc);
|
|
return (rc); /* bad type id */
|
|
}
|
|
|
|
/* If we got here, we have a valid runtime and have resolved local */
|
|
/* data pointer and size. Go ahead and build the ASN.1 data element. */
|
|
|
|
/* First we need to initialize the ASN.1 encode tools, then do the */
|
|
/* encode */
|
|
asn1r_strt_asn1_bld (aCtx, asn1_dest_buffer, asn1_buffer_len);
|
|
|
|
#if defined(MVL_AA_SUPP)
|
|
if (alt_access_pres == SD_FALSE || aa_mode == MVL_USE_NO_AA)
|
|
{
|
|
rc = ms_local_to_asn1 (aCtx, rt, num_rt, (ST_CHAR *) va->data);
|
|
}
|
|
else
|
|
{
|
|
if (aa_mode == MVL_USE_PACKED_AA)
|
|
m_alt_acc_packed = SD_TRUE;
|
|
else
|
|
m_alt_acc_packed = SD_FALSE;
|
|
|
|
rc = ms_local_to_asn1_aa (aCtx, rt, num_rt, alt_acc, (ST_CHAR *) va->data);
|
|
}
|
|
#else
|
|
rc = ms_local_to_asn1 (aCtx, rt, num_rt, (ST_CHAR *) va->data);
|
|
#endif
|
|
|
|
/* When the ASN.1 encode is complete, 'asn1_field_ptr' points 1 byte ahead */
|
|
/* of the start of the message. The ASN.1 message is build from back to */
|
|
/* front, so that is now we calculate the length of the PDU */
|
|
if (rc == SD_SUCCESS)
|
|
{
|
|
asn1_start = aCtx->asn1r_field_ptr+1;
|
|
asn1_len = (asn1_dest_buffer + asn1_buffer_len) - asn1_start;
|
|
memmove (asn1_dest_buffer,asn1_start,asn1_len);
|
|
*asn1_len_out = asn1_len;
|
|
|
|
if (va->proc && va->proc->post_read_aa)
|
|
{
|
|
(*va->proc->post_read_aa)(va, alt_access_pres, alt_acc,
|
|
net_info);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MVL_LOG_NERR1 ("Local to ASN1 data conversion error: 0x%04x", rc);
|
|
}
|
|
return (rc);
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
#if defined(MVL_AA_SUPP)
|
|
/************************************************************************/
|
|
|
|
/************************************************************************/
|
|
/************************************************************************/
|
|
/* _mvl_get_asn1_aa */
|
|
/************************************************************************/
|
|
|
|
ST_RET _mvl_get_asn1_aa (ALT_ACCESS *alt_acc, VARIABLE_LIST *vl)
|
|
{
|
|
ST_UCHAR *aa_buf;
|
|
ST_INT aa_buf_size;
|
|
ST_UCHAR *asn1_start;
|
|
ST_INT asn1_len;
|
|
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
|
|
ASN1_ENC_CTXT *aCtx = &localEncCtx;
|
|
|
|
aa_buf = _m_get_aa_asn1_buf (&aa_buf_size);
|
|
asn1r_strt_asn1_bld (aCtx, aa_buf, aa_buf_size);
|
|
if (ms_aa_to_asn1 (aCtx, alt_acc))
|
|
{
|
|
_m_free_aa_asn1_buf ();
|
|
return (SD_FAILURE);
|
|
}
|
|
else
|
|
{
|
|
asn1_start = aCtx->asn1r_field_ptr+1;
|
|
asn1_len = (aa_buf + aa_buf_size) - asn1_start;
|
|
vl->alt_access.len = asn1_len;
|
|
vl->alt_access.data = asn1_start;
|
|
vl->alt_access_pres = SD_TRUE;
|
|
_m_set_aa_asn1_buf_end (asn1_start -1);
|
|
}
|
|
return (SD_SUCCESS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
static ST_UCHAR *aa_buffer_head;
|
|
static ST_UCHAR *aa_buffer_end;
|
|
|
|
/************************************************************************/
|
|
/* _m_get_aa_asn1_buf */
|
|
/************************************************************************/
|
|
|
|
ST_UCHAR *_m_get_aa_asn1_buf (ST_INT *size_out)
|
|
{
|
|
ST_UCHAR *ret;
|
|
|
|
if (!aa_buffer_head)
|
|
{
|
|
aa_buffer_head = (ST_UCHAR *) M_MALLOC (MSMEM_AA_ENCODE, mvl_cfg_info->max_msg_size);
|
|
aa_buffer_end = aa_buffer_head + mvl_cfg_info->max_msg_size -1;
|
|
}
|
|
|
|
*size_out = aa_buffer_end - aa_buffer_head + 1;
|
|
ret = aa_buffer_head;
|
|
return (ret);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _m_set_aa_asn1_buf_end */
|
|
/************************************************************************/
|
|
|
|
ST_VOID _m_set_aa_asn1_buf_end (ST_UCHAR *new_end)
|
|
{
|
|
aa_buffer_end = new_end;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* _m_free_aa_asn1_buf */
|
|
/************************************************************************/
|
|
|
|
ST_VOID _m_free_aa_asn1_buf (ST_VOID)
|
|
{
|
|
if (aa_buffer_head)
|
|
{
|
|
M_FREE (MSMEM_AA_ENCODE, aa_buffer_head);
|
|
aa_buffer_head = NULL;
|
|
}
|
|
}
|
|
|
|
#endif /* #if defined(MVL_AA_SUPP) */
|
|
|
|
|
|
/************************************************************************/
|
|
/* mvl_get_descr_local_addr */
|
|
/* DESCRIBED VARIABLE ASSOCIATION */
|
|
/* Addresses are in the form : */
|
|
/* "baseaddr:xxx" */
|
|
/* where xxx is the element offset from the base address. */
|
|
/************************************************************************/
|
|
|
|
/************************************************************************/
|
|
#if defined (MVL_DESCR_SUPP)
|
|
/************************************************************************/
|
|
|
|
ST_RET mvl_get_descr_local_addr (VAR_ACC_ADDR *addr,
|
|
RUNTIME_TYPE *rt,
|
|
ST_INT num_rt,
|
|
ST_CHAR **data_out,
|
|
ST_INT *data_size_out)
|
|
{
|
|
ST_INT i;
|
|
MVL_DESCR_ADDR_ASSOC *d;
|
|
ST_INT base_name_len;
|
|
ST_INT offset;
|
|
ST_INT num_offset;
|
|
ST_INT num_elmnts;
|
|
|
|
/* We only support symbolic addresses */
|
|
if (addr->addr_tag != SYM_ADDR)
|
|
{
|
|
MVL_LOG_NERR0 ("Get Described Local Address : Only Symbolic Addresses are supported");
|
|
return (MVL_ERR_NOT_SYM_ADDR);
|
|
}
|
|
|
|
/* Find the matching described variable association */
|
|
d = mvl_vmd.descr_addr_assoc_tbl;
|
|
for (i = 0; i < mvl_vmd.num_descr_addr; ++i, ++d)
|
|
{
|
|
base_name_len = strlen (d->base_name);
|
|
if (!strncmp (d->base_name, addr->addr.sym_addr, base_name_len))
|
|
{
|
|
/* Check for offset from base element */
|
|
if (base_name_len == strlen (addr->addr.sym_addr))
|
|
offset = 0;
|
|
else
|
|
{
|
|
num_offset = atoi (&addr->addr.sym_addr[base_name_len + 1]);
|
|
if (num_offset) /* :1 is first element */
|
|
num_offset--;
|
|
offset = d->data_size * num_offset;
|
|
}
|
|
|
|
if (rt->el_tag != RT_ARR_START) /* if not array */
|
|
{
|
|
*data_out = (ST_CHAR *) d->data + offset;
|
|
*data_size_out = d->data_size;
|
|
return (SD_SUCCESS);
|
|
}
|
|
else /* this is an array */
|
|
{
|
|
num_elmnts = rt->u.arr.num_elmnts; /* get number of elements */
|
|
if (num_elmnts + num_offset > d->max_elmnts)
|
|
{
|
|
MVL_LOG_NERR0 ("Get Described Local Address : Invalid array element count");
|
|
return (MVL_ERR_ARRAY_ELEMENT_CNT);
|
|
}
|
|
|
|
*data_out = (ST_CHAR *) d->data + offset;
|
|
*data_size_out = d->data_size * num_elmnts;
|
|
return (SD_SUCCESS);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
MVL_LOG_NERR0 ("Get Described Local Address : Could not get Local Address");
|
|
return (MVL_ERR_LOCAL_ADDRESS);
|
|
}
|
|
/************************************************************************/
|
|
#endif /* #if defined (MVL_DESCR_SUPP) */
|
|
/************************************************************************/
|
|
|