/************************************************************************/ /* 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); }