/************************************************************************/ /* SISCO SOFTWARE MODULE HEADER *****************************************/ /************************************************************************/ /* (c) Copyright Systems Integration Specialists Company, Inc., */ /* 1997, All Rights Reserved */ /* */ /* PROPRIETARY AND CONFIDENTIAL */ /* */ /* MODULE NAME : cosp_enc.c */ /* PRODUCT(S) : MOSI Stack (over TP4) */ /* */ /* MODULE DESCRIPTION : */ /* This file implements the encoding of COSP SPDUs. */ /* */ /* NOTE: Implementation restrictions: */ /* Non-segmenting COSP, */ /* Transport connections are not reused. */ /* */ /* For information see the: */ /* ISO 8326 "Information processing systems - Open Systems */ /* Interconnection - Basic connection oriented session service */ /* definition. */ /* ISO 8327 "Information processing systems - Open Systems */ /* Interconnection - Basic connection oriented session protocol */ /* specification. */ /* ISO 8327/ADD.2 (Draft for Version2). */ /* */ /* */ /* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */ /* */ /* cosp_envelope_len */ /* cosp_enc_cn_ac */ /* cosp_enc_rf */ /* cosp_enc_fn_dn */ /* cosp_enc_ab */ /* cosp_enc_dt */ /* */ /* MODIFICATION LOG : */ /* Date Who Rev Comments */ /* -------- --- ------ ------------------------------------------- */ /* 06/02/04 JRB 10 cosp_enc_dt: do NOT restrict user data len. */ /* 07/16/02 JRB 09 Clean up & fix comments in cosp_enc_cn_ac. */ /* 06/05/02 JRB 08 Send Calling SSEL on connect request. */ /* 09/12/01 JRB 07 Reverse last change (not needed). */ /* 08/01/01 JRB 06 Del rem_addr arg from cosp_enc_cn_ac. */ /* 04/12/00 JRB 05 Lint cleanup. */ /* 09/13/99 MDE 04 Added SD_CONST modifiers */ /* 08/13/98 JRB 03 Lint cleanup. */ /* 05/27/97 JRB 7.00 MMSEASE 7.0 release. */ /* 03/20/97 EJV 02 Enhanced logging. */ /* 01/17/97 EJV 01 Created */ /************************************************************************/ #include "glbtypes.h" #include "sysincs.h" #ifdef DEBUG_SISCO SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__; /* Define for SLOG mechanism */ #endif #include "acse2.h" #include "cosp_log.h" #include "cosp.h" #include "cosp_usr.h" /*----------------------------------------------*/ /* Fixed encoding for CONNECT / ACCEPT SPDU: */ /* Connect/Accept PGI: */ /* - extended concatination not supported, */ /* - COSP Version2 supported */ /* Session User Requirements PI: */ /* - duplex functional unit (FU) supported */ /*----------------------------------------------*/ static ST_UCHAR cosp_cn_ac_fixed [12] = { 5, /* CN-AC PGI code */ 6, /* CN-AC PGI len */ /* Protocol Option PI: */ 19, /* PI code */ 1, /* PI len */ 0, /* 0 if rcv extended concatinat. not supported*/ /* Version Number PI: */ 22, /* PI code */ 1, /* PI len */ COSP_VER2, /* we supporting Version2 */ /* Session User Requirements PI: */ 20, /* PI code */ 2, /* PI len */ 0, /* bits 9-16 are 0 */ 2}; /* bits 1-8 (only bit2=1 duplex FU supported) */ /*----------------------------------------------*/ /* Fixed encoding for REFUSE SPDU: */ /* Session User Requirements PI: */ /* - duplex functional unit (FU) supported */ /* COSP Version PI: */ /* - Version2 supported */ /*----------------------------------------------*/ static ST_UCHAR cosp_rf_fixed [7] = { /* Session User Requirements PI: */ 20, /* PI code */ 2, /* PI len */ 0, /* bits 9-16 are 0 */ 2, /* bits 1-8 (only bit2=1 duplex FU supported) */ /* Version Number PI: */ 22, /* PI code */ 1, /* PI len */ COSP_VER2}; /* we supporting Version2 */ static ST_UINT cosp_enc_len (ST_UINT16 len, ST_UCHAR *buf); /************************************************************************/ /* cosp_envelope_len */ /*----------------------------------------------------------------------*/ /* Function to compute the number of envelope bytes needed to encode */ /* a SPDU. The returned length does not include the SS-user data length.*/ /* */ /* Parameters: */ /* ACSE_CONN *con Connection info parameters */ /* ST_UINT rem_ssel_len Remote SSEL length */ /* ST_UCHAR spdu_type One of COSP_SI_... from cosp.h */ /* */ /* Return: */ /* ST_UINT Length of SPDU envelope encoding */ /************************************************************************/ ST_UINT cosp_envelope_len (ACSE_CONN *con, ST_UINT rem_ssel_len, ST_UCHAR spdu_type) { ST_UINT enc_len; ST_UINT udata_len; udata_len = con->ppdu_len; enc_len = 0; switch (spdu_type) { case COSP_SI_CONNECT: enc_len = 2+6 /* Connect/Accept PGI */ + 2+2 /* Ses User Requirem. PI*/ + (cosp_only_ssel[0] != 0 ? 2+cosp_only_ssel[0] : 0)/* Calling SSEL*/ + (rem_ssel_len != 0 ? 2+rem_ssel_len : 0)/* Called SSEL */ + (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */ + (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */ break; case COSP_SI_ACCEPT: enc_len = 2+6 /* Connect/Accept PGI */ + 2+2 /* Ses User Requirem. PI*/ + (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */ + (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */ break; case COSP_SI_REFUSE: enc_len = 2+2 /* Ses User Requirem. PI*/ + 2+1 /* Supported Version PI */ + 2+1 /* 1 PI code, 1 len, 1 Reason Code*/ + (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */ break; case COSP_SI_FINISH: case COSP_SI_DISCON: enc_len = (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */ + (udata_len > 254 ? 2 : 0); /* addl 2 bytes for len */ break; case COSP_SI_ABORT: enc_len = 2+1 /* TP Disconnect PI */ + (udata_len > 0 ? 2 : 0) /* 1 PI code, 1 len */ + (udata_len > 254 ? 2 : 0); /* add 2 bytes for len */ break; case COSP_SI_DATA: /* We send Give Token SPDU concatinated with the DT (basic concatination) */ enc_len = 2; /* (SI=01,LI=0) token functionality not used */ break; default: COSP_LOG_ERR1 ("COSP-ERROR: Encoding: Invalid PDU type = %d", spdu_type); break; } /* add bytes for params len (none in DT) */ if (spdu_type == COSP_SI_DATA) /* in DT we do not send any parameters but we have to send the LI=0 */ enc_len += 1; /* 1 byte for len */ else { /* all udata is encoded in a parameter */ if (enc_len + udata_len > 254) enc_len += 3; /* 3 bytes for len */ else enc_len += 1; /* 1 byte for len */ } /* add byte for SPDU code */ enc_len += 1; return (enc_len); } /************************************************************************/ /* cosp_enc_cn_ac */ /*----------------------------------------------------------------------*/ /* Function to encode a CONNECT or ACCEPT SPDU. */ /* This function assumed that there is enough place in the enc_buf for */ /* the CN or AC SPDU encoding. The function cosp_envelope_len can be */ /* used to compute exact envelope encoding length. */ /* Note that this function assumes that the SS-user data (CP / CPA PPDU)*/ /* has been already copied into the enc_buf in proper position. */ /* */ /* Parameters: */ /* ACSE_CONN *con Connection info parameters */ /* PRES_ADDR *rem_addr Remote Address (needed only for CN) */ /* char **spdu_ptr Pointer where to return pointer to SPDU */ /* ST_UINT *spdu_len Pointer where to return the SPDU len */ /* ST_UCHAR spdu_type COSP_SI_CONNECT or COSP_SI_ACCEPT */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_cn_ac (ACSE_CONN *con, PRES_ADDR *rem_addr, char **spdu_ptr, ST_UINT *spdu_len, ST_UCHAR spdu_type) { ST_UINT envelope_len; ST_UINT udata_len; ST_UINT udata_max_len; ST_UCHAR ssel_len; ST_UCHAR *ssel; ST_UCHAR *enc_buf; ST_UINT enc_len; ST_UINT idx; /*------------------------------------------------------------*/ /* make sure data len is OK (User Data presence is mandatory) */ /*------------------------------------------------------------*/ udata_len = con->ppdu_len; if (rem_addr) envelope_len = cosp_envelope_len (con, rem_addr->ssel_len, spdu_type); else envelope_len = cosp_envelope_len (con, 0, spdu_type); if (spdu_type == COSP_SI_CONNECT) udata_max_len = COSP_MAX_UDATA_CON; else udata_max_len = COSP_MAX_UDATA; /* for ACCEPT SPDU */ if (udata_len == 0 || udata_len > udata_max_len) { COSP_LOG_ERR2 ("COSP-ERROR: Encoding CN/AC: Invalid User Data length=%u (0ppdu_ptr - envelope_len; if (enc_buf < cosp_buf) { COSP_LOG_ERR0 ("COSP-ERROR: Encoding CN/AC: Invalid pointer to Global Encoding Buffer."); return (COSP_ERR_INV_POINTER); } idx = 0; /*--------------------------------------------*/ /* Encode CN or AC code and total SPDU len */ /*--------------------------------------------*/ /* SPDU length to encode does not include 1 byte for SPDU code and */ /* 1 or 3 bytes for total len */ if (envelope_len-2 + udata_len <= 254) enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */ else enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */ enc_buf [idx++] = spdu_type; idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]); /*--------------------------------------------*/ /* no Connection Identifier PGI encoded */ /*--------------------------------------------*/ /*--------------------------------------------*/ /* encode Connect/Accept PGI: */ /* - extended concatination not supported, */ /* - COSP Version2 supported */ /* encode Session User Requirements PI: */ /* - duplex functional unit (FU) supported */ /*--------------------------------------------*/ memcpy (&enc_buf [idx], cosp_cn_ac_fixed, sizeof (cosp_cn_ac_fixed)); idx += sizeof (cosp_cn_ac_fixed); /*----------------------------------------------*/ /* encode Calling SSEL - (CN only) */ /*----------------------------------------------*/ ssel_len = 0; ssel = NULL; /* Just to avoid "uninitialized" warning. */ if (spdu_type == COSP_SI_CONNECT) { /* Calling SSEL - optional (only if needed) */ ssel_len = cosp_only_ssel [0]; ssel = &cosp_only_ssel [1]; } if (ssel_len > 0) { enc_buf [idx++] = 51; /* encode PI code */ enc_buf [idx++] = ssel_len; /* encode PI len */ memcpy (&enc_buf [idx], ssel, (ST_UINT) ssel_len); idx += ssel_len; } /*------------------------------------*/ /* encode Called/Responding SSEL (CN only) */ /*------------------------------------*/ ssel_len = 0; ssel = NULL; /* Just to avoid "uninitialized" warning. */ if (spdu_type == COSP_SI_CONNECT && rem_addr != NULL) { /* Called SSEL - mandatory */ ssel_len = (ST_UCHAR) rem_addr->ssel_len; ssel = (ST_UCHAR *) rem_addr->ssel; } if (ssel_len > 0) { enc_buf [idx++] = 52; /* PI code */ enc_buf [idx++] = ssel_len; /* PI len */ memcpy (&enc_buf [idx], ssel, (ST_UINT) ssel_len); idx += ssel_len; } /*--------------------------------------------------------------------*/ /* encode User Data (length only), SS-user Data should be already */ /* in the enc_buf (in proper position). */ /*--------------------------------------------------------------------*/ if (spdu_type == COSP_SI_CONNECT) { if (udata_len <= 512) enc_buf [idx++] = 193; /* encode PGI code */ else enc_buf [idx++] = 194; /* if 512 < udata_len <= 10240)*/ } else { /* ACCEPT SPDU */ enc_buf [idx++] = 193; /* encode PGI code */ } idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]); /* udata should be already in enc_buf */ /*-----------------------------------------------*/ /* set values to be returned to calling function */ /*-----------------------------------------------*/ *spdu_len = envelope_len + udata_len; *spdu_ptr = (char *) enc_buf; return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_rf */ /*----------------------------------------------------------------------*/ /* Function to encode a REFUSE SPDU. */ /* This function assumed that there is enough place in the enc_buf for */ /* the RF SPDU encoding. The function cosp_envelope_len can be used */ /* to compute exact envelope encoding length. */ /* Note that this function assumes that the SS-user data (refuse reason)*/ /* has been already copied into the enc_buf in proper position. */ /* */ /* Parameters: */ /* ACSE_CONN *con Connection info parameters */ /* charE **spdu_ptr Pointer where to return pointer to SPDU */ /* ST_UINT *spdu_len Pointer where to return the SPDU len */ /* ST_UCHAR reason Reason code for refuse */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_rf (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len, ST_UCHAR reason) { ST_UINT envelope_len; ST_UINT udata_len; ST_UCHAR *enc_buf; ST_UINT enc_len; ST_UINT idx; /*--------------------------------------------*/ /* make sure data len is OK */ /*--------------------------------------------*/ udata_len = con->ppdu_len; envelope_len = cosp_envelope_len (con, 0, COSP_SI_REFUSE); if (udata_len > COSP_MAX_UDATA) { COSP_LOG_ERR2 ("COSP-ERROR: Encoding RF: Invalid User Data length=%u (length<=%u).", udata_len, COSP_MAX_UDATA); return (COSP_ERR_INV_UDATA_LEN); } /* set the pointer to beginning of encoding in the buffer (global buf)*/ enc_buf = con->ppdu_ptr - envelope_len; if (enc_buf < cosp_buf) { COSP_LOG_ERR0 ("COSP-ERROR: Encoding RF: Invalid pointer to Global Encoding Buffer."); return (COSP_ERR_INV_POINTER); } idx = 0; /*------------------------------------*/ /* Encode RF code and total SPDU len */ /*------------------------------------*/ /* SPDU length to encode does not include 1 byte for SPDU code and */ /* 1 or 3 bytes for total len */ if (envelope_len-2 + udata_len <= 254) enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */ else enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */ enc_buf [idx++] = COSP_SI_REFUSE; idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]); /*--------------------------------------------*/ /* no Connection Identifier PGI encoded */ /*--------------------------------------------*/ /*--------------------------------------------*/ /* encode Session User Requirements PI: */ /* - duplex functional unit (FU) supported */ /* encode COSP Version PI: */ /* - Version2 supported */ /*--------------------------------------------*/ memcpy (&enc_buf [idx], cosp_rf_fixed, sizeof (cosp_rf_fixed)); idx += sizeof (cosp_rf_fixed); /*--------------------------------------------------------------------*/ /* encode Reason Code. SS-user Data (if any) should be already in the */ /* enc_buf (in proper position). */ /*--------------------------------------------------------------------*/ enc_buf [idx++] = 50; /* PI code */ idx += cosp_enc_len ((ST_UINT16) (udata_len+1), &enc_buf [idx]); /* len */ enc_buf [idx++] = reason; /* Reason code */ /* udata may follow if reason=COSP_RF_REASON_U_REJECT */ /*-----------------------------------------------*/ /* set values to be returned to calling function */ /*-----------------------------------------------*/ *spdu_len = envelope_len + udata_len; *spdu_ptr = (char *) enc_buf; return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_fn_dn */ /*----------------------------------------------------------------------*/ /* Function to encode a FINISH or DISCONNECT SPDU. */ /* This function assumed that there is enough place in the enc_buf for */ /* the FN or DN SPDU encoding. The function cosp_envelope_len can be */ /* used to compute exact envelope encoding length. */ /* Note that this function assumes that the SS-user data (RLRQ or RLRE */ /* APDU) have been already copied into the enc_buf in proper position. */ /* */ /* Parameters: */ /* ACSE_CONN *con Connection info parameters */ /* char **spdu_ptr Pointer where to return pointer to SPDU */ /* ST_UINT *spdu_len Pointer where to return the SPDU len */ /* ST_UCHAR spdu_type COSP_SI_FINISH or COSP_SI_DISCON */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_fn_dn (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len, ST_UCHAR spdu_type) { ST_UINT envelope_len; ST_UINT udata_len; ST_UCHAR *enc_buf; ST_UINT enc_len; ST_UINT idx; /*------------------------------------------------------------*/ /* make sure data len is OK (User Data mandatory) */ /*------------------------------------------------------------*/ udata_len = con->ppdu_len; envelope_len = cosp_envelope_len (con, 0, spdu_type); if (udata_len == 0 || udata_len > COSP_MAX_UDATA) { COSP_LOG_ERR2 ("COSP-ERROR: Encoding FN/DN: Invalid User Data length=%u (0ppdu_ptr - envelope_len; if (enc_buf < cosp_buf) { COSP_LOG_ERR0 ("COSP-ERROR: Encoding FN/DN: Invalid pointer to Global Encoding Buffer."); return (COSP_ERR_INV_POINTER); } idx = 0; /*------------------------------------------*/ /* Encode FN or DN code and total SPDU len */ /*------------------------------------------*/ /* SPDU length to encode does not include 1 byte for FN or DN code */ /* and 1 or 3 bytes for total len */ if (envelope_len-2 + udata_len <= 254) enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */ else enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */ enc_buf [idx++] = spdu_type; idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]); /*--------------------------------------------------------------------*/ /* encode User Data (length only), SS-user Data should be already in */ /* the enc_buf (in proper position). */ /*--------------------------------------------------------------------*/ enc_buf [idx++] = 193; /* PI code */ idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]); /*-----------------------------------------------*/ /* set values to be returned to calling function */ /*-----------------------------------------------*/ *spdu_len = envelope_len + udata_len; *spdu_ptr = (char *) enc_buf; return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_u_ab */ /*----------------------------------------------------------------------*/ /* Function to encode a SS-user generated ABORT SPDU */ /* This function assumed that there is enough place in the enc_buf for */ /* the AB SPDU encoding. The function cosp_envelope_len can be used */ /* to compute exact envelope encoding length. */ /* Note that this function assumes that the SS-user data (ARP /ATU PPDU)*/ /* has been already copied into the enc_buf in proper position. */ /* */ /* Parameters: */ /* ACSE_CON *con Connection info parameters */ /* char **spdu_ptr Pointer where to return pointer to SPDU */ /* ST_UINT *spdu_len Pointer where to return the SPDU len */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_u_ab (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len) { ST_UINT envelope_len; ST_UINT udata_len; ST_UCHAR *enc_buf; ST_UINT enc_len; ST_UINT idx; /*------------------------------------------------------------*/ /* make sure data len is OK (depending on the reason the User */ /* Data or the Reflect Parameter presence is mandatory) */ /*------------------------------------------------------------*/ udata_len = con->ppdu_len; envelope_len = cosp_envelope_len (con, 0, COSP_SI_ABORT); //envelope_len = cosp_envelope_len (con, 0, COSP_SI_AB_ACCEPT); //renxiaobao2022 mod if (udata_len == 0 || udata_len > COSP_MAX_UDATA) { COSP_LOG_ERR2 ("COSP-ERROR: Encoding U-AB: Invalid User Data length=%u (0ppdu_ptr - envelope_len; if (enc_buf < cosp_buf) { COSP_LOG_ERR0 ("COSP-ERROR: Encoding U-AB: Invalid pointer to Global Encoding Buffer."); return (COSP_ERR_INV_POINTER); } idx = 0; /*------------------------------------*/ /* Encode AB code and total SPDU len */ /*------------------------------------*/ /* SPDU length to encode does not include 1 byte for AB code and */ /* 1 or 3 bytes for total len */ if (envelope_len-2 + udata_len <= 254) enc_len = envelope_len-2 + udata_len; /* len enc on 1 byte */ else enc_len = envelope_len-4 + udata_len; /* len enc on 3 bytes */ enc_buf [idx++] = COSP_SI_ABORT; //enc_buf [idx++] = COSP_SI_AB_ACCEPT;; //renxiaobao2022 mod idx += cosp_enc_len ((ST_UINT16) enc_len, &enc_buf [idx]); /*----------------------------------------------------*/ /* Encode Transport Disonnect PI (release TP conn) */ /*----------------------------------------------------*/ enc_buf [idx++] = 17; /* PI code */ enc_buf [idx++] = 1; /* PI len */ enc_buf [idx++] = COSP_TCONN_RELEASE | COSP_AB_REASON_USER_ABORT; /*--------------------------------------------------------------------*/ /* encode User Data (length only), SS-user Data should be already */ /* in the enc_buf (in proper position). */ /*--------------------------------------------------------------------*/ if (udata_len > 0) { /* encode User Data */ enc_buf [idx++] = 193; /* PGI code */ idx += cosp_enc_len ((ST_UINT16) udata_len, &enc_buf [idx]); /* udata should be already in enc_buf */ } /*-----------------------------------------------*/ /* set values to be returned to calling function */ /*-----------------------------------------------*/ *spdu_len = envelope_len + udata_len; *spdu_ptr = (char *) enc_buf; return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_p_ab */ /*----------------------------------------------------------------------*/ /* Function to encode a SS-provider generated ABORT SPDU */ /* This function assumed that there is enough place in the enc_buf for */ /* the AB SPDU encoding (COSP_P_AB_LEN bytes). */ /* */ /* Parameters: */ /* char *spdu_ptr Pointer to encode buffer for SPDU */ /* ST_INT err_code This value will be passed for AB reason */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_p_ab (char *spdu_ptr, ST_INT err_code) { /*------------------------------------*/ /* Encode AB code and total SPDU len */ /*------------------------------------*/ spdu_ptr [0] = COSP_SI_ABORT; spdu_ptr [1] = 3 + 4; /*----------------------------------------------------*/ /* Encode Transport Disonnect PI (release TP conn) */ /*----------------------------------------------------*/ spdu_ptr [2] = 17; /* PI code */ spdu_ptr [3] = 1; /* PI len */ spdu_ptr [4] = COSP_TCONN_RELEASE | COSP_AB_REASON_PROT_ERROR; /* encode the Reflect Parameter PI */ spdu_ptr [5] = 49; /* PI code */ spdu_ptr [6] = (ST_UCHAR) 2; /* PI len (0-9) */ spdu_ptr [7] = (ST_UCHAR) ((err_code >> 8) & 0x00FF); spdu_ptr [8] = (ST_UCHAR) (err_code & 0x00FF); /* !!! if number of encoded bytes changes make sure that the define */ /* !!! COSP_P_AB_SPDU_LEN is changed accordingly. */ return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_dt */ /*----------------------------------------------------------------------*/ /* Function to encode a DATA SPDU */ /* This function assumed that there is enough place in the enc_buf for */ /* the GIVE-TOKEN ans DT SPDU encoding. */ /* The function cosp_envelope_len can be used to compute exact envelope */ /* encoding length. */ /* Note that this function assumes that the SS-user data have been */ /* already copied into the enc_buf in proper position. */ /* */ /* Parameters: */ /* ACSE_CON *con Connection info parameters */ /* char **spdu_ptr Pointer where to return pointer to SPDU */ /* ST_UINT *spdu_len Pointer where to return the SPDU len */ /* */ /* Return: */ /* SD_SUCCESS (0) if successful */ /* error code otherwise */ /************************************************************************/ ST_RET cosp_enc_dt (ACSE_CONN *con, char **spdu_ptr, ST_UINT *spdu_len) { ST_UINT envelope_len; ST_UINT udata_len; ST_UCHAR *enc_buf; ST_UINT idx; /*------------------------------------------------------------*/ /* make sure data len is OK */ /*------------------------------------------------------------*/ udata_len = con->ppdu_len; envelope_len = cosp_envelope_len (con, 0, COSP_SI_DATA); if (udata_len == 0) { COSP_LOG_ERR2 ("COSP-ERROR: Encoding DT: Invalid User Data length=%u (0ppdu_ptr - envelope_len; if (enc_buf < cosp_buf) { COSP_LOG_ERR0 ("COSP-ERROR: Encoding DT: Invalid pointer to Global Encoding Buffer."); return (COSP_ERR_INV_POINTER); } idx = 0; /*--------------------------------------------*/ /* Encode GIVE-TOKEN code and params len LI=0 */ /*--------------------------------------------*/ enc_buf [idx++] = COSP_SI_GIVE_TOKEN; enc_buf [idx++] = 0; /* no parameters present LI=0 */ /*------------------------------------*/ /* Encode DT code and params len LI=0 */ /*------------------------------------*/ enc_buf [idx++] = COSP_SI_DATA; enc_buf [idx++] = 0; /* no parameters present LI=0 */ /* udata should be already in enc_buf */ /*-----------------------------------------------*/ /* set values to be returned to calling function */ /*-----------------------------------------------*/ *spdu_len = envelope_len + udata_len; *spdu_ptr = (char *) enc_buf; return (SD_SUCCESS); } /************************************************************************/ /* cosp_enc_len */ /*----------------------------------------------------------------------*/ /* Function to encode a parameter's len. If len<=254 then 1 byte */ /* will be used to encode the length. If len>254 then 3 bytes will */ /* be used to encode the length. */ /* */ /* Parameters: */ /* ST_UINT16 len Parameter's length to encode */ /* ST_UCHAR *buf Pointer where to encode the len */ /* */ /* Return: */ /* ST_UINT Number of bytes used in encoding of len */ /************************************************************************/ static ST_UINT cosp_enc_len (ST_UINT16 len, ST_UCHAR *buf) { ST_UINT bytes; if (len <= 254) { buf [0] = (ST_UCHAR) len; bytes = 1; } else { buf [0] = (ST_UCHAR) 0xFF; /* indicates len>254 */ buf [1] = (ST_UCHAR)((len >> 8) & 0x00FF); /* high order byte */ buf [2] = (ST_UCHAR) (len & 0x00FF); /* low order byte */ bytes = 3; } return (bytes); }