Files
microser/mmslib/mmsl/mms_rej.c

282 lines
9.6 KiB
C
Raw Normal View History

2026-06-15 15:48:16 +08:00
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1986 - 2002, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : mms_rej.c */
/* PRODUCT(S) : MMSEASE, MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* This module contains the functions to decode/encode a reject */
/* operation. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 03/11/04 GLB 06 Cleaned up "thisFileName" */
/* 01/18/02 JRB 05 Fix encoding if !DEBUG_SISCO (use new fcts */
/* _ms_fin_pdu & _ms_fin_pdu_log. */
/* 12/20/01 JRB 04 Converted to use ASN1R (re-entrant ASN1) */
/* 09/13/99 MDE 03 Added SD_CONST modifiers */
/* 03/23/99 MDE 02 Changes to decode buffer allocation scheme */
/* 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"
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
#if defined(DEBUG_SISCO) && defined(S_MT_SUPPORT)
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
static REJECT_RESP_INFO *rej_info_ptr;
static ST_VOID rej_get_problem (ASN1_DEC_CTXT *aCtx, ST_UINT16 id_code);
/************************************************************************/
/************************************************************************/
/* mms_reject */
/* Reject PDU is being decoded, and this is a context-specific element. */
/* It should be an integer. */
/************************************************************************/
ST_VOID mms_reject (ASN1_DEC_CTXT *aCtx, ST_UINT16 id_code)
{
MLOG_CDEC0 ("mms_reject");
if (aCtx->asn1r_constr_elmnt)
{
asn1r_set_dec_err (aCtx, PDU_INVALID);
return;
}
rej_info_ptr = (REJECT_RESP_INFO *) _m_get_dec_buf (aCtx, sizeof (REJECT_RESP_INFO));
aCtx->asn1r_decode_method = ASN1_CLASS_METHOD;
rej_info_ptr -> detected_here = SD_FALSE; /* reject detected remotely */
rej_info_ptr -> pdu_type = UNKNOWNTYPE; /* in this case, no pdu type */
if (!id_code) /* if this is invoke id - */
{
if (asn1r_get_u32 (aCtx, &rej_info_ptr -> invoke)) /* read invoke id */
asn1r_set_dec_err (aCtx, PDU_INVALID);
else
{
rej_info_ptr -> invoke_known = SD_TRUE; /* set flag */
_mmsdec_rslt -> dec_level = 2;
_mmsdec_rslt -> id = rej_info_ptr -> invoke; /* store invoke ID */
aCtx->asn1r_c_id_fun = rej_get_problem;
}
}
else
{
rej_info_ptr -> invoke_known = SD_FALSE; /* clear */
rej_get_problem (aCtx, id_code); /* call rejectreason fun direct */
}
}
/************************************************************************/
/* rej_get_problem */
/* Reject PDU is being decoded, and this is a context-specific element. */
/* It should be an integer in which the tag is the error class and the */
/* value is the error code. */
/************************************************************************/
static ST_VOID rej_get_problem (ASN1_DEC_CTXT *aCtx, ST_UINT16 id_code)
{
MLOG_CDEC0 ("rej_get_problem");
if (aCtx->asn1r_constr_elmnt || id_code < 1 || id_code > 11 || aCtx->asn1r_elmnt_len > 1)
{ /* better not be constructor */
asn1r_set_dec_err (aCtx, PDU_INVALID); /* better be context tagged 1-4 */
return; /* max value = 8 */
}
/* Information looks OK; extract it. */
rej_info_ptr -> rej_class = id_code;
asn1r_get_i16 (aCtx, &rej_info_ptr -> rej_code); /* get the problem value */
aCtx->asn1r_decode_done_fun = _mms_dec_done_ok; /* all done now */
aCtx->asn1r_decode_done = SD_TRUE;
}
#ifndef MMS_LITE
/************************************************************************/
/************************************************************************/
/* mp_reject_resp */
/* Sends reject message. Returns integer value indicating success */
/* (value = 0) or failure (value <> 0) to send the reject message. */
/************************************************************************/
ST_RET mp_reject_resp (ST_INT chan, REJECT_RESP_INFO *info_ptr)
{
ST_UCHAR *msg_ptr;
ST_INT msg_len;
LLP_ADDR_INFO add_llp_info;
ST_RET ret;
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
S_LOCK_COMMON_RESOURCES ();
msg_ptr = _ms_mk_reject (aCtx, m_build_buf,mms_max_msgsize,info_ptr);
msg_len = M_BUILD_BUF_END - msg_ptr; /* find length */
add_llp_info.i.LLC.use_rem_addr = SD_FALSE;
add_llp_info.i.LLC.send_type = REJECT_PDU;
add_llp_info.i.LLC.req_ptr = (ST_CHAR *)NULL;
/* Check for encode overrun */
if (aCtx->asn1r_encode_overrun)
ret = ME_ASN1_ENCODE_OVERRUN;
else
ret = _mms_send_data (chan, msg_len, msg_ptr, P_context_sel[chan], &add_llp_info);
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
#else
/************************************************************************/
/************************************************************************/
/* mpl_reject_resp */
/* Sends reject message. Returns integer value indicating success */
/* (value = 0) or failure (value <> 0) to send the reject message. */
/************************************************************************/
ST_RET mpl_reject_resp (REJECT_RESP_INFO *info_ptr)
{
ST_RET ret;
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
S_LOCK_COMMON_RESOURCES ();
mmsl_msg_start = _ms_mk_reject (aCtx, mmsl_enc_buf,mmsl_enc_buf_size,info_ptr);
/* find length */
mmsl_msg_len = (mmsl_enc_buf + mmsl_enc_buf_size) - mmsl_msg_start;
if (aCtx->asn1r_encode_overrun) /* Check for encode overrun */
ret = ME_ASN1_ENCODE_OVERRUN;
else
ret = SD_SUCCESS;
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
#endif
/************************************************************************/
/* _ms_mk_reject */
/* Construct a reject PDU. */
/************************************************************************/
ST_UCHAR *_ms_mk_reject (ASN1_ENC_CTXT *aCtx, ST_UCHAR *msg_ptr, ST_INT buf_len,
REJECT_RESP_INFO *info_ptr)
{
ST_UCHAR *pduStart;
ST_INT pduLen;
asn1r_strt_asn1_bld (aCtx, msg_ptr,buf_len); /* init the ASN.1 tools */
asn1r_wr_i16 (aCtx, info_ptr -> rej_code);
asn1r_fin_prim (aCtx, info_ptr -> rej_class,CTX);
#ifndef MMS_LITE
if (info_ptr->invoke_known && info_ptr->invoke <= MAX_INVOKE)
#else
if (info_ptr->invoke_known)
#endif
{
asn1r_wr_u32 (aCtx, info_ptr -> invoke); /* if the invoke ID is known & */
asn1r_fin_prim (aCtx, 0,CTX); /* is not artificial, write it */
}
pduStart = _ms_fin_pdu (aCtx, MMSREJECT, &pduLen);
#ifdef DEBUG_SISCO
_ms_fin_pdu_log (MMSREJECT, "REJECT", pduStart, pduLen);
#endif
return (pduStart);
}
#ifndef MMS_LITE
/************************************************************************/
/************************************************************************/
/* _ms_reject_resp */
/* Function to reject an MMS confirmed response pdu, given the request */
/* control structure. This must be a valid response, parsed OK. */
/* Called by the user or virtual machine after the confirm is matched. */
/************************************************************************/
ST_VOID _ms_reject_resp (MMSREQ_PEND *reqptr, ST_INT16 code)
{
REJECT_RESP_INFO info; /* reject input info structure */
info.detected_here = SD_TRUE; /* parse error detected locally */
info.invoke_known = SD_TRUE;
info.invoke = reqptr->id;
info.pdu_type = MMSRESP; /* confirmed response */
info.rej_code = code; /* include error code */
info.rej_class = 2; /* invalid response class */
if (mp_reject_resp (reqptr->chan,&info)) /* send the reject pdu */
(*u_mmsexcept_ind_fun)(reqptr->chan,MX_REJECT);
(*u_reject_ind_fun) (reqptr->chan,&info);
}
/************************************************************************/
/* mp_reject_ind */
/************************************************************************/
ST_RET mp_reject_ind (MMSREQ_IND *req_ptr, REJECT_RESP_INFO *info_ptr)
{
ST_RET ret; /* function return value */
S_LOCK_COMMON_RESOURCES ();
if (!(ret = _ms_check_ind_actv (req_ptr)))
{
if (!(ret = mp_reject_resp (req_ptr->chan, info_ptr)))
_ms_ind_serve_done (req_ptr);
}
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
/************************************************************************/
/* mp_reject_conf */
/************************************************************************/
ST_RET mp_reject_conf (MMSREQ_PEND *req_ptr, REJECT_RESP_INFO *info_ptr)
{
ST_RET ret; /* function return value */
S_LOCK_COMMON_RESOURCES ();
if (!(ret = _ms_check_req_actv (req_ptr)))
{
ret = mp_reject_resp (req_ptr->chan, info_ptr);
}
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
#endif