自主协议库编译通过

This commit is contained in:
lnk
2026-06-15 15:48:16 +08:00
parent d3579a2aa7
commit 7205cb5cb9
621 changed files with 224958 additions and 48 deletions

438
mmslib/mvlu/s_write.c Normal file
View File

@@ -0,0 +1,438 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1994 - 1996, All Rights Reserved */
/* */
/* MODULE NAME : s_write.c */
/* PRODUCT(S) : MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* NONE */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/02/09 JRB 32 Chk va_to_free before ...free_va. */
/* 01/23/09 MDE 31 Use 0x%X for hex values in log msgs. */
/* 01/13/09 MDE 30 Free VA (and temp type) in case of errors */
/* 05/01/08 JRB 29 Chk ms_asn1_to_local return & set */
/* WRITE_RESULT "failure" appropriately. */
/* 04/09/07 MDE 28 Enhanced filtered logging */
/* 10/30/06 JRB 27 Use new mvl_vmd_* object handling functions. */
/* Add args on call to _mvl_objname_to_va. */
/* Elim use of global "_mvl_curr_net_info". */
/* Elim use of global "_mvl_curr_usr_ind_ctrl". */
/* 08/09/06 JRB 26 ALWAYS set resp_tag & failure in wr_rslt */
/* same as in vaCtrl. In put_asn1_data, set */
/* vaCtrl->failure to appropriate value. */
/* 01/30/06 GLB 25 Integrated porting changes for VMS */
/* 05/16/05 JRB 24 Send appropriate failure codes in write resp.*/
/* Move statistics code so it is always executed*/
/* 03/13/03 JRB 23 Use mvl_type_ctrl_find. */
/* 07/24/02 JRB 22 Use mvl_send_resp_i like ALL responses. */
/* 07/09/02 MDE 21 Add maxpend_ind support */
/* 09/21/01 JRB 20 Alloc global bufs only once at startup. */
/* 05/25/01 MDE 19 Moved where the old data is saved */
/* 03/30/01 MDE 18 Changed MSMEM_ENC_INFO to MSMEM_ENC_OS_INFO */
/* 10/25/00 JRB 17 Del u_mvl funct ptrs. Call functs directly. */
/* Control with #ifdefs. */
/* 10/06/00 MDE 16 Now restore old data for write failure */
/* 05/15/00 MDE 15 Added MMS statistics */
/* 01/21/00 MDE 14 Now use MEM_SMEM for dynamic memory */
/* 11/22/99 JRB 13 mvlas_write_resp: del indCtrl from link list */
/* 09/13/99 MDE 12 Added SD_CONST modifiers */
/* 04/07/99 MDE 11 Logging improvements */
/* 12/11/98 MDE 10 Removed scope references from VA */
/* 12/08/98 MDE 09 Fixed write handling for alternate access */
/* 11/16/98 MDE 08 Renamed internal functions (prefix '_') */
/* 09/21/98 MDE 07 Minor lint cleanup */
/* 06/15/98 MDE 06 Changes to allow compile under C++ */
/* 05/15/98 JRB 05 Chg mvl_process.. arg to (MVL_IND_PEND *). */
/* 05/15/98 JRB 04 Call u_mvl_write_ind direct (no funct ptr). */
/* 02/20/98 MDE 03 Fixed usrVa set problem */
/* 02/10/98 MDE 02 Removed NEST_RT_TYPES, always support AA, */
/* added 'u_mvl_wr_ind_start' and */
/* 'u_mvl_wr_resp_sent', other */
/* 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_defs.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
/************************************************************************/
ST_RET (*u_mvl_wr_ind_start) (MVL_IND_PEND *indCtrl);
ST_VOID (*u_mvl_wr_resp_sent) (MVL_IND_PEND *indCtrl);
/************************************************************************/
/* Internal functions */
static ST_VOID put_asn1_data (MVL_IND_PEND *indCtrl, VARIABLE_LIST *vl,
ST_UCHAR *asn1_buffer, ST_INT asn1_len,
MVLAS_WR_VA_CTRL *vaCtrl);
/************************************************************************/
/************************************************************************/
/* _mvl_process_write_ind */
/* A write indication has been received, process it and respond */
/************************************************************************/
ST_VOID _mvl_process_write_ind (MVL_IND_PEND *indCtrl)
{
MVLAS_WRITE_CTRL *wrCtrl;
MVLAS_WR_VA_CTRL *vaCtrl;
WRITE_REQ_INFO *write_info;
ST_INT num_var;
VARIABLE_LIST *vl_ptr;
VAR_ACC_DATA *va_ptr;
ST_INT i;
ST_RET rc;
write_info = (WRITE_REQ_INFO *) indCtrl->event->u.mms.dec_rslt.data_ptr;
num_var = write_info->va_spec.num_of_variables;
/* verify that this is a list of variables */
if (write_info->va_spec.var_acc_tag != VAR_ACC_VARLIST)
{
_mplas_err_resp (indCtrl,7,2); /* access, non-existent */
return;
}
if (u_mvl_wr_ind_start)
{
/* This might set optional user pointer "indCtrl->usr_ind_ctrl". */
rc = (*u_mvl_wr_ind_start) (indCtrl);
if (rc != SD_SUCCESS)
{
_mplas_err_resp (indCtrl,7,2); /* access, non-existent */
return;
}
}
wrCtrl = &indCtrl->u.wr;
wrCtrl->vaCtrlTbl = (MVLAS_WR_VA_CTRL *) M_CALLOC (MSMEM_GEN, num_var,
sizeof(MVLAS_WR_VA_CTRL));
vaCtrl = wrCtrl->vaCtrlTbl;
wrCtrl->numVar = num_var;
/* Looks OK, prepare to process each variable in the list */
vl_ptr = (VARIABLE_LIST *) (write_info+1);
va_ptr = write_info->va_data;
for (i = 0; i < num_var; ++i, ++vl_ptr, ++va_ptr, ++vaCtrl)
put_asn1_data (indCtrl, vl_ptr, va_ptr->data, va_ptr->len, vaCtrl);
u_mvl_write_ind (indCtrl);
}
/************************************************************************/
/* mvlas_write_resp */
/************************************************************************/
ST_VOID mvlas_write_resp (MVL_IND_PEND *indCtrl)
{
MVLAS_WRITE_CTRL *wrCtrl;
MVLAS_WR_VA_CTRL *vaCtrl;
MVL_COMM_EVENT *event;
MVL_NET_INFO *net_info;
ST_RET rc;
ST_CHAR *resp_buf;
ST_INT num_var;
ST_INT va_data_size;
WRITE_RESP_INFO *resp_info;
WRITE_RESULT *wr_rslt;
ST_INT i;
MVL_TYPE_CTRL *type_ctrl;
net_info = indCtrl->event->net_info;
event = indCtrl->event;
wrCtrl = &indCtrl->u.wr;
vaCtrl = wrCtrl->vaCtrlTbl;
num_var = wrCtrl->numVar;
resp_buf = (ST_CHAR *) M_CALLOC (MSMEM_ENC_OS_INFO, 1, sizeof(WRITE_RESP_INFO) +
(num_var * sizeof (WRITE_RESULT)));
/* Create a write response info struct */
resp_info = (WRITE_RESP_INFO *) resp_buf;
resp_info->num_of_result = num_var;
wr_rslt = (WRITE_RESULT *) (resp_info +1);
for (i = 0; i < num_var; ++i, ++wr_rslt, ++vaCtrl)
{
wr_rslt->resp_tag = vaCtrl->resp_tag;
wr_rslt->failure = vaCtrl->failure;
if (vaCtrl->va != NULL)
{
if (wr_rslt->resp_tag == WR_RSLT_FAILURE)
{ /* On a failure, restore the previous data */
type_ctrl = mvl_type_ctrl_find (vaCtrl->va->type_id);
va_data_size = type_ctrl->data_size;
memcpy (vaCtrl->va->data, vaCtrl->oldData, va_data_size);
}
M_FREE (MSMEM_GEN, vaCtrl->oldData);
#if defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS)
if (vaCtrl->va->va_to_free != NULL)
u_mvl_free_va (MMSOP_WRITE, vaCtrl->va, event->net_info);
#endif /* defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS) */
}
if (wr_rslt->resp_tag == WR_RSLT_SUCCESS)
++mvl_mms_statistics.serverVarWrOk;
else
++mvl_mms_statistics.serverVarWrErr;
} /* end loop */
/* Build a write response */
rc = mpl_write_resp (event->u.mms.dec_rslt.id, resp_info);
if (rc == SD_SUCCESS)
mpl_resp_log (indCtrl, resp_info);
if (u_mvl_wr_resp_sent)
(*u_mvl_wr_resp_sent) (indCtrl);
M_FREE (MSMEM_ENC_OS_INFO, resp_buf);
M_FREE (MSMEM_GEN, wrCtrl->vaCtrlTbl);
/* NOTE: This funct frees indCtrl. DO NOT use after this. */
/* NOTE: if rc != SD_SUCCESS, this funct sends error resp. */
_mvl_send_resp_i (indCtrl, rc);
}
/************************************************************************/
/* put_asn1_data */
/* This function is to provide ASN.1 encoded data, given the variable */
/* list element. */
/************************************************************************/
static ST_VOID put_asn1_data (MVL_IND_PEND *indCtrl, VARIABLE_LIST *vl,
ST_UCHAR *asn1_buffer, ST_INT asn1_len,
MVLAS_WR_VA_CTRL *vaCtrl)
{
MVL_VAR_ASSOC *va;
RUNTIME_TYPE *rt;
ST_INT num_rt;
ST_RET rc;
ST_CHAR *temp_data_buf;
ST_CHAR *va_data;
ST_INT va_data_size;
ST_INT aa_mode;
ALT_ACCESS alt_acc; /* Alternate Access specification */
ST_BOOLEAN alt_access_pres;
ST_BOOLEAN alt_access_done;
MVL_TYPE_CTRL *type_ctrl;
/* There are more ways to fail than to succeed! */
/* Assume failure=ARE_TYPE_INCONSISTENT, but may be changed in some cases.*/
vaCtrl->resp_tag = WR_RSLT_FAILURE;
vaCtrl->failure = ARE_TYPE_INCONSISTENT;
alt_access_pres = vl->alt_access_pres;
if (alt_access_pres) /* no alternate access support now */
{
#if !defined(MVL_AA_SUPP)
MVL_LOG_NERR0 ("Put ASN1 Data : Alternate Access not supported");
return;
#else
/* now create the AA, given the ASN.1 spec */
if (ms_asn1_to_aa (vl->alt_access.data, vl->alt_access.len,
&alt_acc))
{
MVL_LOG_NERR0 ("Write Indication : ASN.1 -> AA failure");
return;
}
#endif
}
switch (vl->var_spec.var_spec_tag)
{
case VA_SPEC_NAMED :
va = _mvl_objname_to_va (&mvl_vmd, indCtrl->event->net_info, MMSOP_WRITE, &vl->var_spec.vs.name,
&vaCtrl->va_scope,
alt_access_pres,
&alt_acc,
&alt_access_done);
if (alt_access_pres && alt_access_done)
{
M_FREE (MSMEM_GEN, alt_acc.aa);
alt_access_pres = SD_FALSE;
}
if (!va) /* could not find variable association */
{
MVL_LOG_NERR1 ("Write ind : Variable Association '%s' not found",
vl->var_spec.vs.name.obj_name.vmd_spec);
vaCtrl->failure = ARE_OBJ_NONEXISTENT;
return;
}
vaCtrl->va = va;
va->usr_ind_ctrl = indCtrl->usr_ind_ctrl; /* save optional user pointer in va*/
/* Save the current data in case the user rejects the write */
type_ctrl = mvl_type_ctrl_find (va->type_id); /* find type */
va_data_size = type_ctrl->data_size;
vaCtrl->oldData = (ST_UCHAR *) M_MALLOC (MSMEM_GEN, va_data_size);
memcpy (vaCtrl->oldData, va->data, va_data_size);
/* We have obtained a variable association */
/* Now do the alternate access preprocess function if appropriate */
#if defined(MVL_AA_SUPP)
aa_mode = MVL_USE_UNPACKED_AA;
if (alt_access_pres && va->proc && va->proc->proc_write_aa)
{
rc = (*va->proc->proc_write_aa)(&va, &alt_acc,
indCtrl->event->net_info, &aa_mode);
if (rc != SD_SUCCESS)
{
MVL_LOG_NERR1 ("Write : proc_write_aa returned %d", rc);
return;
}
}
#endif
/* Now take care of the data conversion (asn1 to local) */
rc = mvl_get_runtime (va->type_id, &rt, &num_rt);
if (rc != SD_SUCCESS)
{
M_FREE (MSMEM_GEN, vaCtrl->oldData);
MVL_LOG_NERR1 ("Could not get type_id %d", va->type_id);
vaCtrl->va = NULL;
return;
}
/* Sanity check, because foundry can generate configured vars w/o */
/* the data pointer initialized. */
if (va->data == NULL)
{
M_FREE (MSMEM_GEN, vaCtrl->oldData);
MVL_LOG_NERR1 ("Write Indication : va '%s' data is NULL", va->name);
vaCtrl->va = NULL;
return;
}
va_data = (ST_CHAR *) va->data;
/* "va_data_size" already set above */
break;
case VA_SPEC_DESCRIBED :
default :
MVL_LOG_NERR0 ("Put ASN1 Data : Invalid Variable Specification Tag");
vaCtrl->failure = ARE_OBJ_ACC_UNSUPPORTED;
return;
break;
}
/* If we got here, we have a valid runtime and have resolved local */
/* data pointer and size. Go ahead and convert the ASN.1 data element to*/
/* local data format */
temp_data_buf = (ST_CHAR *) M_MALLOC (MSMEM_WR_DATA_DEC_BUF, va_data_size);
#if defined(MVL_AA_SUPP)
if (alt_access_pres == SD_FALSE || aa_mode == MVL_USE_NO_AA)
rc = ms_asn1_to_local (rt, num_rt, asn1_buffer, asn1_len, temp_data_buf);
else
{
/* This is an alternate access write, we must first copy the data */
/* contents to to the temp buffer, then only the selected elements */
/* will be written by the data conversion. */
memcpy (temp_data_buf, va_data, va_data_size);
if (aa_mode == MVL_USE_PACKED_AA)
m_alt_acc_packed = SD_TRUE;
else
m_alt_acc_packed = SD_FALSE;
rc = ms_asn1_to_local_aa (rt, num_rt, &alt_acc,
asn1_buffer, asn1_len, temp_data_buf);
}
#else
rc = ms_asn1_to_local (rt, num_rt, asn1_buffer, asn1_len, temp_data_buf);
#endif
if (rc != SD_SUCCESS)
{
MVL_LOG_NERR1 ("Put ASN1 Data : ms_asn1_to_local failed, rc = 0x%X", rc);
M_FREE (MSMEM_GEN, vaCtrl->oldData);
M_FREE (MSMEM_WR_DATA_DEC_BUF, temp_data_buf);
#if defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS)
/* Need to free VA (caller will not if vaCtrl->va == NULL) */
if (vaCtrl->va->va_to_free != NULL)
u_mvl_free_va (MMSOP_WRITE, vaCtrl->va, NULL);
#endif
vaCtrl->va = NULL;
if (rc == ASN1E_UNEXPECTED_TAG)
/* Tag mismatch in this context indicates MMS type mismatch. */
vaCtrl->failure = ARE_TYPE_INCONSISTENT;
else
vaCtrl->failure = ARE_OBJ_VALUE_INVALID;
return;
}
/* Call the preprocessing function for this variable, if it exists */
if (va->proc && va->proc->pre_write_aa)
{
rc = (*va->proc->pre_write_aa)(va, alt_access_pres, &alt_acc,
indCtrl->event->net_info,
temp_data_buf, va_data_size);
if (rc != SD_SUCCESS)
{
MVL_LOG_NERR1 ("Put ASN1 Data : call to Write pre-processor failed, rc = 0x%X", rc);
M_FREE (MSMEM_GEN, vaCtrl->oldData);
#if defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS)
/* Need to free VA (caller will not if vaCtrl->va == NULL) */
if (vaCtrl->va->va_to_free != NULL)
u_mvl_free_va (MMSOP_WRITE, vaCtrl->va, NULL);
#endif
vaCtrl->va = NULL;
}
}
/* OK, almost done. The data has been converted OK and the user has had */
/* a chance to look at it. If rc == SD_SUCCESS, we are OK. */
if (rc == SD_SUCCESS)
{
vaCtrl->resp_tag = WR_RSLT_SUCCESS;
memcpy (va_data, temp_data_buf, va_data_size);
/* Call the postprocessing function for this variable, if it exists */
if (va->proc && va->proc->post_write_aa)
(*va->proc->post_write_aa)(va, alt_access_pres, &alt_acc, indCtrl->event->net_info);
}
#if defined(MVL_AA_SUPP)
if (alt_access_pres) /* if we calloc'd this AA, free it */
M_FREE (MSMEM_GEN, alt_acc.aa);
#endif
M_FREE (MSMEM_WR_DATA_DEC_BUF, temp_data_buf);
}