//---------------------------------------------------------------------------
// Copyright (C) 2001 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//---------------------------------------------------------------------------
//

#include "ownet.h"
#include <memory.h>

#define MAX_SEND            255      // Maximum send buffer size 
#define MAX_RECEIVE         2048     // Maximum receive buffer size 
#define MAX_JIB_NUM         16       // Maximum number of CiBs on system 
#define MAX_BUF_SIZE        256 
#define MAX_PIN_SIZE        8
#define MAX_AID_SIZE        16

// maximum data bytes that can be sent in a single packet 
#define MAX_APDU_SIZE       114

#define JIB_APDU_CLA_COMMAND_PROC (uchar)0xd0
#define JIB_APDU_CLA_LOAD_APPLET  (uchar)0xd0
#define JIB_APDU_CLA_SELECT       (uchar)0x00
#define JIB_APDU_INS_COMMAND_PROC (uchar)0x95
#define JIB_APDU_INS_LOAD_APPLET  (uchar)0xa6
#define JIB_APDU_INS_SELECT       (uchar)0xa4
#define JIB_APDU_P1_LOAD_APPLET   (uchar)0x01
#define JIB_APDU_P1_CONTINUE_LOAD (uchar)0x02
#define JIB_APDU_P1_SELECT        (uchar)0x04
#define JIB_APDU_P1_COMMAND_ADMIN (uchar)0x00
#define JIB_APDU_P1_COMMAND_INFO  (uchar)0x01
#define JIB_APDU_P1_COMMAND_STATS (uchar)0x02
#define JIB_APDU_P1_COMMAND_AID   (uchar)0x03
#define JIB_APDU_LE_DEFAULT       (uchar)0x00
#define JIB_APDU_UNUSED           (uchar)0x00

// API communication error codes
#define ERR_NO_JIBS_FOUND        0xF000
#define ERR_BAD_JIB_ROM          0xF100
#define ERR_JIB_NOT_FOUND        0xF200
#define ERR_ADAPTER_NOT_FOUND    0xF300
#define ERR_COMM_FAILURE         0xF400

// General API Errors
#define ERR_API_INVALID_PARAMETER 0xFA00
#define ERR_API_MEMORY_ALLOCATION 0xFA01

// ISO Errors & JiB Errors
#define ERR_ISO_NORMAL_00             0x9000
#define ERR_NEXT_LOAD_PACKET_EXPECTED 0x6301

#define COMMIT_BUFFER_BYTES_PER_FIELD 0x09



//---------------------------------------------------------------------------
// For the current CIB implementation, the maximum outbound or inbound
// message size is 128 bytes, and the header (FIFO) data is always 8 bytes
// long for all transactions.
 
#define SEGSIZE     128    // Max seg size that we can send to the device 
#define HEADERSIZE  8      // Size of a comm layer header packet 
#define CIB_FC      0x16
#define MAX_CIB_NUM 16
#define FIFO_LEN    8

// Communications Layer OWMS Status Codes -
#define CE_RESET         0
#define CE_MSGINCOMP     1
#define CE_BADSEQ        2 
#define CE_BUFOVERRUN    3
#define CE_BADCKSUM      4
#define CE_HDRSIZE       5
#define CE_DATASIZE      6
#define CE_BADCRC        7
#define CE_DURATION      8
#define CE_FIFONOTEMPTY  9
#define CE_STANDBY       10
#define CE_RESPONSERDY   11
#define CE_RESPINCOMP    12
#define CE_NOHEADER      13
#define CE_MESSAGEOK     15
#define CE_FIRSTBIRTH    29
#define CE_CIREEXEC      30
#define CE_CMDINCOMP     31

#define CE_BPOR          0x40   // Buferred POR bit in OWMS status byte 

