Files
microser/mmslib/ositcps/copp_enc.c

661 lines
26 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., */
/* 1997-2002, All Rights Reserved */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : copp_enc.c */
/* PRODUCT(S) : MOSI Stack (over TP4) */
/* */
/* MODULE DESCRIPTION : */
/* This file implements binding and encoding functions */
/* of the COPP protocol. */
/* */
/* For information see the: */
/* ISO 8822 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation service */
/* definition. */
/* ISO 8823 "Information processing systems - Open Systems */
/* Interconnection - Connection oriented presentation protocol */
/* specification. */
/* */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* copp_bind */
/* copp_unbind */
/* */
/* copp_con_req */
/* copp_con_rsp_pos */
/* copp_con_rsp_neg */
/* */
/* copp_rel_req */
/* copp_rel_rsp_pos */
/* */
/* copp_u_abort_req */
/* */
/* copp_data_req */
/* */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 04/28/08 GLB 07 Removed CALLED_ONLY and CALLING_ONLY */
/* 01/02/02 JRB 06 Converted to use ASN1R (re-entrant ASN1) */
/* 06/17/98 JRB 05 Allow second call to copp_bind if PSEL same. */
/* Use new error codes. */
/* 02/20/98 JRB 04 Cast wr_i8 arg. Chg abort_reason to ST_INT8. */
/* 12/22/97 JRB 03 Use ST_INT8. */
/* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */
/* 03/19/97 JRB 02 Add "CALLING" support. General cleanup. */
/* 02/27/97 JRB 01 Created */
/************************************************************************/
#ifdef DEBUG_SISCO
static char *thisFileName = __FILE__;
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "asn1defs.h"
#include "acse2.h"
#include "copp.h"
#include "cosp_usr.h"
ST_BOOLEAN copp_bind_called; /* flag to tell if copp_bind was called */
ST_UCHAR only_loc_psel [1+MAX_PSEL_LEN]; /* Local len & PSEL */
/************************************************************************/
/* copp_bind */
/************************************************************************/
ST_RET copp_bind (ST_LONG user_bind_id, PRES_ADDR *pres_addr,
ST_INT sharable, ST_INT max_conns)
{
ST_INT ret = SD_SUCCESS;
COPP_LOG_ENC1 ("P-BIND.req: copp_user_bind_id =0x%08X", user_bind_id);
if (!copp_bind_called)
{
/* Make sure Local PSEL len is legal before copying. */
if (pres_addr->psel_len <= sizeof (only_loc_psel)-1)
{
/* Save Local PSEL (only do memcpy if len != 0). */
if ((only_loc_psel [0] = (ST_UCHAR) pres_addr->psel_len) != 0)
memcpy (&only_loc_psel [1], pres_addr->psel, pres_addr->psel_len);
}
else
{
COPP_LOG_ERR1 ("COPP-ERROR: P-BIND.req: Invalid length=%d of PSEL.",
pres_addr->psel_len);
ret = COPP_ERR_INV_PSEL; /* invalid local PSEL */
}
}
else
{ /* Second Bind. Only allow it if the PSEL is the same. */
if (only_loc_psel [0] != (ST_UCHAR) pres_addr->psel_len ||
(pres_addr->psel_len != 0 &&
memcmp (&only_loc_psel [1], pres_addr->psel, pres_addr->psel_len)))
{
COPP_LOG_ERR0 ("COPP-ERROR: Cannot BIND to different PSEL");
ret = COPP_ERR_INV_PSEL; /* invalid local PSEL */
}
}
/* Call cosp_bind. */
if (ret == SD_SUCCESS)
ret = cosp_bind (user_bind_id, pres_addr, sharable, max_conns);
/* If successful, set called flag. Otherwise, treat next bind like first.*/
if (ret == SD_SUCCESS)
copp_bind_called = SD_TRUE;
return (ret);
}
/************************************************************************/
/* copp_unbind */
/************************************************************************/
ST_RET copp_unbind (ST_LONG copp_bind_id)
{
COPP_LOG_ENC1 ("P-UNBIND.req: copp_bind_id =%9ld", copp_bind_id);
return (cosp_unbind (copp_bind_id));
}
/************************************************************************/
/* copp_con_req */
/************************************************************************/
ST_RET copp_con_req (ST_LONG copp_bind_id, ACSE_CONN *acse_conn, PRES_ADDR *rem_addr)
{
/* WARNING: this hardcoding assumes that ACSE pci always equals 1 */
/* and MMS pci always equals 3 when we send P-CONNECT.req. */
/* These must be set in a_associate_req before any encoding. */
static ST_UCHAR hc_definition_list [] =
{
0x30, 0x0f, 0x02, 0x01, 0x01, 0x06, 0x04, 0x52, 0x01, 0x00, 0x01,
0x30, 0x04, 0x06, 0x02, 0x51, 0x01,
0x30, 0x10, 0x02, 0x01, 0x03, 0x06, 0x05, 0x28, 0xca, 0x22, 0x02, 0x01,
0x30, 0x04, 0x06, 0x02, 0x51, 0x01
};
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
/* DEBUG: should we check the copp_bind_id????? */
COPP_LOG_ENC2 ("P-CONNECT.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
acse_conn->cr = SD_FALSE;
acse_conn->rl = SD_FALSE;
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CP SET */
asn1r_strt_constr (aCtx); /* start enclosed SEQUENCE */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
/* Hardcode Presentation-requirements (kernel only). */
*aCtx->asn1r_field_ptr-- = 0x00;
*aCtx->asn1r_field_ptr-- = 0x06;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x88;
/* 2 P-contexts: ACSE and MMS, and they both have a TSN of ASN1, */
/* so we can hardcode this. */
/* WARNING: this hardcoding assumes that ACSE pci always equals 1 */
/* and MMS pci always equals 3 when we send P-CONNECT.req. */
/* These must be set in a_associate_req before any encoding. */
asn1r_strt_constr (aCtx); /* start P-context-def-list. */
aCtx->asn1r_field_ptr -= sizeof (hc_definition_list);
memcpy (aCtx->asn1r_field_ptr + 1, hc_definition_list, sizeof (hc_definition_list));
asn1r_fin_constr (aCtx, 4,CTX,DEF); /* finish P-context-def-list. */
/* Encode Called-p-selector. */
aCtx->asn1r_field_ptr -= rem_addr->psel_len;
memcpy (aCtx->asn1r_field_ptr + 1, rem_addr->psel, rem_addr->psel_len);
*aCtx->asn1r_field_ptr-- = rem_addr->psel_len;
*aCtx->asn1r_field_ptr-- = 0x82; /* Tag for Called-p-selector */
/* Encode Calling-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x81; /* Tag for Calling-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, 2,CTX,DEF); /* finish enclosed SEQUENCE */
/* Hard-code Mode. Always "normal-mode". */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
*aCtx->asn1r_field_ptr-- = 0x03;
*aCtx->asn1r_field_ptr-- = 0xA0;
asn1r_fin_constr (aCtx, SET_CODE,UNI,DEF); /* finish CPA SET */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_AWAIT_CPA;
/* Pass to COSP. */
return (cosp_con_req (copp_bind_id, rem_addr, acse_conn));
}
/************************************************************************/
/* copp_rel_req */
/************************************************************************/
ST_RET copp_rel_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-RELEASE.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-RELEASE.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Set release collision flags. */
if (acse_conn->rl)
acse_conn->cr = SD_TRUE;
acse_conn->rl = SD_TRUE;
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
return (cosp_rel_req (acse_conn));
}
/************************************************************************/
/* copp_con_rsp_pos */
/* Encode and send CPA PPDU. */
/************************************************************************/
ST_RET copp_con_rsp_pos (ACSE_CONN *acse_conn)
{
static ST_UCHAR hc_result_list [] =
{
0x30, 0x07, 0x80, 0x01, 0x00, 0x81, 0x02, 0x51, 0x01,
0x30, 0x07, 0x80, 0x01, 0x00, 0x81, 0x02, 0x51, 0x01
};
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-CONNECT.rsp+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_AWAIT_CON_RSP)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.rsp+ (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CPA SET */
asn1r_strt_constr (aCtx); /* start enclosed SEQUENCE */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
/* Hardcode Presentation-requirements (kernel only). */
*aCtx->asn1r_field_ptr-- = 0x00;
*aCtx->asn1r_field_ptr-- = 0x06;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x88;
/* Hey, I like this. We only accept connections if there are */
/* 2 P-contexts: ACSE and MMS, and they both have a TSN of ASN1, */
/* so we can hardcode this. */
asn1r_strt_constr (aCtx); /* start P-context-def-result-list. */
aCtx->asn1r_field_ptr -= sizeof (hc_result_list);
memcpy (aCtx->asn1r_field_ptr + 1, hc_result_list, sizeof (hc_result_list));
asn1r_fin_constr (aCtx, 5,CTX,DEF); /* finish P-context-def-result-list. */
/* Encode Responding-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x83; /* Tag for Responding-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, 2,CTX,DEF); /* finish enclosed SEQUENCE */
/* Hard-code Mode. Always "normal-mode". */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
*aCtx->asn1r_field_ptr-- = 0x03;
*aCtx->asn1r_field_ptr-- = 0xA0;
asn1r_fin_constr (aCtx, SET_CODE,UNI,DEF); /* finish CPA SET */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_CONNECTED;
/* Pass to COSP. */
return (cosp_con_rsp_pos (acse_conn));
}
/************************************************************************/
/* copp_con_rsp_neg */
/* Encode and send CPR PPDU. */
/* If "provider_reason" < 0, this is "user-reject", else this is */
/* "provider-reject" and the value of "provider_reason" will be */
/* encoded in the "Provider-reason" parameter of the PPDU. */
/************************************************************************/
ST_RET copp_con_rsp_neg (ACSE_CONN *acse_conn, ST_INT provider_reason)
{
ST_INT j;
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC3 ("P-CONNECT.rsp-: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d",
acse_conn, acse_conn->user_conn_id, provider_reason);
if (provider_reason < 0)
{ /* user-reject: must have User-data */
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
}
if (provider_reason < 0 && acse_conn->copp_state != COPP_STATE_AWAIT_CON_RSP)
{ /* If from user, must be in "await P-CONrsp" state. */
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-CONNECT.rsp- (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start CPR SEQUENCE */
if (provider_reason < 0)
{ /* user-reject: encode P-User-data */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
} /* end "if (provider_reason < 0)" */
if (provider_reason >= 0)
{ /* provider-reject: encode Provider-reason */
asn1r_wr_i8 (aCtx, (ST_INT8) provider_reason); /* Provider-reason */
asn1r_fin_prim (aCtx, 10,CTX);
}
if (provider_reason == PROV_REASON_DEFAULT_CONTEXT)
{ /* Hardcode "Default-context-result = 2" (provider rejection) */
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x87;
}
/* If P-contexts proposed, just accept all of them. */
/* We're rejecting the connect anyway, so it doesn't matter. */
if (acse_conn->num_ctxt)
{
asn1r_strt_constr (aCtx); /* start P-context-def-result-list. */
for (j = 0; j < acse_conn->num_ctxt; j++)
{
asn1r_strt_constr (aCtx); /* start SEQUENCE */
/* DEBUG: would be better to encode same TSN they sent. */
*aCtx->asn1r_field_ptr-- = 0x01; /* Hardcode Transfer-syntax-name = ASN.1*/
*aCtx->asn1r_field_ptr-- = 0x51;
*aCtx->asn1r_field_ptr-- = 0x02;
*aCtx->asn1r_field_ptr-- = 0x81;
*aCtx->asn1r_field_ptr-- = 0x00; /* Hardcode "Result=0" (acceptance) */
*aCtx->asn1r_field_ptr-- = 0x01;
*aCtx->asn1r_field_ptr-- = 0x80;
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
}
asn1r_fin_constr (aCtx, 5,CTX,DEF); /* finish P-context-def-result-list. */
}
/* Encode Responding-p-selector. */
aCtx->asn1r_field_ptr -= (only_loc_psel[0]+1);
memcpy (aCtx->asn1r_field_ptr + 1, only_loc_psel, only_loc_psel[0]+1);
*aCtx->asn1r_field_ptr-- = 0x83; /* Tag for Responding-p-selector */
/* Protocol-version defaults to version-1, so don't encode. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish CPR SEQUENCE */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_IDLE;
/* Pass to COSP. */
return (cosp_con_rsp_neg (acse_conn, COSP_CON_RSP_U_IN_UDATA));
}
/************************************************************************/
/* copp_rel_rsp_pos */
/************************************************************************/
ST_RET copp_rel_rsp_pos (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-RELEASE.rsp+: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-RELEASE.rsp+ (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
if (acse_conn->cr)
{
acse_conn->cr = SD_FALSE;
acse_conn->rl = SD_FALSE; /* and stay in COPP_STATE_CONNECTED */
}
else
acse_conn->copp_state = COPP_STATE_IDLE;
return (cosp_rel_rsp_pos (acse_conn));
}
/************************************************************************/
/* copp_u_abort_req */
/************************************************************************/
ST_RET copp_u_abort_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-U-ABORT.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state == COPP_STATE_IDLE)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-U-ABORT.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start ARU */
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start P-context-identifier-list */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_wr_objid (aCtx, asn1_obj_id.comps,
asn1_obj_id.num_comps); /* Transfer syntax name (i.e. ASN1)*/
asn1r_fin_prim (aCtx, OBJ_ID_CODE,UNI);
asn1r_wr_i8 (aCtx, acse_conn->pciacse); /* PCI for ACSE */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish P-context-identifier-list */
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish ARU */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
acse_conn->copp_state = COPP_STATE_IDLE;
return (cosp_u_abort_req (acse_conn));
}
/************************************************************************/
/* copp_data_req */
/************************************************************************/
ST_RET copp_data_req (ACSE_CONN *acse_conn)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC2 ("P-DATA.req: acse_conn_id =0x%08X user_conn_id =%4ld",
acse_conn, acse_conn->user_conn_id);
COPP_LOG_ENCC1 ("User data length: %d", acse_conn->apdu_len);
COPP_LOG_ENCH (acse_conn->apdu_len, acse_conn->apdu_ptr);
if (acse_conn->copp_state != COPP_STATE_CONNECTED)
{
COPP_LOG_ERR1 ("COPP-ERROR: Cannot send P-DATA.req (Illegal state=%d)",
acse_conn->copp_state);
return (COPP_ERR_INV_STATE);
}
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start P-User-data (fully-encoded) */
asn1r_strt_constr (aCtx); /* start SEQUENCE */
asn1r_strt_constr (aCtx); /* start single-ASN1-type */
/* Fake out ACSE encoding. Already encoded into cosp_buf. */
aCtx->asn1r_field_ptr -= acse_conn->apdu_len;
asn1r_fin_constr (aCtx, 0,CTX,DEF); /* finish single-ASN1-type */
asn1r_wr_i8 (aCtx, acse_conn->pcimms); /* PCI for MMS */
asn1r_fin_prim (aCtx, INT_CODE,UNI);
/* Do not encode Transfer syntax name. We know it is ASN1. */
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish SEQUENCE */
asn1r_fin_constr (aCtx, 1,APP,DEF); /* finish P-User-data (fully-encoded) */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
return (cosp_data_req (acse_conn));
}
/************************************************************************/
/* copp_p_abort_req */
/* Encode and send ARP PPDU (i.e. P-P-Abort.req). */
/* This function only called by the COPP-provider (not by COPP-user). */
/* Parameters: */
/* ACSE_CONN *acse_conn Pointer to connection info */
/* ST_INT8 abort_reason Abort-reason to send in ARP */
/* ST_INT8 event_id Event-identifier to send in ARP */
/* If -1, don't send it. */
/************************************************************************/
ST_VOID copp_p_abort_req (ACSE_CONN *acse_conn, ST_INT8 abort_reason, ST_INT8 event_id)
{
ASN1_ENC_CTXT localEncCtx; /* For readability, use "aCtx" to access this.*/
ASN1_ENC_CTXT *aCtx = &localEncCtx;
COPP_LOG_ENC4 ("P-P-ABORT.req: acse_conn_id =0x%08X user_conn_id =%4ld reason =%d event_id =%d",
acse_conn, acse_conn->user_conn_id, (ST_INT) abort_reason, (ST_INT) event_id);
/* Begin encoding request. */
asn1r_strt_asn1_bld (aCtx, cosp_buf, cosp_msgsize);
asn1r_strt_constr (aCtx); /* start ARP SEQUENCE */
if (event_id != -1)
{
asn1r_wr_i8 (aCtx, event_id); /* Event-identifier */
asn1r_fin_prim (aCtx, 1,CTX);
}
asn1r_wr_i8 (aCtx, abort_reason); /* Abort-reason */
asn1r_fin_prim (aCtx, 0,CTX);
asn1r_fin_constr (aCtx, SEQ_CODE,UNI,DEF); /* finish ARP SEQUENCE */
acse_conn->ppdu_ptr = aCtx->asn1r_field_ptr + 1;
acse_conn->ppdu_len = cosp_buf + cosp_msgsize - acse_conn->ppdu_ptr;
/* Pointing to beginning of Session User Information Field now. */
/* Pass ARP to COSP. */
cosp_u_abort_req (acse_conn);
}