282 lines
9.6 KiB
C
282 lines
9.6 KiB
C
/************************************************************************/
|
|
/* 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
|