776 lines
28 KiB
C
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 */
|
|
}
|
|
|