601 lines
19 KiB
C
601 lines
19 KiB
C
|
|
/************************************************************************/
|
||
|
|
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||
|
|
/* 1986 - 2001, All Rights Reserved */
|
||
|
|
/* */
|
||
|
|
/* PROPRIETARY AND CONFIDENTIAL */
|
||
|
|
/* */
|
||
|
|
/* MODULE NAME : ms_size.c */
|
||
|
|
/* PRODUCT(S) : MMSEASE */
|
||
|
|
/* */
|
||
|
|
/* MODULE DESCRIPTION : */
|
||
|
|
/* This module contains support functions for estimating maximum */
|
||
|
|
/* size of Variable Access service PDUs (Read, Write, and InfoRpt).*/
|
||
|
|
/* */
|
||
|
|
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||
|
|
/* */
|
||
|
|
/* MODIFICATION LOG : */
|
||
|
|
/* Date Who Rev Comments */
|
||
|
|
/* -------- --- ------ ------------------------------------------- */
|
||
|
|
/* 04/14/03 JRB 09 Eliminate compiler warnings. */
|
||
|
|
/* 04/02/03 JRB 08 Add UTF8string support (see RT_UTF8_STRING). */
|
||
|
|
/* 11/14/01 EJV 07 Added support for new MMS type UtcTime: */
|
||
|
|
/* ms_data_size: added case for RT_UTC_TIME */
|
||
|
|
/* 10/18/00 RKR 06 Changed RT_UNSIGNED in ms_data_size */
|
||
|
|
/* 09/15/00 MDE 05 Fixed MMS-EASE compile error */
|
||
|
|
/* 09/07/00 MDE 04 Added MMS-LITE support */
|
||
|
|
/* 02/10/98 MDE 03 Now don't use runtime type loops element */
|
||
|
|
/* 08/15/97 MDE 02 Minor cleanup */
|
||
|
|
/* 06/09/97 MDE 01 Changed Runtime Type, and it's use */
|
||
|
|
/* 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"
|
||
|
|
#if defined(MMS_LITE)
|
||
|
|
#include "mvl_defs.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* For debug version, use a static pointer to avoid duplication of */
|
||
|
|
/* __FILE__ strings. */
|
||
|
|
|
||
|
|
#if defined(DEBUG_SISCO) && defined(S_MT_SUPPORT)
|
||
|
|
static ST_CHAR *thisFileName = __FILE__;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static ST_LONG address_size (VAR_ACC_ADDR *address, ST_BOOLEAN req);
|
||
|
|
static ST_LONG obj_name_size (OBJECT_NAME *name, ST_BOOLEAN req);
|
||
|
|
static ST_LONG ms_data_size (RUNTIME_TYPE *rt_ptr, ST_INT rt_num,
|
||
|
|
ST_INT alt_len, ST_UCHAR *alt_ptr,
|
||
|
|
ST_BOOLEAN req);
|
||
|
|
|
||
|
|
static ST_INT arr_loop_level;
|
||
|
|
static ST_INT *arr_loops;
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* To allow the user to specify either MMS-EASE or UNKNOWN PDU style, */
|
||
|
|
/* the following definitions & data structures are used. */
|
||
|
|
/* See ms_size.doc for information on how these were derived. */
|
||
|
|
|
||
|
|
ST_INT ms_req_bld_id = UNKNOWN_BUILDER;
|
||
|
|
ST_INT ms_resp_bld_id = UNKNOWN_BUILDER;
|
||
|
|
|
||
|
|
/* Because the MMS-EASE ASN.1 tools are a bit conservitive, need to */
|
||
|
|
/* provide for a little extra overhead. */
|
||
|
|
ST_INT ms_size_oh_pad = ASN1_MAX_ELEMENT_OVERHEAD;
|
||
|
|
|
||
|
|
ST_LONG large_el_oh[] =
|
||
|
|
{
|
||
|
|
6L, /* MMS-EASE is PDU Builder */
|
||
|
|
8L /* UNKNOWN PDU Builder */
|
||
|
|
};
|
||
|
|
ST_LONG med_el_oh[] =
|
||
|
|
{
|
||
|
|
4L, /* MMS-EASE is PDU Builder */
|
||
|
|
8L /* UNKNOWN PDU Builder */
|
||
|
|
};
|
||
|
|
ST_LONG small_el_oh[] =
|
||
|
|
{
|
||
|
|
2L, /* MMS-EASE is PDU Builder */
|
||
|
|
8L /* UNKNOWN PDU Builder */
|
||
|
|
};
|
||
|
|
|
||
|
|
#define LARGE_EL_REQ_OH large_el_oh[ms_req_bld_id]
|
||
|
|
#define MED_EL_REQ_OH med_el_oh[ms_req_bld_id]
|
||
|
|
#define SMALL_EL_REQ_OH small_el_oh[ms_req_bld_id]
|
||
|
|
|
||
|
|
#define LARGE_EL_RESP_OH large_el_oh[ms_resp_bld_id]
|
||
|
|
#define MED_EL_RESP_OH med_el_oh[ms_resp_bld_id]
|
||
|
|
#define SMALL_EL_RESP_OH small_el_oh[ms_resp_bld_id]
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* Overhead for various types of MMS ASN.1 data elements */
|
||
|
|
|
||
|
|
|
||
|
|
#define CONF_REQ_PDU_OH (ms_size_oh_pad+MED_EL_REQ_OH+SMALL_EL_REQ_OH+4)
|
||
|
|
#define CONF_RESP_PDU_OH (ms_size_oh_pad+MED_EL_RESP_OH+SMALL_EL_RESP_OH+4)
|
||
|
|
#define UNCONF_PDU_OH (ms_size_oh_pad+MED_EL_REQ_OH)
|
||
|
|
|
||
|
|
/* Overhead for empty PDU's of various types */
|
||
|
|
#define READ_REQ_OH (CONF_REQ_PDU_OH + (MED_EL_REQ_OH * 2))
|
||
|
|
#define READ_RESP_OH (CONF_RESP_PDU_OH + (MED_EL_RESP_OH * 2))
|
||
|
|
#define WRITE_REQ_OH (CONF_REQ_PDU_OH + (MED_EL_REQ_OH * 2))
|
||
|
|
#define WRITE_RESP_OH (CONF_RESP_PDU_OH + MED_EL_RESP_OH)
|
||
|
|
#define INFO_REQ_OH (UNCONF_PDU_OH + (MED_EL_REQ_OH * 2))
|
||
|
|
|
||
|
|
/* Overhead for various components of interest */
|
||
|
|
#define SPEC_IN_RSLT_SIZE (MED_EL_REQ_OH + 1)
|
||
|
|
|
||
|
|
/* Object name overhead */
|
||
|
|
#define VMD_OBJ_NAME_REQ_OH SMALL_EL_REQ_OH
|
||
|
|
#define DOM_OBJ_NAME_REQ_OH (MED_EL_REQ_OH + (SMALL_EL_REQ_OH * 2))
|
||
|
|
#define AA_OBJ_NAME_REQ_OH SMALL_EL_REQ_OH
|
||
|
|
|
||
|
|
#define VMD_OBJ_NAME_RESP_OH SMALL_EL_RESP_OH
|
||
|
|
#define DOM_OBJ_NAME_RESP_OH (MED_EL_RESP_OH + (SMALL_EL_RESP_OH * 2))
|
||
|
|
#define AA_OBJ_NAME_RESP_OH SMALL_EL_RESP_OH
|
||
|
|
|
||
|
|
|
||
|
|
#define GENTIME_LEN 18L
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* ms_init_va_size */
|
||
|
|
/* This function is called from the user as a first step in estimating */
|
||
|
|
/* the maximum size of both the request and response PDUs of any of the */
|
||
|
|
/* Variable Access services (Read, Write, and InformationReport). This */
|
||
|
|
/* function initializes the values pointed to by req_size and resp_size */
|
||
|
|
/* to the overhead in the PDU (before determining the size of the data */
|
||
|
|
/* and specification of each variable to be included). The companion */
|
||
|
|
/* function ms_va_size is then called for each variable to add on the */
|
||
|
|
/* estimated size attributable to that variable. This function returns */
|
||
|
|
/* 0 for success, else an error code. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
ST_RET ms_init_va_size (ST_INT op, ST_UCHAR spec_in_rslt, ST_INT16 var_acc_tag,
|
||
|
|
OBJECT_NAME *vl_name, ST_LONG *req_size, ST_LONG *resp_size)
|
||
|
|
{
|
||
|
|
ST_RET ret;
|
||
|
|
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
ret = SD_SUCCESS;
|
||
|
|
switch (op)
|
||
|
|
{
|
||
|
|
case MMSOP_READ:
|
||
|
|
/* initialize sizes to include all overhead for basic request */
|
||
|
|
*req_size = READ_REQ_OH;
|
||
|
|
*resp_size = READ_RESP_OH;
|
||
|
|
|
||
|
|
/* To send request for spec in result takes extra bytes, do does */
|
||
|
|
/* sending the VA spec in the response. */
|
||
|
|
if (spec_in_rslt)
|
||
|
|
{
|
||
|
|
*req_size += SPEC_IN_RSLT_SIZE;
|
||
|
|
*resp_size += MED_EL_RESP_OH;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MMSOP_WRITE:
|
||
|
|
/* initialize sizes to include all overhead for basic request */
|
||
|
|
*req_size = WRITE_REQ_OH;
|
||
|
|
*resp_size = WRITE_RESP_OH;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case MMSOP_INFO_RPT:
|
||
|
|
/* initialize sizes to include all overhead for basic request */
|
||
|
|
*req_size = INFO_REQ_OH;
|
||
|
|
*resp_size = 0;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default :
|
||
|
|
ret = MVE_WRONG_OP;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* If the variable specification is a named list, add in the name, else */
|
||
|
|
/* add in the sequence of sequence constructor overhead */
|
||
|
|
/* Note that this is done here, NOT in later calls to ms_va_size */
|
||
|
|
|
||
|
|
if (var_acc_tag == VAR_ACC_NAMEDLIST) /* list of variables case */
|
||
|
|
*req_size += MED_EL_REQ_OH + obj_name_size (vl_name,SD_TRUE);
|
||
|
|
else
|
||
|
|
*req_size += MED_EL_REQ_OH; /* seq of seq */
|
||
|
|
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (ret);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* ms_va_size */
|
||
|
|
/* This function is called from the user repetitively for each variable */
|
||
|
|
/* expected to be included in a Read, Write, or InfoRpt PDU. Note that */
|
||
|
|
/* the function ms_init_va_size should be called first to initialize */
|
||
|
|
/* the two outputs req_size and resp_size. The values pointed to by */
|
||
|
|
/* req_size and resp_size are incremented by the appropriate amount, */
|
||
|
|
/* so that after this function has been called for all variables, they */
|
||
|
|
/* represent valid estimates of the size of the request and response */
|
||
|
|
/* PDUs for the given service (indicated by op). In some cases, the */
|
||
|
|
/* type of the variable may be indicated both by the vl_ptr argument */
|
||
|
|
/* and by the type argument; in this case, both must still be specified */
|
||
|
|
/* and it is up to the user to verify that they are equal. This */
|
||
|
|
/* function returns 0 for success, else an error code. */
|
||
|
|
/* */
|
||
|
|
/* NOTE: In the case of accessing a variable list object (as opposed */
|
||
|
|
/* to a list of variable objects), a variable_list structure must */
|
||
|
|
/* be built and filled in appropriately, with var_spec_tag set to */
|
||
|
|
/* 5. (Otherwise, the value pointed to by req_size and, in */
|
||
|
|
/* certain cases, the value pointed to by resp_size will be */
|
||
|
|
/* much larger than necessary. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
#if !defined(MMS_LITE)
|
||
|
|
ST_RET ms_va_size (ST_INT op, ST_UCHAR spec_in_rslt, ST_INT16 var_acc_tag,
|
||
|
|
VARIABLE_LIST *vl_ptr, NAMED_TYPE *type,
|
||
|
|
ST_LONG *req_size, ST_LONG *resp_size)
|
||
|
|
#else
|
||
|
|
ST_RET ms_va_size (ST_INT op, ST_UCHAR spec_in_rslt, ST_INT16 var_acc_tag,
|
||
|
|
VARIABLE_LIST *vl_ptr, ST_INT type_id,
|
||
|
|
ST_LONG *req_size, ST_LONG *resp_size)
|
||
|
|
#endif
|
||
|
|
{
|
||
|
|
ST_LONG size;
|
||
|
|
ST_INT alt_acc_len;
|
||
|
|
RUNTIME_TYPE *rt;
|
||
|
|
ST_INT rt_num;
|
||
|
|
#if defined(MMS_LITE)
|
||
|
|
ST_INT rc;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(MMS_LITE)
|
||
|
|
rt = type->rt_head;
|
||
|
|
rt_num = type->rt_num;
|
||
|
|
#else
|
||
|
|
rc = mvl_get_runtime (type_id, &rt, &rt_num);
|
||
|
|
if (rc != SD_SUCCESS)
|
||
|
|
return (rc);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
S_LOCK_COMMON_RESOURCES ();
|
||
|
|
|
||
|
|
/* non functional at this time */
|
||
|
|
if (vl_ptr->alt_access_pres)
|
||
|
|
alt_acc_len = vl_ptr->alt_access.len;
|
||
|
|
else
|
||
|
|
alt_acc_len = 0;
|
||
|
|
|
||
|
|
/* get the size of the data element based on the MMS type and add the */
|
||
|
|
/* data element size to the target PDU */
|
||
|
|
|
||
|
|
if (op == MMSOP_READ) /* read response carries data */
|
||
|
|
{
|
||
|
|
size = ms_data_size (rt, rt_num, alt_acc_len,
|
||
|
|
vl_ptr->alt_access.data,SD_FALSE);
|
||
|
|
*resp_size += size;
|
||
|
|
}
|
||
|
|
else /* WRITE or INFO */
|
||
|
|
{
|
||
|
|
size = ms_data_size (rt, rt_num, alt_acc_len,
|
||
|
|
vl_ptr->alt_access.data,SD_TRUE);
|
||
|
|
*req_size += size;
|
||
|
|
|
||
|
|
if (op == MMSOP_WRITE) /* Write response carries result */
|
||
|
|
*resp_size += SMALL_EL_RESP_OH + 1; /* assume failure (+1) */
|
||
|
|
}
|
||
|
|
if (size <= 0) /* verify the data size was OK */
|
||
|
|
{
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (MVE_TYPENAME);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Now calculate the size of the variable access spec for this var. */
|
||
|
|
/* Only req'd if var_acc_tag is list of vars (list name added already) */
|
||
|
|
if (var_acc_tag == VAR_ACC_VARLIST)
|
||
|
|
{
|
||
|
|
size = MED_EL_REQ_OH;
|
||
|
|
switch (vl_ptr->var_spec.var_spec_tag)
|
||
|
|
{
|
||
|
|
case VA_SPEC_NAMED :
|
||
|
|
size += obj_name_size (&vl_ptr->var_spec.vs.name,SD_TRUE);
|
||
|
|
break;
|
||
|
|
|
||
|
|
#if !defined(MMS_LITE)
|
||
|
|
case VA_SPEC_DESCRIBED : /* described gets address & type */
|
||
|
|
size += type->asn1len +
|
||
|
|
address_size (&vl_ptr->var_spec.vs.address,SD_TRUE);
|
||
|
|
break;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
case VA_SPEC_ADDRESSED :
|
||
|
|
size += address_size (&vl_ptr->var_spec.vs.address,SD_TRUE);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case VA_SPEC_SCATTERED : /* not currently supported */
|
||
|
|
case VA_SPEC_INVALIDATED :
|
||
|
|
default:
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (MVE_VM_SERVICE_NOTSUPP);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* not really supported at this time, leave in anyway */
|
||
|
|
if (vl_ptr->alt_access_pres)
|
||
|
|
size += (ST_LONG) alt_acc_len;
|
||
|
|
|
||
|
|
/* Now we have the variable specification size, add to the request */
|
||
|
|
*req_size += size;
|
||
|
|
|
||
|
|
/* Now, if spec in result requested, calculate VA spec size for resp */
|
||
|
|
if (op == MMSOP_READ && spec_in_rslt)
|
||
|
|
{
|
||
|
|
size = MED_EL_RESP_OH;
|
||
|
|
switch (vl_ptr->var_spec.var_spec_tag)
|
||
|
|
{
|
||
|
|
case VA_SPEC_NAMED :
|
||
|
|
size += obj_name_size (&vl_ptr->var_spec.vs.name,SD_FALSE);
|
||
|
|
break;
|
||
|
|
|
||
|
|
#if !defined(MMS_LITE)
|
||
|
|
case VA_SPEC_DESCRIBED : /* described gets address & type */
|
||
|
|
size += type->asn1len +
|
||
|
|
address_size (&vl_ptr->var_spec.vs.address,SD_FALSE);
|
||
|
|
|
||
|
|
break;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
case VA_SPEC_ADDRESSED :
|
||
|
|
size += address_size (&vl_ptr->var_spec.vs.address,SD_FALSE);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case 5: /* variable list object case */
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (SD_SUCCESS); /* No variable spec. req'd */
|
||
|
|
break;
|
||
|
|
|
||
|
|
case VA_SPEC_SCATTERED : /* not currently supported */
|
||
|
|
case VA_SPEC_INVALIDATED :
|
||
|
|
default:
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (MVE_VM_SERVICE_NOTSUPP);
|
||
|
|
}
|
||
|
|
*resp_size += size;
|
||
|
|
}
|
||
|
|
} /* if VAR_ACC_VARLIST */
|
||
|
|
|
||
|
|
/* Now, if WRITE, need to add write result */
|
||
|
|
|
||
|
|
|
||
|
|
S_UNLOCK_COMMON_RESOURCES ();
|
||
|
|
return (SD_SUCCESS);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* obj_name_size */
|
||
|
|
/* This function is called from ms_init_va_size and ms_va_size to */
|
||
|
|
/* calculate (exactly) the size that a particular object name will take */
|
||
|
|
/* up in a request or response PDU for the Read, Write, and InfoReport */
|
||
|
|
/* services. Returns the size of the object name, or 0 if there is a */
|
||
|
|
/* problem. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_LONG obj_name_size (OBJECT_NAME *name, ST_BOOLEAN req)
|
||
|
|
{
|
||
|
|
ST_LONG oh;
|
||
|
|
|
||
|
|
switch (name->object_tag)
|
||
|
|
{
|
||
|
|
case VMD_SPEC :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
oh = VMD_OBJ_NAME_REQ_OH;
|
||
|
|
else
|
||
|
|
oh = VMD_OBJ_NAME_RESP_OH;
|
||
|
|
|
||
|
|
return (oh + (ST_LONG) strlen (name->obj_name.vmd_spec));
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOM_SPEC :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
oh = DOM_OBJ_NAME_REQ_OH;
|
||
|
|
else
|
||
|
|
oh = DOM_OBJ_NAME_RESP_OH;
|
||
|
|
|
||
|
|
return (oh + (ST_LONG) (strlen (name->obj_name.item_id) +
|
||
|
|
strlen (name->domain_id)));
|
||
|
|
break;
|
||
|
|
|
||
|
|
case AA_SPEC :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
oh = AA_OBJ_NAME_REQ_OH;
|
||
|
|
else
|
||
|
|
oh = AA_OBJ_NAME_RESP_OH;
|
||
|
|
|
||
|
|
return (oh + (ST_LONG) strlen (name->obj_name.aa_spec));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
mms_op_err = MVE_OBJECT_SCOPE;
|
||
|
|
return (0L); /* indicates error condition */
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/* address_size */
|
||
|
|
/* This function is called from ms_va_size to calculate (exactly) the */
|
||
|
|
/* size that a particular address will take up in a request or response */
|
||
|
|
/* PDU for the Read, Write, and InfoReport services. Returns the size */
|
||
|
|
/* of the address, or 0 if there is a problem. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_LONG address_size (VAR_ACC_ADDR *address, ST_BOOLEAN req)
|
||
|
|
{
|
||
|
|
ST_LONG size;
|
||
|
|
ST_LONG numaddr;
|
||
|
|
|
||
|
|
switch (address->addr_tag)
|
||
|
|
{
|
||
|
|
case NUM_ADDR :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
size = SMALL_EL_REQ_OH;
|
||
|
|
else
|
||
|
|
size = SMALL_EL_RESP_OH;
|
||
|
|
numaddr = address->addr.num_addr;
|
||
|
|
if (numaddr < 128L)
|
||
|
|
size += 1;
|
||
|
|
else if (numaddr < 32768L)
|
||
|
|
size += 2;
|
||
|
|
else if (numaddr < 8388608L)
|
||
|
|
size += 3;
|
||
|
|
else
|
||
|
|
size += 4;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case SYM_ADDR :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
size = MED_EL_REQ_OH;
|
||
|
|
else
|
||
|
|
size = MED_EL_RESP_OH;
|
||
|
|
size += strlen (address->addr.sym_addr);
|
||
|
|
break;
|
||
|
|
|
||
|
|
case UNCON_ADDR :
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
size = MED_EL_REQ_OH;
|
||
|
|
else
|
||
|
|
size = MED_EL_RESP_OH;
|
||
|
|
size += address->addr.unc_addr.unc_len;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
mms_op_err = MVE_ADDR;
|
||
|
|
return (0);
|
||
|
|
}
|
||
|
|
return (size);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/************************************************************************/
|
||
|
|
/* ms_data_size */
|
||
|
|
/* This function is called from the user or the MMS-EASE virtual */
|
||
|
|
/* machine to estimate the size that the data corresponding to a */
|
||
|
|
/* particular type will take up in a request or response PDU for the */
|
||
|
|
/* Read, Write, and InfoReport services. Returns the size of the data, */
|
||
|
|
/* or 0 if there is a problem. (A rough error code can be found in */
|
||
|
|
/* mms_op_err; a more detailed one in asn1_pdu_dec_err.) */
|
||
|
|
/* */
|
||
|
|
/* Note: Alternate access may be used to modify a type, thereby */
|
||
|
|
/* affecting the size of the corresponding data. However, */
|
||
|
|
/* the alternate access inputs are disregarded at this time. */
|
||
|
|
/* This will be fixed in a later revision. */
|
||
|
|
/************************************************************************/
|
||
|
|
|
||
|
|
static ST_LONG ms_data_size (RUNTIME_TYPE *rt_ptr, ST_INT rt_num,
|
||
|
|
ST_INT alt_len, ST_UCHAR *alt_ptr,
|
||
|
|
ST_BOOLEAN req)
|
||
|
|
{
|
||
|
|
ST_LONG size;
|
||
|
|
RUNTIME_TYPE *rt_end;
|
||
|
|
ST_LONG med_oh;
|
||
|
|
ST_LONG small_oh;
|
||
|
|
ST_UINT ellen;
|
||
|
|
ST_LONG len;
|
||
|
|
ST_INT arr_loop_buf[ASN1_MAX_LEVEL];
|
||
|
|
ST_UINT el_size; /* num bytes to encode data */
|
||
|
|
|
||
|
|
arr_loop_level = 0;
|
||
|
|
arr_loops = arr_loop_buf;
|
||
|
|
|
||
|
|
if (req) /* if calculating for a request */
|
||
|
|
{
|
||
|
|
med_oh = MED_EL_REQ_OH;
|
||
|
|
small_oh = SMALL_EL_REQ_OH;
|
||
|
|
}
|
||
|
|
else /* calculating for response */
|
||
|
|
{
|
||
|
|
med_oh = MED_EL_RESP_OH;
|
||
|
|
small_oh = SMALL_EL_RESP_OH;
|
||
|
|
}
|
||
|
|
|
||
|
|
rt_end = rt_ptr + rt_num; /* end block */
|
||
|
|
|
||
|
|
size = 0;
|
||
|
|
while (rt_ptr < rt_end)
|
||
|
|
{
|
||
|
|
if (rt_ptr->el_tag == RT_ARR_END) /* treat case of array ending */
|
||
|
|
{ /* loops set at start of array */
|
||
|
|
if (--arr_loops[arr_loop_level] > 0) /* if need to do next ar elmnt */
|
||
|
|
rt_ptr -= rt_ptr->u.arr.num_rt_blks; /* mv rt_ptr to start of arr */
|
||
|
|
else
|
||
|
|
--arr_loop_level;
|
||
|
|
}
|
||
|
|
|
||
|
|
ellen = abs (rt_ptr->u.p.el_len); /* make sure positive */
|
||
|
|
switch (rt_ptr->el_tag)
|
||
|
|
{
|
||
|
|
case RT_ARR_START : /* arrays don't have to be aligned */
|
||
|
|
++arr_loop_level;
|
||
|
|
arr_loops[arr_loop_level] = rt_ptr->u.arr.num_elmnts;
|
||
|
|
/* let fall through to STR_MMSOP_START */
|
||
|
|
|
||
|
|
case RT_STR_START : /* structure starting */
|
||
|
|
size += med_oh; /* add in data element overhead */
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_UNSIGNED : /* unsigned integer */
|
||
|
|
size += small_oh + ellen + 1; /* high order bit set needs 0x00*/
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_UTC_TIME : /* UTC time */
|
||
|
|
case RT_BINARY_TIME : /* binary time */
|
||
|
|
case RT_INTEGER : /* integer */
|
||
|
|
case RT_FLOATING_POINT : /* float */
|
||
|
|
size += small_oh + ellen;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_VISIBLE_STRING : /* visible string */
|
||
|
|
case RT_OCTET_STRING : /* octet string */
|
||
|
|
size += ellen;
|
||
|
|
if (ellen < 128)
|
||
|
|
size += small_oh;
|
||
|
|
else
|
||
|
|
size += med_oh;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_GENERAL_TIME : /* generalized time */
|
||
|
|
size += small_oh + GENTIME_LEN;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_BOOL : /* boolean */
|
||
|
|
size += small_oh +1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_BCD : /* bcd */
|
||
|
|
size += small_oh + ellen;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_BIT_STRING : /* bit string */
|
||
|
|
len = 1 + CALC_BIT_LEN (ellen);
|
||
|
|
|
||
|
|
if (len < 128)
|
||
|
|
size += small_oh + len; /* add in data element overhead */
|
||
|
|
else
|
||
|
|
size += med_oh + len; /* add in data element overhead */
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_UTF8_STRING : /* Unicode UTF8 string */
|
||
|
|
el_size = ellen*4; /* Could take 4 bytes per char */
|
||
|
|
size += el_size;
|
||
|
|
if (el_size < 128)
|
||
|
|
size += small_oh;
|
||
|
|
else
|
||
|
|
size += med_oh;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case RT_ARR_END : /* array done */
|
||
|
|
case RT_STR_END : /* structure done */
|
||
|
|
break;
|
||
|
|
|
||
|
|
default : /* should not be any other tag */
|
||
|
|
return (0);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
rt_ptr++; /* point to next block */
|
||
|
|
} /* while (rt blocks) */
|
||
|
|
return (size);
|
||
|
|
}
|
||
|
|
|
||
|
|
|