// Function Error Return Codes
#define ER_NOROOM    2       // No room in outbound FIFO for a message header 
#define ER_POR       3       // Constant POR status from device 
#define ER_ACCESS    4       // Error trying to access device 
#define ER_COLLIDE   5       // One-Wire Collision Error 
#define ER_ACK       6       // Failure to get device acknowledge bit 
#define ER_CRC       7       // CRC test failed 
#define ER_CHECKSUM  8       // Checksum test failed 
#define ER_NOHEADER  9       // No header found (no message to read) 
#define ER_BADHEADER 10      // Bad header form or length 
#define ER_HDRCRC    11      // Header crc does not match data segment crc 
#define ER_SEQUENCE  12      // Segments arrived out of sequence or missing 
#define ER_OVERRUN   13      // Inbound message overflowed buffer limit 
#define ER_COPRUN    14      // Co-Processor Will Not Complete 
#define ER_RERUN     15      // Prior command will not complete 
#define ER_ADAPTER   16      // Bad adapter selection  

// Error Group Codes
#define ER_SENDDATA   0x10   // Error in sending segment data 
#define ER_SENDHDR    0x20   // Error in sending a segment header 
#define ER_GETSTATUS  0X30   // Error in geting status 
#define ER_SENDSTATUS 0x40   // Error in sending status command 
#define ER_SENDRUN    0x50   // Error in sending run command 
#define ER_SENDRESET  0x60   // Error in sending reset command 
#define ER_SENDINT    0x70   // Error in sending interrupt command 
#define ER_RECVHDR    0x80   // Error in unload of segment header 
#define ER_RECVDATA   0x90   // Error in unload of segment data 
#define ER_COMMERROR  0xA0   // Comm Error response from device 

// One-Wire Command Codes -
#define OW_MICRORUN       0x87
#define OW_MICROINTERRUPT 0x77
#define OW_MICRORESET     0xDD
#define OW_STATUSREAD     0xE1
#define OW_STATUSWRITE    0xD2
#define OW_IPRREAD        0xAA
#define OW_IPRWRITE       0x0F
#define OW_FIFOREAD       0x22
#define OW_FIFOWRITE      0x2D

// CiB One-Wire Release sequence values -
#define RS_MICRORUN       0x5D73
#define RS_MICROINTERRUPT 0x6D43
#define RS_MICRORESET     0x92BC
#define RS_STATUSWRITE    0x517F
#define RS_FIFOREAD       0x624C
#define RS_FIFOWRITE      0x9DB3

#define LSB(a) (uchar) ((a) & 0xFF)
#define MSB(a) (uchar) (((a) & 0xFF00) >> 8)

//---------------------------------------------------------------------------
// Structure definitions
//
typedef struct _FIFORDWR
{
   uchar Cmd;
   uchar Len;
   uchar FIFOBuf[8];
}
FIFORDWR;

typedef struct _CMDPACKET
{
   uchar Len;
   uchar CmdByte;
   uchar GroupID;
   uchar CmdData[MAX_SEND]; 
}
CMDPACKET;

// Firmware return packet 
typedef struct _RETPACKET      
{
   uchar CSB;
   uchar GroupID;
   uchar DataLen;
   uchar CmdData[MAX_RECEIVE];
}
RETPACKET;

// Command APDU 
typedef struct _COMMANDAPDU  
{
  uchar   Header[4];
  uchar   Lc;
  uchar  *Data;
  uchar   Le;
} COMMANDAPDU, *LPCOMMANDAPDU;

// Field access defines 
#define CLA Header[0]
#define INS Header[1]
#define P1  Header[2]
#define P2  Header[3]

// Response APDU 
typedef struct _RESPONSEAPDU 
{
  ushort   Len;
  uchar   *Data;
  ushort   SW;
} RESPONSEAPDU,*LPRESPONSEAPDU;

// iButton Master PIN 
typedef struct _JIBMASTERPIN 
{
  uchar Len;
  uchar Data[MAX_PIN_SIZE];
} JIBMASTERPIN,*LPJIBMASTERPIN;

// Applet AID 
typedef struct _AID
{
  uchar Len;
  uchar Data[MAX_AID_SIZE];
} AID, *LPAID;

