/******************************************************************************* * Copyright (c) 1998 Gemplus developpement * * Name : GemCore.c * * Description : GemCore functions. * * * Compiler : Microsoft DDK for Windows 9x, NT * * Host : IBM PC and compatible machines under Windows 32 bits (W9x or WNT). * * Release : 1.00.001 * * Last Modif : 11 feb. 98: V1.00.001 (GPZ) * - start of the development. * ******************************************************************************** * * Warning : * * Remark : * *******************************************************************************/ /*------------------------------------------------------------------------------ Include section: ------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ - ntddk.h: DDK Windows NT general definitons. - ntddser.h: DDK Windows NT serial management definitons. ------------------------------------------------------------------------------*/ #include #include /*------------------------------------------------------------------------------ - string.h for _fmemcpy. - smclib.h: smart card library definitions. - gemcore.h is used to define general macros and values. - gntser.h is used to define general macros and values for serial management. ------------------------------------------------------------------------------*/ #define SMARTCARD_POOL_TAG 'cGCS' #include #include #include "gemcore.h" #include "gioctl09.h" #include "gntser.h" /*------------------------------------------------------------------------------ Constant section: - IBLOCK_PCB (0x00) and IBLOCK_MASK (0xA0) are used to detect the I-Block PCB signature (0x0xxxxxb). - IBLOCK_SEQ_POS indicates the number of left shift to apply to 0000000xb for x to be the sequence bit for a I-Block. - RBLOCK_PCB (0x80) and RBLOCK_MASK (0xEC) are used to detect the R-Block PCB signature (100x00xx). - RBLOCK_SEQ_POS indicates the number of left shift to apply to 0000000xb for x to be the sequence bit for a R-Block. - ERR_OTHER and ERR_EDC are the error bits in a R-Block PCB. - RESYNCH_REQUEST (0xC0) and RESYNCH_RESPONSE (0xE0) are the PCB used in S-Blocks. ------------------------------------------------------------------------------*/ #define IBLOCK_PCB 0x00 #define IBLOCK_MASK 0xA0 #define IBLOCK_SEQ_POS 0x06 #define RBLOCK_PCB 0x80 #define RBLOCK_MASK 0xEC #define RBLOCK_SEQ_POS 0x04 #define ERR_OTHER 0x02 #define ERR_EDC 0x01 #define RESYNCH_REQUEST 0xC0 #define RESYNCH_RESPONSE 0xE0 /*------------------------------------------------------------------------------ Macro section: - HOST2IFD (Handle) returns the NAD byte for message from Host to IFD. - IFD2HOST (Handle) returns the NAD byte awaited in an IFD message. - MK_IBLOCK_PCB (x) builds an I-Block PCB where x is the channel handle. - MK_RBLOCK_PCB (x) builds an R-Block PCB where x is the channel handle. - ISA_IBLOCK_PCB (x) return TRUE if the given parameter is a I-Block PCB. - ISA_RBLOCK_PCB (x) return TRUE if the given parameter is a R-Block PCB. - SEQ_IBLOCK (x) return the state of the sequence bit: 0 or 1. - INC_SEQUENCE (x) increment a sequence bit: 0 -> 1 and 1 -> 0. ------------------------------------------------------------------------------*/ #define HOST2IFD(Handle) ((WORD8) \ ( \ (gtgbp_channel[(Handle)].IFDAdd << 4) \ + gtgbp_channel[(Handle)].HostAdd \ ) \ ) #define IFD2HOST(Handle) ((WORD8) \ ( \ (gtgbp_channel[(Handle)].HostAdd << 4) \ + gtgbp_channel[(Handle)].IFDAdd \ ) \ ) #define MK_IBLOCK_PCB(x) ((WORD8) \ ( \ IBLOCK_PCB \ + (gtgbp_channel[(x)].SSeq << IBLOCK_SEQ_POS) \ ) \ ) #define MK_RBLOCK_PCB(x) ((WORD8) \ ( \ RBLOCK_PCB \ + (gtgbp_channel[(x)].RSeq << RBLOCK_SEQ_POS) \ + gtgbp_channel[(x)].Error \ ) \ ) #define ISA_IBLOCK_PCB(x) (((x) & IBLOCK_MASK) == IBLOCK_PCB) #define ISA_RBLOCK_PCB(x) (((x) & RBLOCK_MASK) == RBLOCK_PCB) #define SEQ_IBLOCK(x) (((x) & (0x01 << IBLOCK_SEQ_POS)) >> IBLOCK_SEQ_POS) #define INC_SEQUENCE(x) (x) = (WORD8)(((x) + 1) % 2) /*------------------------------------------------------------------------------ Types section: - TGTGBP_CHANNEL gathers information about a channel: * UserNb is the number of user for the channel. * HostAdd holds the address identifier for the host in 0..15. * IFDAdd holds the address identifier for the associated IFD in 0..15. * PortCom holds the serial port number * SSeq holds the sequence bit for the next I-Block to send: 0 or 1. * RSeq holds the awaited sequence bit: 0 or 1. * Error gathers the encountered error conditions. ------------------------------------------------------------------------------*/ typedef struct { WORD8 UserNb; WORD8 HostAdd; WORD8 IFDAdd; INT16 PortCom; WORD8 SSeq; WORD8 RSeq; WORD8 Error; } TGTGBP_CHANNEL; /*------------------------------------------------------------------------------ Global variable section (Shared): - gtgbp_channel[MAX_IFD_CHANNEL] is an array of TGTGBP_CHANNEL which memorises the communication parameters for each opened channel. - handle_GBP is a conversion for the logical channel to the GBP channel. ------------------------------------------------------------------------------*/ static TGTGBP_CHANNEL gtgbp_channel[MAX_IFD_CHANNEL] = { {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0} }; static INT16 handle_GBP[MAX_IFD_CHANNEL] = { {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0},{0} }; /******************************************************************************* * INT16 G_DECL G_GBPOpen * ( * const INT16 Handle, * const WORD16 HostAdd, * const WORD16 IFDAdd, * const INT16 PortCom * ) * * Description : * ------------- * This function initialises internal variables for communicating in Gemplus * Block protocol through a serial port. * This function must be called before any other in this module. * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * - HostAdd is the host address. A valid value must be in 0.. 15. The memorised * value is (HostAdd mod 16). * - AFDAdd is the IFD address. A valid value must be in 0.. 15. The memorised * value is (IFDAdd mod 16). * This value should be different from the HostAdd. * - PortCom holds the serial port number * * Out : * ------------- * Nothing. * * Responses : * ------------- * If everything is Ok: * G_OK ( 0). * If an error condition is raised: * - GE_HOST_PARAMETERS (-450) if the given handle is out of the valid range. * Extern var : ------------- Nothing. Global var : ------------- gtgbp_channel is read and the selected channel is eventually updated. *******************************************************************************/ INT16 G_DECL G_GBPOpen ( const INT16 Handle, const WORD16 HostAdd, const WORD16 IFDAdd, const INT16 PortCom ) { /*------------------------------------------------------------------------------ Local Variable: - cptHandleLog holds the counter to scan structure - present indicate if the trio (HostAdd, IFDAdd, PortCom) exist ------------------------------------------------------------------------------*/ INT16 cptHandleLog=0; INT16 present=-1; /*------------------------------------------------------------------------------ The given parameters are controlled: <= Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL): GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: <= Test Handle parameter (0 <= HostAdd < MAX_IFD_CHANNEL): GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((HostAdd <= 0) || (HostAdd >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: <= Test Handle parameter (0 <= IFDAdd < MAX_IFD_CHANNEL): GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((IFDAdd <= 0) || (IFDAdd >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: <= Test Handle parameter (HostAdd!=IFDAdd): GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if (HostAdd == IFDAdd) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: <= Test Handle parameter (0 <= PortCom < HGTSER_MAX_PORT): GE_HOST_PORT ------------------------------------------------------------------------------*/ if ((PortCom < 0) || (PortCom >= HGTSER_MAX_PORT)) { return (GE_HOST_PORT); } /*------------------------------------------------------------------------------ Scan the structure to found an already opened channel for the same PortCom and HostAdd. ------------------------------------------------------------------------------*/ while ((cptHandleLog 0) ) { present = cptHandleLog; } cptHandleLog++; } /*------------------------------------------------------------------------------ If IFDAdd, PortCom, and HostAdd fields exists Increment the user number counter and write in the array handle_GBP the handle of the GBP. <== G_OK ------------------------------------------------------------------------------*/ if (present != -1) { gtgbp_channel[present].UserNb += 1; handle_GBP[Handle] = present; return (G_OK); } /*------------------------------------------------------------------------------ Scan the structure to find the first line free ------------------------------------------------------------------------------*/ cptHandleLog=0; present=-1; while ((cptHandleLog= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ <= Test channel state (UseNbr field different from 0): GE_HOST_PORT_CLOSE ------------------------------------------------------------------------------*/ if (gtgbp_channel[handle_GBP[Handle]].UserNb == 0) { return (GE_HOST_PORT_CLOSE); } /*------------------------------------------------------------------------------ Decrement the gtgbp_channel structure UserNb field. ------------------------------------------------------------------------------*/ gtgbp_channel[handle_GBP[Handle]].UserNb -= 1; /*------------------------------------------------------------------------------ <= G_OK ------------------------------------------------------------------------------*/ return (G_OK); } /******************************************************************************* * INT16 G_DECL G_GBPBuildIBlock * ( * const INT16 Handle, * const WORD16 CmdLen, * const WORD8 G_FAR Cmd[], * WORD16 G_FAR *MsgLen, * WORD8 G_FAR Msg[] * ) * * Description : * ------------- * This function takes a command and builds an Information Gemplus Block * Protocol. * * Remarks : * ------------- * When this command is successful, the send sequence bit is updated for the next * exchange. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * - CmdLen indicates the number of bytes in the Cmd buffer. * This value must be lower than HGTGBP_MAX_DATA (Today 254). * - Cmd holds the command bytes. * - MsgLen indicates the number of available bytes in Msg. * This value must be at least 4 + CmdLen to allow to build the message. * * Out : * ------------- * - MsgLen and Msg are updated with the message length and the message bytes. * * Responses : * ------------- * If everything is Ok: * G_OK ( 0). * If an error condition is raised: * - GE_HI_CMD_LEN (-313) if the CmdLen is greater than HGTGBP_MAX_DATA or * if MsgLen is too small to receive the built message. * - GE_HOST_PORT_CLOSE (-412) if the selected channel has not been opened. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the valid range. * Extern var : ------------- Nothing. Global var : ------------- gtgbp_channel is read. *******************************************************************************/ INT16 G_DECL G_GBPBuildIBlock ( const INT16 Handle, const WORD16 CmdLen, const WORD8 G_FAR Cmd[], WORD16 G_FAR *MsgLen, WORD8 G_FAR Msg[] ) { /*------------------------------------------------------------------------------ Local variable: - edc receives the exclusive or between all the character from to the last data byte. - i is the index which allows to read each Cmd byte. - j is the index which allows to write each Msg byte. It indicates the next free position in this buffer and is initialized to 0. ------------------------------------------------------------------------------*/ WORD8 edc; WORD16 i, j = 0; ASSERT(Cmd != NULL); ASSERT(MsgLen != NULL); ASSERT(Msg != NULL); /*------------------------------------------------------------------------------ The given parameters are controlled: Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ <= Test channel state (UserNb different from 0): GE_HOST_PORT_CLOSE ------------------------------------------------------------------------------*/ if (gtgbp_channel[handle_GBP[Handle]].UserNb == 0) { return (GE_HOST_PORT_CLOSE); } /*------------------------------------------------------------------------------ <= Test CmdLen (<= HGTGBP_MAX_DATA) and MsgLen (>= 4 + CmdLen): GE_HI_CMD_LEN. Msg must be able to receive the following GBP block [ Data ...] ------------------------------------------------------------------------------*/ if ((CmdLen > HGTGBP_MAX_DATA) || (*MsgLen < CmdLen + 4)) { return (GE_HI_CMD_LEN); } /*------------------------------------------------------------------------------ The message is built: NAD holds Target address in high part and Source address in low part. PCB holds I-Block mark: 0 SSeq 0 x x x x x Len is given by CmdLen [.. Data ..] are stored in Cmd. EDC is an exclusive or of all the previous bytes. It is updated when Msg buffer is updated. ------------------------------------------------------------------------------*/ edc = Msg[j++] = HOST2IFD(handle_GBP[Handle]); edc ^= Msg[j++] = MK_IBLOCK_PCB(handle_GBP[Handle]); edc ^= Msg[j++] = (WORD8) CmdLen; for (i = 0; i < CmdLen; i++) { edc ^= Msg[j++] = Cmd[i]; } Msg[j++] = edc; /*------------------------------------------------------------------------------ MsgLen is updated with the number of bytes written in Msg buffer. ------------------------------------------------------------------------------*/ *MsgLen = (WORD16)j; /*------------------------------------------------------------------------------ The sequence number is updated for the next exchange. ------------------------------------------------------------------------------*/ INC_SEQUENCE(gtgbp_channel[handle_GBP[Handle]].SSeq); /*------------------------------------------------------------------------------ <= G_OK ------------------------------------------------------------------------------*/ return (G_OK); } /******************************************************************************* * INT16 G_DECL G_GBPBuildRBlock * ( * const INT16 Handle, * WORD16 G_FAR *MsgLen, * WORD8 G_FAR Msg[] * ) * * Description : * ------------- * This function builds a Repeat Gemplus Block Protocol. * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * - MsgLen indicates the number of available bytes in Msg. * This value must be at least 4 to allow to build the message. * * Out : * ------------- * - MsgLen and Msg are updated with the message length and the message bytes. * * Responses : * ------------- * If everything is Ok: * G_OK ( 0). * If an error condition is raised: * - GE_HI_CMD_LEN (-313) if MsgLen is too small to receive the built * message. * - GE_HOST_PORT_CLOSE (-412) if the selected channel has not been opened. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the valid range. * Extern var : ------------- Nothing. Global var : ------------- gtgbp_channel is read. *******************************************************************************/ INT16 G_DECL G_GBPBuildRBlock ( const INT16 Handle, WORD16 G_FAR *MsgLen, WORD8 G_FAR Msg[] ) { /*------------------------------------------------------------------------------ Local variable: - edc receives the exclusive or between all the character from to the last data byte. - j is the index which allows to write each Msg byte. It indicates the next free position in this buffer and is initialized to 0. ------------------------------------------------------------------------------*/ WORD8 edc; WORD16 j = 0; ASSERT(MsgLen != NULL); ASSERT(Msg != NULL); /*------------------------------------------------------------------------------ The given parameters are controlled: Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ <= Test channel state (UserNb different from 0): GE_HOST_PORT_CLOSE ------------------------------------------------------------------------------*/ if (gtgbp_channel[handle_GBP[Handle]].UserNb == 0) { return (GE_HOST_PORT_CLOSE); } /*------------------------------------------------------------------------------ <= Test MsgLen (>= 4 ): GE_HI_CMD_LEN. Msg must be able to receive the following GBP block <0> ------------------------------------------------------------------------------*/ if (*MsgLen < 4) { return (GE_HI_CMD_LEN); } /*------------------------------------------------------------------------------ The message is built: NAD holds Target address in high part and Source address in low part. PCB holds R-Block mark: 1 0 0 RSeq 0 x x x x x Len is null EDC is an exclusive or of all the previous bytes. It is updated when Msg buffer is updated. ------------------------------------------------------------------------------*/ edc = Msg[j++] = HOST2IFD(handle_GBP[Handle]); edc ^= Msg[j++] = MK_RBLOCK_PCB(handle_GBP[Handle]); edc ^= Msg[j++] = 0; Msg[j++] = edc; /*------------------------------------------------------------------------------ MsgLen is updated with the number of bytes written in Msg buffer. ------------------------------------------------------------------------------*/ *MsgLen = (WORD16)j; /*------------------------------------------------------------------------------ <= G_OK ------------------------------------------------------------------------------*/ return (G_OK); } /******************************************************************************* * INT16 G_DECL G_GBPBuildSBlock * ( * const INT16 Handle, * WORD16 G_FAR *MsgLen, * WORD8 G_FAR Msg[] * ) * * Description : * ------------- * This function builds a Synchro request Gemplus Block Protocol. * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * - MsgLen indicates the number of available bytes in Msg. * This value must be at least 4 to allow to build the message. * * Out : * ------------- * - MsgLen and Msg are updated with the message length and the message bytes. * * Responses : * ------------- * If everything is Ok: * G_OK ( 0). * If an error condition is raised: * - GE_HI_CMD_LEN (-313) if MsgLen is too small to receive the built * message. * - GE_HOST_PORT_CLOSE (-412) if the selected channel has not been opened. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the valid range. * Extern var : ------------- Nothing. Global var : ------------- gtgbp_channel is read. *******************************************************************************/ INT16 G_DECL G_GBPBuildSBlock ( const INT16 Handle, WORD16 G_FAR *MsgLen, WORD8 G_FAR Msg[] ) { /*------------------------------------------------------------------------------ Local variable: - edc receives the exclusive or between all the character from to the last data byte. - j is the index which allows to write each Msg byte. It indicates the next free position in this buffer and is initialized to 0. ------------------------------------------------------------------------------*/ WORD8 edc; WORD16 j = 0; ASSERT(MsgLen != NULL); ASSERT(Msg != NULL); /*------------------------------------------------------------------------------ The given parameters are controlled: Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ <= Test channel state (UserNb different from 0): GE_HOST_PORT_CLOSE ------------------------------------------------------------------------------*/ if (gtgbp_channel[handle_GBP[Handle]].UserNb == 0) { return (GE_HOST_PORT_CLOSE); } /*------------------------------------------------------------------------------ <= Test MsgLen (>= 4 ): GE_HI_CMD_LEN. Msg must be able to receive the following GBP block <0> ------------------------------------------------------------------------------*/ if (*MsgLen < 4) { return (GE_HI_CMD_LEN); } /*------------------------------------------------------------------------------ The message is built: NAD holds Target address in high part and Source address in low part. PCB holds R-Block mark: 1 1 0 0 0 0 0 0 Len is null EDC is an exclusive or of all the previous bytes. It is updated when Msg buffer is updated. ------------------------------------------------------------------------------*/ edc = Msg[j++] = HOST2IFD(handle_GBP[Handle]); edc ^= Msg[j++] = RESYNCH_REQUEST; edc ^= Msg[j++] = 0; Msg[j++] = edc; /*------------------------------------------------------------------------------ MsgLen is updated with the number of bytes written in Msg buffer. ------------------------------------------------------------------------------*/ *MsgLen = (WORD16)j; /*------------------------------------------------------------------------------ <= G_OK ------------------------------------------------------------------------------*/ return (G_OK); } /******************************************************************************* * INT16 G_DECL G_GBPDecodeMessage * ( * const INT16 Handle, * const WORD16 MsgLen, * const WORD8 G_FAR Msg[], * WORD16 G_FAR *RspLen, * WORD8 G_FAR Rsp[] * ) * * Description : * ------------- * This function takes a Gemplus Block Protocol message and extract the response * from it. * * Remarks : * ------------- * The awaited sequence bit is updated when a valid I-Block has been received. * The sequence bits are reseted when a valid RESYNCH RESPONSE has been received. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * - MsgLen indicates the number of bytes in the Msg buffer. * - Msg holds the command bytes. * - RspLen indicates the number of available bytes in Msg. * * Out : * ------------- * - RspLen and Rsp are updated with the response length and the response bytes. * * Responses : * ------------- * If everything is Ok: * G_OK (0). * If an error condition is raised: * - GE_HI_LRC (-302) if an EDC error has been detected. * - GE_HI_LEN (-311) if a bad value has been detected in LN field * or if the response buffer is too small. * - GE_HI_FORMAT (-312) if the received message is neither I-Block, * neither R-Block and neither S-Block. * - GE_HI_NACK (-314) if a R-Block has been received. * - GE_HI_RESYNCH (-315) if a S-Block has been received. * - GE_HI_ADDRESS (-316) if the NAD is not valid for the selected channel. * - GE_HI_SEQUENCE (-317) if a bad sequence number has been received. * - GE_HOST_PORT_CLOSE (-412) if the selected channel has not been opened. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the valid range. * Extern var : ------------- Nothing. Global var : ------------- gtgbp_channel is read and the selected channel is eventually updated. *******************************************************************************/ INT16 G_DECL G_GBPDecodeMessage ( const INT16 Handle, const WORD16 MsgLen, const WORD8 G_FAR Msg[], WORD16 G_FAR *RspLen, WORD8 G_FAR Rsp[] ) { /*------------------------------------------------------------------------------ Local variables: - edc receives the exclusive or between all the character from to the last data byte. - j will point on next free byte in Rsp. - response is updated with the function status. ------------------------------------------------------------------------------*/ WORD8 edc; WORD16 j; INT16 response; ASSERT(Msg != NULL); ASSERT(RspLen != NULL); ASSERT(Rsp != NULL); /*------------------------------------------------------------------------------ The given parameters are controlled: Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { *RspLen =0; return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { *RspLen =0; return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ <= Test channel state (UserNb different from 0): GE_HOST_PORT_CLOSE ------------------------------------------------------------------------------*/ if (gtgbp_channel[handle_GBP[Handle]].UserNb == 0) { *RspLen =0; return (GE_HOST_PORT_CLOSE); } /*------------------------------------------------------------------------------ Reset the associated error field. ------------------------------------------------------------------------------*/ gtgbp_channel[handle_GBP[Handle]].Error = 0; /*------------------------------------------------------------------------------ Verifies the message frame and copies the data bytes: <= Test NAD (HostAdd | IFDAdd): GE_HI_ADDRESS ------------------------------------------------------------------------------*/ if (Msg[0] != IFD2HOST(handle_GBP[Handle])) { *RspLen =0; return (GE_HI_ADDRESS); } edc = Msg[0]; /*------------------------------------------------------------------------------ Updates response variable with the PCB type: - GE_HI_RESYNCH if a S-Block has been detected - GE_HI_NACK if a T-Block has been detected ------------------------------------------------------------------------------*/ if (Msg[1] == RESYNCH_RESPONSE) { response = GE_HI_RESYNCH; } else if (ISA_RBLOCK_PCB(Msg[1])) { response = GE_HI_NACK; } /*------------------------------------------------------------------------------ - For I-Block <= Test PCB sequence bit: GE_HI_SEQUENCE ------------------------------------------------------------------------------*/ else if (ISA_IBLOCK_PCB(Msg[1])) { if ( (WORD8) SEQ_IBLOCK(Msg[1]) != gtgbp_channel[handle_GBP[Handle]].RSeq) { return (GE_HI_SEQUENCE); } response = G_OK; } /*------------------------------------------------------------------------------ - For other cases <= GE_HI_FORMAT ------------------------------------------------------------------------------*/ else { return(GE_HI_FORMAT); } edc ^= Msg[1]; /*------------------------------------------------------------------------------ <= Test Len (Len + 4 = MsgLen and RspLen >= Len): GE_HI_LEN This error update the Error.other bit. ------------------------------------------------------------------------------*/ if (((WORD16)Msg[2] > *RspLen) || ((WORD16)(Msg[2] + 4) != MsgLen)) { *RspLen =0; gtgbp_channel[handle_GBP[Handle]].Error |= ERR_OTHER; return (GE_HI_LEN); } edc ^= Msg[2]; /*------------------------------------------------------------------------------ Copies the data bytes, updates RspLen and calculated edc. ------------------------------------------------------------------------------*/ *RspLen = (WORD16)Msg[2]; for (j = 0; j < *RspLen; j++) { Rsp[j] = Msg[j + 3]; edc ^= Rsp[j]; } /*------------------------------------------------------------------------------ <= Test the read EDC: GE_HI_LRC This error update the Error.EDC bit. ------------------------------------------------------------------------------*/ if (edc != Msg[j + 3]) { *RspLen = 0; gtgbp_channel[handle_GBP[Handle]].Error |= ERR_EDC; return (GE_HI_LRC); } /*------------------------------------------------------------------------------ Updates the awaited sequence bit when a valid I-Block has been received. ------------------------------------------------------------------------------*/ if (response == G_OK) { INC_SEQUENCE(gtgbp_channel[handle_GBP[Handle]].RSeq); } /*------------------------------------------------------------------------------ Reset the sequence bits when a valid S-Block has been received. ------------------------------------------------------------------------------*/ else if (response == GE_HI_RESYNCH) { gtgbp_channel[handle_GBP[Handle]].SSeq = gtgbp_channel[handle_GBP[Handle]].RSeq = 0; } /*------------------------------------------------------------------------------ <= GE_HI_RESYNCH / GE_HI_NACK / G_OK ------------------------------------------------------------------------------*/ return (response); } /******************************************************************************* * INT16 G_DECL G_GBPChannelToPortComm * ( * const INT16 Handle * ) * * Description : * ------------- * This function return a physical port associate with the Logical Channel * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Handle holds the communication handle to associate to the channel. * * Out : * ------------- * Nothing. * * Responses : * ------------- Extern var : ------------- Nothing. Global var : ------------- Nothing. *******************************************************************************/ INT16 G_DECL G_GBPChannelToPortComm ( const INT16 Handle ) { /*------------------------------------------------------------------------------ The given parameters are controlled: Test Handle parameter (0 <= Handle < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((Handle < 0) || (Handle >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } /*------------------------------------------------------------------------------ The given parameters are controlled: Test handle_GBP[Handle] parameter (0 <= IFDAdd < MAX_IFD_CHANNEL) <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ if ((handle_GBP[Handle] < 0) || (handle_GBP[Handle] >= MAX_IFD_CHANNEL)) { return (GE_HOST_PARAMETERS); } return(gtgbp_channel[handle_GBP[Handle]].PortCom); } /******************************************************************************* * NTSTATUS GDDK_Translate * ( * const INT16 Status, * const ULONG IoctlType * ) * * Description : * ------------- * Translate GemError codes in NT status. * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Status is the value to translate. * - IoctlType is the current smart card ioctl. * * Out : * ------------- * Nothing. * * Responses : * ------------- * A NT status code. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ NTSTATUS GDDK_Translate ( const INT16 Status, const ULONG IoctlType ) { switch (Status) { case G_OK: return STATUS_SUCCESS; case GE_ICC_ABSENT: return STATUS_NO_MEDIA; case GE_ICC_MUTE: if (IoctlType == RDF_CARD_POWER) { return STATUS_UNRECOGNIZED_MEDIA;} else { return STATUS_IO_TIMEOUT; } case GE_ICC_UNKNOWN: return STATUS_UNRECOGNIZED_MEDIA; case GE_ICC_PULL_OUT: return STATUS_NO_MEDIA; case GE_ICC_NOT_POWER: return STATUS_UNRECOGNIZED_MEDIA; case GE_ICC_INCOMP: return STATUS_UNRECOGNIZED_MEDIA; case GE_ICC_ABORT: return STATUS_REQUEST_ABORTED; case GE_II_COMM: return STATUS_CONNECTION_ABORTED; case GE_II_PARITY: return STATUS_PARITY_ERROR; case GE_II_EDC: return STATUS_CRC_ERROR; case GE_II_ATR: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_ATR_TS: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_ATR_TCK: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_ATR_READ: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_PROTOCOL: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_UNKNOWN: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_PTS: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_IFSD_LEN: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_PROC_BYTE: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_INS: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_RES_LEN: return STATUS_UNRECOGNIZED_MEDIA; case GE_II_RESYNCH: return STATUS_UNRECOGNIZED_MEDIA; case GE_IFD_ABSENT: return STATUS_DEVICE_NOT_CONNECTED; case GE_IFD_MUTE: return STATUS_INVALID_DEVICE_STATE; case GE_IFD_UNKNOWN: return STATUS_NO_SUCH_DEVICE; case GE_IFD_BUSY: return STATUS_DEVICE_BUSY; case GE_IFD_FN_PROG: return STATUS_IO_DEVICE_ERROR; case GE_IFD_FN_UNKNOWN: return STATUS_IO_DEVICE_ERROR; case GE_IFD_FN_FORMAT: return STATUS_IO_DEVICE_ERROR; case GE_IFD_FN_DEF: return STATUS_IO_DEVICE_ERROR; case GE_IFD_FN_FAIL: return STATUS_IO_DEVICE_ERROR; case GE_IFD_MEM_PB: return STATUS_IO_DEVICE_ERROR; case GE_IFD_MEM_ACCESS: return STATUS_IO_DEVICE_ERROR; case GE_IFD_MEM_ACTIVATION: return STATUS_IO_DEVICE_ERROR; case GE_IFD_ABORT: return STATUS_IO_DEVICE_ERROR; case GE_IFD_RESYNCH: return STATUS_IO_DEVICE_ERROR; case GE_IFD_TIMEOUT: return STATUS_IO_TIMEOUT; case GE_IFD_OVERSTRIKED: return STATUS_IO_DEVICE_ERROR; case GE_HI_COMM: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_PARITY: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_LRC: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_PROTOCOL: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_LEN: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_FORMAT: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_CMD_LEN: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_NACK: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_RESYNCH: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_ADDRESS: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HI_SEQUENCE: return STATUS_DEVICE_PROTOCOL_ERROR; case GE_HOST_PORT: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_ABS: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_INIT: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_BUSY: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_BREAK: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_LOCKED: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_OS: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_OPEN: return STATUS_PORT_DISCONNECTED; case GE_HOST_PORT_CLOSE: return STATUS_PORT_DISCONNECTED; case GE_HOST_MEMORY: return STATUS_NO_MEMORY; case GE_HOST_POINTER: return RPC_NT_NULL_REF_POINTER; case GE_HOST_BUFFER_SIZE: return STATUS_INVALID_BUFFER_SIZE; case GE_HOST_RESOURCES: return STATUS_INSUFFICIENT_RESOURCES; case GE_HOST_USERCANCEL: return STATUS_CANCELLED; case GE_HOST_PARAMETERS: return STATUS_INVALID_PARAMETER; case GE_HOST_DLL_ABS: return STATUS_IO_DEVICE_ERROR; case GE_HOST_DLL_FN_ABS: return STATUS_IO_DEVICE_ERROR; case GE_APDU_CHAN_OPEN: return STATUS_DEVICE_ALREADY_ATTACHED; case GE_APDU_CHAN_CLOSE: return STATUS_ALREADY_DISCONNECTED; case GE_APDU_SESS_CLOSE: return STATUS_IO_DEVICE_ERROR; case GE_APDU_SESS_SWITCH: return STATUS_IO_DEVICE_ERROR; case GE_APDU_LEN_MAX: return STATUS_IO_DEVICE_ERROR; case GE_APDU_LE: return STATUS_INFO_LENGTH_MISMATCH; case GE_APDU_RECEIV: return STATUS_INFO_LENGTH_MISMATCH; case GE_APDU_IFDMOD_ABS: return STATUS_NO_SUCH_DEVICE; case GE_APDU_IFDMOD_FN_ABS: return STATUS_IO_DEVICE_ERROR; case GE_TLV_WRONG: return STATUS_IO_DEVICE_ERROR; case GE_TLV_SIZE: return STATUS_IO_DEVICE_ERROR; case GE_TLV_NO_ACTION: return STATUS_IO_DEVICE_ERROR; case GE_FILE_OPEN: return STATUS_OPEN_FAILED; case GE_FILE_CLOSE: return STATUS_FILE_CLOSED; case GE_FILE_WRITE: return STATUS_IO_DEVICE_ERROR; case GE_FILE_READ: return STATUS_IO_DEVICE_ERROR; case GE_FILE_FORMAT: return STATUS_FILE_INVALID; case GE_FILE_HEADER: return STATUS_FILE_INVALID; case GE_FILE_QUOT_MARK: return STATUS_IO_DEVICE_ERROR; case GE_FILE_END: return STATUS_IO_DEVICE_ERROR; case GE_FILE_CRC: return STATUS_IO_DEVICE_ERROR; case GE_FILE_VERSION: return STATUS_IO_DEVICE_ERROR; case GE_FILE_CONFIG: return STATUS_IO_DEVICE_ERROR; case GE_SYS_WAIT_FAILED: return STATUS_CANT_WAIT; case GE_SYS_SEMAP_RELEASE: return STATUS_CANT_WAIT; case GW_ATR: return STATUS_SUCCESS; case GW_APDU_LEN_MAX: return STATUS_SUCCESS; case GW_APDU_LE: return STATUS_SUCCESS; case GW_HI_NO_EOM: return STATUS_SUCCESS; default: return STATUS_IO_DEVICE_ERROR; } } /******************************************************************************* * WORD32 G_DECL G_EndTime(const WORD32 Timing) * * Description : * ------------- * This function returns a value to test with G_CurrentTime function to check if * the Timing has been overlapped. * * Remarks : * ------------- * Nothing. * * In : * ------------- * - Timing is a value in milli-seconds which indicates the available time for * an operation. * * Out : * ------------- * Nothing. * * Responses : * ------------- * The response is the value which will be returned by G_CurrentTime when Timing * milli-seconds will be passed. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ WORD32 G_DECL G_EndTime(const WORD32 Timing) { TIME CurrentTime; KeQuerySystemTime(&CurrentTime); return ((WORD32)((CurrentTime.u.LowPart/(10*1000))) + Timing); } /******************************************************************************* * WORD32 G_DECL G_CurrentTime(void) * * Description : * ------------- * This function returns the current time according to an internal unit. This * function has to be used with G_EndTime. * * Remarks : * ------------- * Nothing. * * In : * ------------- * Nothing. * * Out : * ------------- * Nothing. * * Responses : * ------------- * The response is the current timing according to an internal unit. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ WORD32 G_DECL G_CurrentTime(void) { LARGE_INTEGER CurrentTime; KeQuerySystemTime(&CurrentTime); return ((WORD32)(CurrentTime.u.LowPart/(10*1000))); } /******************************************************************************* * INT16 GE_Translate(const BYTE IFDStatus) * * Description : * ------------- * Translate IFD status in GemError codes. * * Remarks : * ------------- * Nothing. * * In : * ------------- * IFDStatus is the value to translate. * * Out : * ------------- * Nothing. * * Responses : * ------------- * A GemError.h code. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ INT16 G_DECL GE_Translate(const BYTE IFDStatus) { switch (IFDStatus) { case 0x00 : return G_OK; case 0x01 : return GE_IFD_FN_UNKNOWN; case 0x02 : return GE_IFD_FN_UNKNOWN; case 0x03 : return GE_IFD_FN_FORMAT; case 0x04 : return GE_IFD_TIMEOUT; case 0x05 : return GE_HI_CMD_LEN; case 0x09 : return GE_HI_FORMAT; case 0x10 : return GE_II_ATR_TS; case 0x11 : return GE_II_INS; case 0x12 : return GE_HI_CMD_LEN; case 0x13 : return GE_II_COMM; case 0x14 : return GE_ICC_UNKNOWN; case 0x15 : return GE_ICC_NOT_POWER; case 0x16 : return GE_IFD_FN_PROG; case 0x17 : return GE_II_PROTOCOL; case 0x18 : return GE_II_PROTOCOL; case 0x19 : return GE_IFD_FN_DEF; case 0x1A : return GE_HI_LEN; case 0x1B : return GE_IFD_FN_FORMAT; case 0x1C : return GE_IFD_FN_DEF; case 0x1D : return GE_II_ATR_TCK; case 0x1E : return GE_IFD_FN_DEF; case 0x1F : return GE_IFD_FN_DEF; case 0x20 : return GE_IFD_FN_UNKNOWN; case 0x30 : return GE_IFD_TIMEOUT; case 0xA0 : return GW_ATR; case 0xA1 : return GE_II_PROTOCOL; case 0xA2 : return GE_ICC_MUTE; case 0xA3 : return GE_II_PARITY; case 0xA4 : return GE_ICC_ABORT; case 0xA5 : return GE_IFD_ABORT; case 0xA6 : return GE_IFD_RESYNCH; case 0xA7 : return GE_II_PTS; case 0xCF : return GE_IFD_OVERSTRIKED; case 0xE4 : return GE_II_PROC_BYTE; case 0xE5 : return GW_APDU_LE; case 0xE7 : return G_OK; case 0xF7 : return GE_ICC_PULL_OUT; case 0xF8 : return GE_ICC_INCOMP; case 0xFB : return GE_ICC_ABSENT; default : return ((INT16) (GE_UNKNOWN_PB - IFDStatus)); }; } /******************************************************************************* * INT16 G_DECL G_Oros3SIOConfigure * ( * const INT16 Handle, * const WORD32 Timeout, * const INT16 Parity, * const INT16 ByteSize, * const WORD32 BaudRate * WORD16 G_FAR *RspLen, * WORD8 G_FAR Rsp[] * ) * * Description : * ------------- * This command sets the SIO line parity, baud rate and number of bits per * character. * * Remarks : * ------------- * After a reset, the line defaults is no parity, 8 bits per character and 9600 * bauds. * This command must be sent 2 times because: * - when the IFD receive the command, it switch immediatly and sends its * response according to the new parameters. Host cannot receive this * response. * - the second call change nothing, so the host receive the response. * * In : * ------------- * - Handle is the handle returned by the communication layer. * - Timout is the time, in ms, for IFD to send its response. * - Parity can hold 0 for no parity or 2 for even parity. * - ByteSize can hold 7 or 8 bits per character. * - BaudRate can hold 1200, 2400, 4800, 9600, 19200, 38400 or 76800. This last * value is not allowed on PC. * - RespLen holds the available place in RespBuff. The needed value is 1 byte. * * Out : * ------------- * - RespLen holds the number of updated bytes in RespBuff. This value is lower * of equal to the value given in entry. * OROS 3.x IFD return 1 byte to this command. * - RespBuff holds RespLen read bytes. The response has the following format: * * * Responses : * ------------- * If everything is OK: * - G_OK ( 0). * If an error condition is raised: * - GE_IFD_MUTE (-201) if a character/command timeout is detected. * - GE_HI_COMM (-300) if a communication error occurs. * - GE_HI_PARITY (-301) if a parity error is encountered. * - GE_HI_LRC (-302) if an EDC error has been detected. * - GE_HI_PROTOCOL (-310) if a frame error is encountered. * - GE_HI_LEN (-311) if a bad value has been detected in LN field * or if the response buffer is too small. * - GE_HI_FORMAT (-312) if the received message is neither I-Block, * neither R-Block and neither S-Block. * - GE_HI_CMD_LEN (-313) if the CmdLen is greater than HGTGBP_MAX_DATA or * if MsgLen is too small to receive the built message. * - GE_HI_NACK (-314) if a R-Block has been received. * - GE_HI_RESYNCH (-315) if a S-Block has been received. * - GE_HI_ADDRESS (-316) if the NAD is not valid for the selected channel. * - GE_HI_SEQUENCE (-317) if a bad sequence number has been received. * - GE_HOST_PORT_BREAK (-404) if the bytes cannot be sent. * - GE_HOST_PORT_CLOSE (-412) if port is closed. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ INT16 G_DECL G_Oros3SIOConfigure ( const INT16 Handle, const WORD32 Timeout, const INT16 Parity, const INT16 ByteSize, const WORD32 BaudRate, WORD16 G_FAR *RspLen, WORD8 G_FAR Rsp[] ) { /*------------------------------------------------------------------------------ Local variables: - cmd holds the configure SIO line command whose format is <0Ah> XXXXXXXXb |||||\-/ codes the selected baud rate according to |||||000 RFU |||||001 76800 |||||010 38400 |||||011 19200 |||||100 9600 |||||101 4800 |||||110 2400 |||||111 1200 ||||---- codes the character size according to ||||0 for 8 bits per character ||||1 for 7 bits per character |||----- codes the parity according to |||0 for no parity |||1 for even parity \-/ are not used. ------------------------------------------------------------------------------*/ WORD8 cmd[2] = { HOR3GLL_IFD_CMD_SIO_SET }; ASSERT(RspLen != NULL); ASSERT(Rsp != NULL); /*------------------------------------------------------------------------------ The configuration byte is set with the given parameters: Switch the BaudRate value, the corresponding code initializes cmd[1]. default case returns the following error: <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ switch (BaudRate) { case 76800lu: { cmd[1] = 0x01; break; } case 38400lu: { cmd[1] = 0x02; break; } case 19200lu: { cmd[1] = 0x03; break; } case 9600lu: { cmd[1] = 0x04; break; } case 4800lu: { cmd[1] = 0x05; break; } case 2400lu: { cmd[1] = 0x06; break; } case 1200lu: { cmd[1] = 0x07; break; } default : { return (GE_HOST_PARAMETERS); } } /*------------------------------------------------------------------------------ Switch the ByteSize value, the corresponding code is added to cmd[1]. default case returns the following error: <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ switch (ByteSize) { case 8 : { break; } case 7 : { cmd[1] += 0x08; break; } default: { return (GE_HOST_PARAMETERS); } } /*------------------------------------------------------------------------------ Switch the Parity value, the corresponding code is added to cmd[1]. default case returns the following error: <= GE_HOST_PARAMETERS ------------------------------------------------------------------------------*/ switch (Parity) { case 0 : { break; } case 2: { cmd[1] += 0x10; break; } default: { return (GE_HOST_PARAMETERS); } } /*------------------------------------------------------------------------------ The command is sent to IFD. <= G_Oros3Exchange status. ------------------------------------------------------------------------------*/ return (G_Oros3Exchange(Handle,Timeout,2,cmd,RspLen,Rsp)); } /******************************************************************************* * INT16 G_DECL G_Oros3SetMode * ( * const INT16 Handle, * const WORD32 Timeout, * const WORD16 Option, * WORD16 G_FAR *RespLen, * BYTE G_FAR RespBuff[] * ) * * Description : * ------------- * This command enables you to disable ROS command compatibility and defines the * IFD operation mode (TLP or Normal). * * Remarks : * ------------- * Disabling ROS command compatibility disables this command. * Disabling ROS commad compatibility also disables TLP mode. * * In : * ------------- * - Handle is the handle returned by the communication layer. * - Timeout is the time, in ms, for IFD to execute the command. * - Option holds the option selection byte: * bit 4 select the mode operation, 1 for TLP mode, 0 for normal mode. * bit 1 set to 0 disables ROS command compatibility and TLP mode. * - RespLen holds the available place in RespBuff. The needed value is 2 bytes. * * Out : * ------------- * - RespLen holds the number of updated bytes in RespBuff. This value is lower * of equal to the value given in entry. * - RespBuff holds RespLen read bytes. The response has the following format: * * * Responses : * ------------- * If everything is OK: * - G_OK ( 0). * If an error condition is raised: * - GE_IFD_MUTE (-201) if a character/command timeout is detected. * - GE_HI_COMM (-300) if a communication error occurs. * - GE_HI_PARITY (-301) if a parity error is encountered. * - GE_HI_LRC (-302) if an EDC error has been detected. * - GE_HI_PROTOCOL (-310) if a frame error is encountered. * - GE_HI_LEN (-311) if a bad value has been detected in LN field * or if the response buffer is too small. * - GE_HI_FORMAT (-312) if the received message is neither I-Block, * neither R-Block and neither S-Block. * - GE_HI_CMD_LEN (-313) if the CmdLen is greater than HGTGBP_MAX_DATA or * if MsgLen is too small to receive the built message. * - GE_HI_NACK (-314) if a R-Block has been received. * - GE_HI_RESYNCH (-315) if a S-Block has been received. * - GE_HI_ADDRESS (-316) if the NAD is not valid for the selected channel. * - GE_HI_SEQUENCE (-317) if a bad sequence number has been received. * - GE_HOST_PORT_BREAK (-404) if the bytes cannot be sent. * - GE_HOST_PORT_CLOSE (-412) if port is closed. * - GE_HOST_PARAMETERS (-450) if the given handle is out of the allowed range. * Extern Var : ------------- Nothing. Global Var : ------------- Nothing. *******************************************************************************/ INT16 G_DECL G_Oros3SetMode ( const INT16 Handle, const WORD32 Timeout, const WORD16 Option, WORD16 G_FAR *RespLen, BYTE G_FAR RespBuff[] ) { /*------------------------------------------------------------------------------ Local variables: - cmd holds the set mode command whose format is <01h> <00h>