Files
microser/mmslib/mmsl/mms_err.c
2026-06-15 15:48:16 +08:00

776 lines
28 KiB
C

/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1986 - 2007, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : mms_err.c */
/* PRODUCT(S) : MMSEASE, MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* This module contains the MMS error functions for decoding */
/* & encoding the error response PDUs : */
/* confirmed-ErrorPDU */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 11/01/07 EJV 08 Rem obsolete LLC30... code. */
/* 04/05/02 MDE 07 Added MLOG logging */
/* 01/23/02 JRB 06 Fix "Response built" msg (was missing header)*/
/* 12/20/01 JRB 05 Converted to use ASN1R (re-entrant ASN1) */
/* 09/13/99 MDE 04 Added SD_CONST modifiers */
/* 03/23/99 MDE 03 Changes to decode buffer allocation scheme */
/* 06/15/98 MDE 02 Changes to allow compile under C++ */
/* 07/03/97 MDE 01 Op-specific info buffer handling changes */
/* 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"
#include "mloguser.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
/************************************************************************/
/* variables global to the decode : */
static ERR_INFO *err_info_ptr;
#ifdef MOD_SUPPORT
static ST_VOID err_mod_pos (ASN1_DEC_CTXT *aCtx);
#endif
static ST_VOID err_rsp2 (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_class (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_cac (ASN1_DEC_CTXT *aCtx);
#ifdef CS_SUPPORT
static ST_VOID err_get_cs (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_cs_done (ASN1_DEC_CTXT *aCtx);
#endif
static ST_VOID err_class_cstr_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_add_code (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_add_descr (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_add_ssi_cstr (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_add_ssi_i16 (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_add_ssi_u32 (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_dee_obj_name (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_dee_obj_name_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_get_add_serv_err (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_adtnl_done (ASN1_DEC_CTXT *aCtx);
static ST_VOID err_ssi_done (ASN1_DEC_CTXT *aCtx);
/************************************************************************/
/************************************************************************/
/* mms_err_invoke_fun */
/* This function is called from mmsdec.c when invoke ID is expected */
/* in a CONFIRMED or CANCEL ERROR PDU. */
/************************************************************************/
ST_VOID mms_err_invoke_fun (ASN1_DEC_CTXT *aCtx, ST_UINT16 id_code)
{
ST_INT pdutype;
pdutype = _mmsdec_rslt->type;
if (aCtx->asn1r_constr_elmnt || id_code != 0)
{
asn1r_set_dec_err (aCtx, PDU_INVALID); /* wrong code or constructed int*/
return;
}
if (asn1r_get_u32 (aCtx, &_mmsdec_rslt->id))
{
if (pdutype == MMSCANERR)
asn1r_set_dec_err (aCtx, CANERR_INVAL_INVOKE); /* not a valid integer contents */
else
asn1r_set_dec_err (aCtx, ERR_INVAL_INVOKE); /* not a valid integer contents */
return;
}
_mmsdec_rslt->dec_level = 2; /* set flag that Invoke ID is OK */
MLOG_CDEC1 ("Invoke ID present, = %ld",_mmsdec_rslt->id);
err_info_ptr = (ERR_INFO *) _m_get_dec_buf (aCtx, sizeof (ERR_INFO));
if (pdutype == MMSCANERR) /* Cancel Error PDU, next must */
ASN1R_TAG_ADD (aCtx, CTX | CONSTR,1,err_rsp2); /* be context tag 1 cstr */
else
{ /* Confirmed Error PDU, next */
#ifdef MOD_SUPPORT
ASN1R_TAG_ADD (aCtx, CTX ,1,err_mod_pos); /* Context tag 1 (opt) */
#endif
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,2,err_rsp2); /* Context tag 2 cstr */
}
}
#ifdef MOD_SUPPORT
/************************************************************************/
/* err_mod_pos */
/* This function is called when a modifier position is detected in a */
/* confirmed_request_error PDU. The only thing which may follow is a */
/* service error description. */
/************************************************************************/
static ST_VOID err_mod_pos (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_mod_pos");
if (asn1r_get_i32 (aCtx, &(err_info_ptr->adtnl.mod_pos))) /* read mod position */
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
err_info_ptr -> adtnl.mod_pos_pres = SD_TRUE;
ASN1R_TAG_ADD (aCtx, CTX | CONSTR,2,err_rsp2); /* Context tag 2 cstr */
}
#endif
/************************************************************************/
/************************************************************************/
/* mms_err_rsp */
/* This function is called from mmsdec.c when an Error Response PDU is */
/* being decoded for initiate or conclude error ONLY */
/* When this is called directly, we need to allocate the buffer */
/************************************************************************/
ST_VOID mms_err_rsp (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("mms_err_rsp");
err_info_ptr = (ERR_INFO *) _m_get_dec_buf (aCtx, sizeof (ERR_INFO));
aCtx->asn1r_err_fun = _mms_dec_buf_free;
err_rsp2 (aCtx); /* set tags */
}
/************************************************************************/
/************************************************************************/
/* _mms_get_service_err */
/* This function is called from rs_termd.c when IS is used and the */
/* 'discarded' parameter is send (service error) -or- from rs_evnot.c */
/* when the action result is failure. */
/************************************************************************/
ST_VOID _mms_get_service_err (ASN1_DEC_CTXT *aCtx, ERR_INFO *err_ptr)
{
err_info_ptr = err_ptr; /* use caller's storage */
err_rsp2 (aCtx); /* set tags */
}
/************************************************************************/
/************************************************************************/
/* err_rsp2 */
/* This function is called when an Error Response PDU is being decoded */
/* for confirmed error. */
/************************************************************************/
static ST_VOID err_rsp2 (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_rsp2");
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,0,err_class);
}
/************************************************************************/
/* err_class */
/* This function is invoked when the ServiceError is being decoded, and */
/* the errorClass choice is encountered. */
/************************************************************************/
static ST_VOID err_class (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_class");
ASN1R_TAG_ADD (aCtx, CTX, 0, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 1, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 2, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 3, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 4, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 5, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 6, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 7, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 8, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX, 9, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX,10, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX,11, err_get_cac);
ASN1R_TAG_ADD (aCtx, CTX,12, err_get_cac);
#ifdef CS_SUPPORT
#ifndef MMS_LITE
if (mms_chan_info[_mmsdechan].version) /* IS */
#else
if (mmsl_version) /* IS */
#endif
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,13, err_get_cs); /* CS error */
#endif
}
/************************************************************************/
/* err_get_cac */
/* error response is being decoded: context tagged error class has */
/* been encountered, get the error class and error code. */
/************************************************************************/
static ST_VOID err_get_cac (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_cac");
err_info_ptr->eclass = aCtx->asn1r_elmnt_id; /* save the error class */
if (asn1r_get_i16 (aCtx, &(err_info_ptr->code))) /* read the error code */
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = err_class_cstr_done; /* choice cstr done */
}
#ifdef CS_SUPPORT
/************************************************************************/
/* err_get_cs */
/* error response is being decoded: context tagged error class 13 has */
/* been encountered, get the CS service error. */
/************************************************************************/
static ST_VOID err_get_cs (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_cs");
err_info_ptr->adtnl.ss_error_data= aCtx->asn1r_field_ptr; /* save ptr to field */
err_info_ptr->adtnl.ss_error_len = aCtx->asn1r_elmnt_len; /* save len of field */
asn1r_parse_next (aCtx, err_cs_done); /* parse the contents */
}
/************************************************************************/
/* err_cs_done */
/* Companion Standard service error has been parsed OK. */
/************************************************************************/
static ST_VOID err_cs_done (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = err_class_cstr_done; /* choice cstr done */
}
#endif
/************************************************************************/
/* err_class_cstr_done */
/* errorClass constructor (choice) is complete */
/* set up to get additional (optional) information */
/************************************************************************/
static ST_VOID err_class_cstr_done (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_class_cstr_done");
/* add tags for optional information */
ASN1R_TAG_ADD (aCtx, CTX, 1, err_get_add_code);
ASN1R_TAG_ADD (aCtx, CTX, 2, err_get_add_descr);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR, 3, err_add_ssi_cstr);
aCtx->asn1r_decode_done_fun = _mms_dec_done_ok;
if ((_mmsdec_rslt->type == MMSREQ) || /* terminate download request */
(_mmsdec_rslt->type == MMSUNREQ)) /* or Event Notification */
/* Terminate Download req or Event Notification unconfirmed */
/* request is being decoded, decode can be done, but check for */
/* companion standard information. */
_ms_set_cs_check (aCtx);
else
asn1r_set_all_cstr_done (aCtx); /* clear all cstr done funtions */
}
/************************************************************************/
/* err_get_add_code */
/* error response is being decoded: additional error code has been */
/* encountered. */
/************************************************************************/
static ST_VOID err_get_add_code (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_add_code");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present */
err_info_ptr->adtnl.code_pres = SD_TRUE; /* set code present */
/* read the additional error code */
if (asn1r_get_i32 (aCtx, &(err_info_ptr->adtnl.code)))
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
ASN1R_TAG_ADD (aCtx, CTX, 2, err_get_add_descr);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR, 3, err_add_ssi_cstr);
if ((_mmsdec_rslt->type == MMSREQ) || /* terminate download request */
(_mmsdec_rslt->type == MMSUNREQ)) /* or Event Notification */
/* Terminate Download req or Event Notification unconfirmed */
/* request is being decoded, decode can be done, but check for */
/* companion standard information. */
_ms_set_cs_check (aCtx);
else
asn1r_set_all_cstr_done (aCtx); /* clear all cstr done funtions */
}
/************************************************************************/
/* err_get_add_descr */
/* error response is being decoded: additional error description has */
/* been encountered. */
/************************************************************************/
static ST_VOID err_get_add_descr (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_add_descr");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present */
err_info_ptr->adtnl.descr_pres = SD_TRUE; /* set descr present */
/* read the additional error description */
/* copy error description back onto itself shifted by one character */
err_info_ptr->adtnl.descr = (ST_CHAR *)aCtx->asn1r_field_ptr -1;
if (asn1r_get_vstr (aCtx, err_info_ptr->adtnl.descr))
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
ASN1R_TAG_ADD (aCtx, CTX|CONSTR, 3, err_add_ssi_cstr);
if ((_mmsdec_rslt->type == MMSREQ) || /* terminate download request */
(_mmsdec_rslt->type == MMSUNREQ)) /* or Event Notification */
/* Terminate Download req or Event Notification unconfirmed */
/* request is being decoded, decode can be done, but check for */
/* companion standard information. */
_ms_set_cs_check (aCtx);
else
asn1r_set_all_cstr_done (aCtx); /* clear all cstr done funtions */
}
/************************************************************************/
/* err_add_ssi_cstr */
/* error response is being decoded: additional service specific error */
/* information constructor has been encountered. */
/************************************************************************/
static ST_VOID err_add_ssi_cstr (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_ssi_cstr");
/* add tags for all choices */
ASN1R_TAG_ADD (aCtx, CTX, 0, err_get_add_ssi_i16);
ASN1R_TAG_ADD (aCtx, CTX, 1, err_get_add_ssi_i16);
ASN1R_TAG_ADD (aCtx, CTX, 2, err_get_add_ssi_i16);
ASN1R_TAG_ADD (aCtx, CTX, 3, err_get_add_ssi_i16);
ASN1R_TAG_ADD (aCtx, CTX, 4, err_get_add_ssi_i16);
ASN1R_TAG_ADD (aCtx, CTX, 5, err_get_add_ssi_u32);
ASN1R_TAG_ADD (aCtx, CTX, 6, err_get_add_ssi_u32);
ASN1R_TAG_ADD (aCtx, CTX, 7, err_get_add_ssi_u32);
#ifndef MMS_LITE
if (mms_chan_info[_mmsdechan].version) /* IS */
#else
if (mmsl_version) /* IS */
#endif
{
ASN1R_TAG_ADD (aCtx, CTX|CONSTR, 8, err_get_dee_obj_name); /* def ev enroll*/
ASN1R_TAG_ADD (aCtx, CTX, 9, err_get_add_ssi_i16); /* file rename */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR,10, err_get_add_serv_err); /* adtnl service*/
}
else
{
ASN1R_TAG_ADD (aCtx, CTX, 8, err_get_add_ssi_i16); /* file rename */
ASN1R_TAG_ADD (aCtx, CTX|CONSTR, 9, err_get_add_serv_err); /* adtnl service*/
}
}
/************************************************************************/
/* err_get_add_ssi_i16 */
/* error response is being decoded: additional service specific error */
/* information has been encountered for obtain file, start, stop, */
/* resume, reset or file rename. */
/************************************************************************/
static ST_VOID err_get_add_ssi_i16 (ASN1_DEC_CTXT *aCtx)
{
ST_INT16 ssi_error;
MLOG_CDEC0 ("err_get_add_ssi_i16");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present indicator */
err_info_ptr->adtnl.ssi_pres = SD_TRUE; /* set additional service pres */
err_info_ptr->adtnl.service = aCtx->asn1r_elmnt_id; /* save the service id */
/* read the additional service error */
if (asn1r_get_i16 (aCtx, &ssi_error))
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
else
err_info_ptr->adtnl.ss_error_val = (ST_UINT32) ssi_error;
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = err_ssi_done;
}
/************************************************************************/
/* err_get_add_ssi_u32 */
/* error response is being decoded: additional service specific error */
/* information has been encountered for delete varaible access, delete */
/* named variable list or delete named type. */
/************************************************************************/
static ST_VOID err_get_add_ssi_u32 (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_add_ssi_u32");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present indicator */
err_info_ptr->adtnl.ssi_pres = SD_TRUE; /* set additional service pres */
err_info_ptr->adtnl.service = aCtx->asn1r_elmnt_id; /* save the service id */
/* read the additional service error */
if (asn1r_get_u32 (aCtx, &(err_info_ptr->adtnl.ss_error_val)))
asn1r_set_dec_err (aCtx, ERR_UNSPECIFIED);
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = err_ssi_done;
}
/************************************************************************/
/* err_get_dee_obj_name */
/* error response is being decoded: additional service specific error */
/* information has been encountered for define event enrollment error */
/* get the object name. */
/************************************************************************/
static ST_VOID err_get_dee_obj_name (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_dee_obj_name");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present indicator */
err_info_ptr->adtnl.ssi_pres = SD_TRUE; /* set additional service pres */
err_info_ptr->adtnl.service = aCtx->asn1r_elmnt_id; /* save the service id */
/* read the object name */
_ms_get_mms_objname (aCtx, &err_info_ptr->adtnl.ss_error_oname,
err_dee_obj_name_done);
}
/************************************************************************/
/* err_dee_obj_name_done */
/* define event enrollment error is being decoded: object name has */
/* been obtained. */
/************************************************************************/
static ST_VOID err_dee_obj_name_done (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_dee_obj_name_done");
aCtx->asn1r_c_done_fun [aCtx->asn1r_msg_level] = err_adtnl_done;
}
/************************************************************************/
/* err_get_add_serv_err */
/* error response is being decoded: additional service specific error */
/* information has been encountered for additional service error. */
/************************************************************************/
static ST_VOID err_get_add_serv_err (ASN1_DEC_CTXT *aCtx)
{
MLOG_CDEC0 ("err_get_add_serv_err");
err_info_ptr->adtnl.info_pres = SD_TRUE; /* set info present indicator */
err_info_ptr->adtnl.ssi_pres = SD_TRUE; /* set additional service pres */
err_info_ptr->adtnl.service = aCtx->asn1r_elmnt_id; /* save the service id */
/* Companion Standard additional service error */
err_info_ptr->adtnl.ss_error_data = aCtx->asn1r_field_ptr; /* save ptr to field */
err_info_ptr->adtnl.ss_error_len = aCtx->asn1r_elmnt_len; /* save len of field */
asn1r_parse_next (aCtx, err_adtnl_done); /* parse contents */
}
/************************************************************************/
/* err_adtnl_done */
/* IS: define event enrollment, object name has been obtained -OR- */
/* Companion Standard ANY has been parsed OK. Message is now done. */
/************************************************************************/
static ST_VOID err_adtnl_done (ASN1_DEC_CTXT *aCtx)
{
aCtx->asn1r_c_done_fun[aCtx->asn1r_msg_level] = err_ssi_done;
}
/************************************************************************/
/* err_ssi_done */
/* Service specific info constructor done */
/************************************************************************/
static ST_VOID err_ssi_done (ASN1_DEC_CTXT *aCtx)
{
if ((_mmsdec_rslt->type == MMSREQ) || /* terminate download request */
(_mmsdec_rslt->type == MMSUNREQ)) /* or Event Notification */
/* Terminate Download req or Event Notification unconfirmed */
/* request is being decoded, decode can be done, but check for */
/* companion standard information. */
_ms_set_cs_check (aCtx);
else
aCtx->asn1r_decode_done = SD_TRUE; /* just terminate the parse */
}
#ifndef MMS_LITE
/************************************************************************/
/************************************************************************/
/* mp_err_resp */
/* Create and send a general error response */
/************************************************************************/
ST_RET mp_err_resp (MMSREQ_IND *indptr, ST_INT16 class, ST_INT16 code)
{
ST_UCHAR *msg_ptr; /* pointer to start of message */
ST_INT msg_len; /* length of message built */
ST_RET ret; /* function return value */
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
S_LOCK_COMMON_RESOURCES ();
if (!(ret = _ms_check_ind_actv (indptr)))
{
msg_ptr = _ms_mk_err_resp (aCtx, m_build_buf,mms_max_msgsize,indptr->op,indptr->id,
class,code);
msg_len = M_BUILD_BUF_END - msg_ptr;
if (aCtx->asn1r_encode_overrun) /* Check for encode overrun */
ret = ME_ASN1_ENCODE_OVERRUN;
else
ret = _mms_send_data (indptr->chan, msg_len, msg_ptr,
indptr->context, indptr->add_addr_info);
/* If a response logging function is installed, call it */
if (!ret && m_log_error_resp_fun && (mms_debug_sel & MMS_LOG_RESP))
(*m_log_error_resp_fun) (indptr, class, code);
_ms_ind_serve_done (indptr);
}
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
#else
/************************************************************************/
/************************************************************************/
/* mpl_err_resp */
/* Create and send a general error response */
/* Initiate, Conclude, Confirmed Service */
/************************************************************************/
ST_RET mpl_err_resp (ST_INT opcode, ST_UINT32 invoke,
ST_INT16 err_class, ST_INT16 code)
{
ST_INT ret;
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
ERR_INFO err_info;
S_LOCK_COMMON_RESOURCES ();
mmsl_msg_start = _ms_mk_err_resp (aCtx, mmsl_enc_buf,mmsl_enc_buf_size,opcode,invoke,
err_class,code);
mmsl_msg_len = (mmsl_enc_buf + mmsl_enc_buf_size) - mmsl_msg_start;
if (!aCtx->asn1r_encode_overrun) /* Check for encode overrun */
ret = SD_SUCCESS;
else
ret = ME_ASN1_ENCODE_OVERRUN;
if ((mms_debug_sel & MMS_LOG_RESP) && ret == SD_SUCCESS && ml_log_error_resp_fun)
{
memset (&err_info, 0, sizeof (err_info));
err_info.code = code;
err_info.eclass = err_class;
(*ml_log_error_resp_fun) (invoke, &err_info);
}
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
#endif
/************************************************************************/
/************************************************************************/
/* _ms_mk_err_resp */
/* This function is called to build a general error response. */
/* adtnl_err_info is a global variable containing additional error */
/* information. */
/************************************************************************/
ST_UCHAR *_ms_mk_err_resp (ASN1_ENC_CTXT *aCtx, ST_UCHAR *buf_ptr, ST_INT buf_len, ST_INT op,
ST_UINT32 id, ST_INT16 err_class, ST_INT16 code)
{
ST_INT pdu_type; /* PDU type to go in error PDU. */
#ifdef DEBUG_SISCO
ST_UCHAR *msg_start; /* These variables used for */
ST_INT msg_len; /* debug print only */
#endif
asn1r_strt_asn1_bld (aCtx, buf_ptr,buf_len); /* init the ASN.1 tools */
_ms_wr_service_err (aCtx, err_class,code,&adtnl_err_info);
/* Write SEQUENCE header and invoke id, if this opcode is NOT initiate */
/* or conclude. */
if ((op == MMSOP_INITIATE) || (op == MMSOP_CONCLUDE))
;
else
{ /* Finish the serviceError sequence. */
if (op == MMSOP_CANCEL)
asn1r_fin_constr (aCtx, 1,CTX,DEF); /* context tag 1 for cancel */
else
asn1r_fin_constr (aCtx, 2,CTX,DEF); /* context 2 for confirmed err */
#ifdef MOD_SUPPORT
if (adtnl_err_info.mod_pos_pres) /* send the modifier position */
{
asn1r_wr_u32 (aCtx, adtnl_err_info.mod_pos);
asn1r_fin_prim (aCtx, 1,CTX);
adtnl_err_info.mod_pos_pres = SD_FALSE;
}
#endif
asn1r_wr_u32 (aCtx, id); /* Write the invoke ID. */
asn1r_fin_prim (aCtx, 0,CTX); /* conf and cancl both use CTX 0 tag */
}
/* Reset add'l info structure to empty */
adtnl_err_info.info_pres = SD_FALSE;
switch (op)
{
case MMSOP_INITIATE :
pdu_type = MMSINITERR;
break;
case MMSOP_CONCLUDE :
pdu_type = MMSCNCLERR;
break;
case MMSOP_CANCEL :
pdu_type = MMSCANERR;
break;
default:
pdu_type = MMSERROR;
}
#ifdef DEBUG_SISCO
asn1r_fin_constr (aCtx, (ST_UINT16) pdu_type,CTX,DEF);
msg_start = aCtx->asn1r_field_ptr + 1;
msg_len = (buf_ptr + buf_len) - msg_start;
MLOG_ENC1 ("ERROR Response built : len = %d ",msg_len);
MLOG_ENCH (msg_len,msg_start);
MLOG_PAUSEENC (NULL);
return (msg_start);
#else
asn1r_fin_constr (aCtx, (ST_UINT16) pdu_type,CTX,DEF);
return (aCtx->asn1r_field_ptr + 1);
#endif
}
/************************************************************************/
/************************************************************************/
/* wr_service_err */
/************************************************************************/
ST_VOID _ms_wr_service_err (ASN1_ENC_CTXT *aCtx, ST_INT16 err_class, ST_INT16 code,
ADTNL_ERR_RESP_INFO *adtnl_info)
{
ST_INT16 ssi_error;
asn1r_strt_constr (aCtx); /* start sequence constructor */
if (adtnl_info->info_pres)
{ /* write additional info if present */
if (adtnl_info->ssi_pres)
{ /* write the service specific info */
asn1r_strt_constr (aCtx);
switch (adtnl_info->service)
{
case 0 : /* obtain file */
case 1 : /* start */
case 2 : /* stop */
case 3 : /* resume */
case 4 : /* reset */
ssi_error = (ST_INT16) adtnl_info->ss_error_val;
asn1r_wr_i16 (aCtx, ssi_error);
asn1r_fin_prim (aCtx, adtnl_info->service,CTX);
break;
case 5 : /* delete variable access */
case 6 : /* delete named variable list */
case 7 : /* delete named type */
asn1r_wr_u32 (aCtx, adtnl_info->ss_error_val);
asn1r_fin_prim (aCtx, adtnl_info->service,CTX);
break;
case 8 :
#ifndef MMS_LITE
if (mms_chan_info[_mmsdechan].version) /* IS */
#else
if (mmsl_version) /* IS */
#endif
{ /* IS, define event enrollment */
asn1r_strt_constr (aCtx);
_ms_wr_mms_objname (aCtx, &adtnl_info->ss_error_oname);
asn1r_fin_constr (aCtx, 8,CTX,DEF);
}
else
{ /* DIS, file rename */
ssi_error = (ST_INT16) adtnl_info->ss_error_val;
asn1r_wr_i16 (aCtx, ssi_error);
asn1r_fin_prim (aCtx, adtnl_info->service,CTX);
}
break;
case 9 :
#ifndef MMS_LITE
if (mms_chan_info[_mmsdechan].version) /* IS */
#else
if (mmsl_version) /* IS */
#endif
{ /* IS, file rename */
ssi_error = (ST_INT16) adtnl_info->ss_error_val;
asn1r_wr_i16 (aCtx, ssi_error);
asn1r_fin_prim (aCtx, adtnl_info->service,CTX);
}
else
{ /* DIS, additional service err */
asn1r_strt_constr (aCtx);
asn1r_wr_delmnt (aCtx, adtnl_info->ss_error_data,adtnl_info->ss_error_len);
asn1r_fin_constr (aCtx, 9,CTX,DEF);
}
break;
default: /* IS, additional service error */
asn1r_strt_constr (aCtx);
asn1r_wr_delmnt (aCtx, adtnl_info->ss_error_data,adtnl_info->ss_error_len);
asn1r_fin_constr (aCtx, 10,CTX,DEF);
}
asn1r_fin_constr (aCtx, 3,CTX,DEF);
}
if (adtnl_info->descr_pres)
{ /* write the additional description */
asn1r_wr_vstr (aCtx, adtnl_info->descr);
asn1r_fin_prim (aCtx, 2,CTX);
}
if (adtnl_info->code_pres)
{ /* write the service specific info */
asn1r_wr_i32 (aCtx, adtnl_info->code);
asn1r_fin_prim (aCtx, 1,CTX);
}
adtnl_info->info_pres = SD_FALSE;
}
asn1r_strt_constr (aCtx); /* start choice constructor */
asn1r_wr_i16 (aCtx, code); /* write the value */
asn1r_fin_prim (aCtx, err_class,CTX); /* finish the contents */
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* context 0 cstr */
}