// API Commands 
#ifdef __cplusplus
extern "C" {
#endif

// raw communication functions
ushort SendCiBMessage(int portnum, 
                        uchar *mp, 
                        ushort mlen, 
                        uchar ExecTime);
ushort RecvCiBMessage(int portnum, 
                        uchar *mp, 
                        ushort *bufsize);
void SetMinRunTime(ushort MR);

// device specific functions
void SetDefaultExecTime(ushort p_ExecTimeMS);
LPRESPONSEAPDU SendAPDU(int portnum, 
                        LPCOMMANDAPDU  p_lpCommandAPDU, 
                        ushort         p_ExecTimeMS);
void SetPIN(LPJIBMASTERPIN p_lpMasterPIN);
LPRESPONSEAPDU Process(int portnum,
                       uchar   p_CLA, 
                       uchar   p_INS, 
                       uchar   p_P1, 
                       uchar   p_P2, 
                       uchar   p_Lc, 
                       uchar* p_lpData,
                       ushort   p_RunTimeMS);
LPRESPONSEAPDU Select(int portnum, LPAID p_lpAID);
LPRESPONSEAPDU MasterErase(int portnum);
LPRESPONSEAPDU GetFreeRam(int portnum);
LPRESPONSEAPDU GetFreeRamPerBank(int portnum);
LPRESPONSEAPDU GetFirmwareVersionString(int portnum);
LPRESPONSEAPDU GetEphemeralGCMode(int portnum);
LPRESPONSEAPDU SetEphemeralGCMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetAppletGCMode(int portnum);
LPRESPONSEAPDU SetAppletGCMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetCommandPINMode(int portnum);
LPRESPONSEAPDU SetCommandPINMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetLoadPINMode(int portnum);
LPRESPONSEAPDU SetLoadPINMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetRestoreMode(int portnum);
LPRESPONSEAPDU SetRestoreMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetExceptionMode(int portnum);
LPRESPONSEAPDU SetExceptionMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetISOExceptionMode(int portnum);
LPRESPONSEAPDU SetISOExceptionMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetErrorReportMode(int portnum);
LPRESPONSEAPDU SetErrorReportMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetCommitBufferSize(int portnum);
LPRESPONSEAPDU GetCommitBufferFields(int portnum);
LPRESPONSEAPDU SetCommitBufferSize(int portnum, short p_SizeInBytes);
LPRESPONSEAPDU SetCommitBufferFields(int portnum, short p_NumberOfFields);
LPRESPONSEAPDU GetATR(int portnum);
LPRESPONSEAPDU GetRealTimeClock(int portnum);
LPRESPONSEAPDU GetRandomBytes(int portnum, short p_NumBytes);
LPRESPONSEAPDU GetAIDByNumber(int portnum, uchar p_AIDNum);
LPRESPONSEAPDU GetLastJCREError(int portnum);
LPRESPONSEAPDU GetAllAIDs(int portnum);
LPRESPONSEAPDU GetActivationTimeRemaining(int portnum);
LPRESPONSEAPDU GetVerifyLoadWithIdMode(int portnum);
LPRESPONSEAPDU SetVerifyLoadWithIdMode(int portnum, uchar p_Mode);
LPRESPONSEAPDU GetPORCount(int portnum);
LPRESPONSEAPDU SetMasterPIN(int portnum, LPJIBMASTERPIN p_lpNewMasterPin);
LPRESPONSEAPDU DeleteSelectedApplet(int portnum);
LPRESPONSEAPDU DeleteAppletByNumber(int portnum, uchar p_AppletNumber);
LPRESPONSEAPDU DeleteAppletByAID(int portnum, LPAID p_lpAID);
LPRESPONSEAPDU LoadApplet(int portnum, 
                          uchar* p_lpAppletBuffer, 
                          uint  p_AppletLen,
                          LPAID  p_lpAID);
void SetJiBError(ushort p_Error);
ushort GetJiBError();

#ifdef __cplusplus
}
#endif
