 
#ifndef __JP_PLC_COMM_H_INCLUDED_
#define __JP_PLC_COMM_H_INCLUDED_



#define PLCCOMM_API   WINAPI

//错误码
#define JP_PC_OK                   0
#define JP_PC_ERROR               (-1)
#define JP_PC_COMM_TIMEOUT        (-2)
#define JP_PC_DATATYPE_UNSUPPORT  (-3)
#define JP_PC_UNKNOWN_MEMTYPE     (-4)
#define JP_PC_MSG_ERROR           (-5)
#define JP_PC_WRITE_ERROR         (-6)
#define JP_PC_READ_ERROR          (-7)
#define JP_PC_CRC_ERROR           (-8)
#define JP_PC_NOT_ENOUGH_MEM      (-9)



#define  JP_PC_DEFAULT             0




//通信模块
#define JP_PC_SCOMM                  0
#define JP_PC_MODBUS_RTU_SLAVE       1
#define JP_PC_MODBUS_RTU_MASTER      2
#define JP_PC_MODBUS_ASCII_SLAVE     3
#define JP_PC_MODBUS_ASCII_MASTER    4


//#define JP_PC_MITUBISH        101 //三菱
//#define JP_PC_SIMATIC         110 //西门子spi
//#define JP_PC_SIMATIC_MPI     111 //西门子mpi

#define JP_PC_CUST_SCOMM      119 //自定义串口协议， 分ASCII和BIN两种子类
#define JP_PC_CUST_MASTER     119 //自定义协议主站, BIN
#define JP_PC_CUST_SLAVE      120 //自定义协议从站, BIN 

#define JP_PC_SCOMM_MASTER_BIN    121
#define JP_PC_SCOMM_SLAVE_BIN     122 

#define JP_PC_SCOMM_MASTER_ASCII   JP_PC_CUST_MASTER 
#define JP_PC_SCOMM_SLAVE_ASCII    JP_PC_CUST_SLAVE 

#define JP_PC_MAX_CUSTOM_SCOMM     199
#define JP_PC_MIN_CUSTOM_SCOMM     JP_PC_CUST_SCOMM

//下面的TCPIP扩展请遵守：
//扩展的特定设备协议主站为单数
// 扩展的特定设备协议从站为双数

#define JP_PC_MAX_SCOMM       199  


#define JP_PC_GPIO            200 //GPIO
//#define JP_PC_YANYU_GPIO      201 //研域GPIO
#define JP_PC_MAX_GPIO        299  



#define JP_PC_TCPIP           300 //NET
#define JP_PC_SLAVE_UDP       301 //从站UDP,SERVER
#define JP_PC_SLAVE_TCP       302 //从站TCP,SERVER
#define JP_PC_MASTER_UDP      303 //主站UDP,CLIENT
#define JP_PC_MASTER_TCP      304 //主站TCP,CLIENT

//310开始，主从站通过参数来区别
#define JP_PC_MODBUS_TCP      310


#define JP_PC_MAX_TCPIP       399

#define JP_PC_MAX_MODULE      500 //最大模块值


//串口停止位
#define JP_PC_ONE_STOPBIT   0
#define JP_PC_ONE5_STOPBIT  1
#define JP_PC_TWO_STOPBIT   2

//串口通信校验
#define JP_PC_NO_PARITY            0
#define JP_PC_ODD_PARITY           1
#define JP_PC_EVEN_PARITY          2
#define JP_PC_MARK_PARITY          3
#define JP_PC_SPACE_PARITY         4
 
//消息校验(Block Check Character))
#define JP_PC_NO_BCC    0
#define JP_PC_ONE_BCC   1
#define JP_PC_TWO_BCC   2
#define JP_PC_MINOLTA    11 //美能达 

//分隔符
#define JP_PC_NO_DELIMITER        0x0000
#define JP_PC_CR_DELIMITER        0x000D
#define JP_PC_LF_DELIMITER        0x000A
#define JP_PC_CRLF_DELIMITER      0x0D0A

 
//4字节浮点数据类型字节顺序
#define JP_PC_FO4_DEFAULT      0
#define JP_PC_FO4_ABCD         1
#define JP_PC_FO4_DCBA         2
#define JP_PC_FO4_BADC         3
#define JP_PC_FO4_CDAB         4
  

typedef struct __comm_options_
{
	int portIndex; //端口号: 从0开始,如COM1为0
	int baudRate;  //波特率: 9600, ...
	int dataBits;  //数据位: 8, ...
    int stopBits;  //停止位: JP_PC_ONE_STOPBIT , ...
	int parity;    //校验位: JP_PC_NO_PARITY, ...
}JP_COMM_OPTIONS;

typedef struct __tcpip_options_
{
	char strIp[64+1]; //端口号 
	int  port;   
	BOOL bRetryTcp;
}JP_TCPIP_OPTIONS;
 

//PLC协议支持的数据类型定义

enum JP_PLC_DATATYPE
{
	PDP_NONE	= -1,	//未定义
	PDP_BIT	 	=  0,	//位类型(包括位块: 按位存储,往字节低位对齐)
	PDP_BYTE 	=  1,	//字节(1字节: char存储格式)
	PDP_WORD 	=  2,	//字(2字节: short存储格式)
	PDP_DWORD	=  3,	//双字(4字节: long存储格式)
	PDP_FLOAT	=  4,		//浮点数(4字节: float存储格式)
	PDP_FLOAT64  = 5,    //双精度
	PDP_TEXT     = 6,     //文本，带NULL终止符
	PDP_BLOCK    = 7,     //字节数据
};

//三菱PLC地址类型
enum  
{
    JP_MITS_NON  =   0,
    JP_MITS_X    =   1,
    JP_MITS_Y    =   2,
    JP_MITS_M    =   3,
    JP_MITS_S    =   4,
    JP_MITS_D    =   5,
    JP_MITS_T    =   6,
    JP_MITS_C16  =   7,
    JP_MITS_C32  =   8   
};

 
//研域数字IO类型
//不再支持
enum  
{
    JP_YYU_INPUT  =   0,
	JP_YYU_OUTPUT ,
};

//字节内容类型
enum
{
	JP_CSC_ASCII = 0,
	JP_CSC_BIN   = 1,
};



////modbus 地址类型
enum 
{
	JP_MB_RCS = 1, // Read Coil Status  
    JP_MB_RIS = 2, // Read Input Status  
    JP_MB_RHR = 3, // Read Holding Registers  
    JP_MB_RIR = 4, // Read Input Registers  
    JP_MB_FSC = 5, // Force Single Coil  
    JP_MB_PSR = 6, // Preset Single Register  
    JP_MB_RES = 7, // Read Exception Status  
    JP_MB_D  = 8, // Diagnostics 
    JP_MB_P  = 9, // Program 484  
    JP_MB_POLL =10,// Poll 484  
    JP_MB_CEC = 11,// Fetch Comm. Event Ctr. 
    JP_MB_CEL = 12,// Fetch Comm. Event Log 
    JP_MB_PROG_C  = 13,// Program Controller  
    JP_MB_POLL_C=14,// Poll Controller  
    JP_MB_FMC = 15,//15 Force Multiple Coils  
    JP_MB_PMR = 16,// Preset Multiple Registers  
    JP_MB_RS_ID =17,// Report Slave ID  
    JP_MB_M84 = 18,// Program 884/M84  
    JP_MB_RCL=19,// Reset Comm. Link  
    JP_MB_RGR = 20,// Read General Reference  
    JP_MB_WGR =21,// Write General Reference  
    JP_MB_MW4X  = 22,// Mask Write 4X Register  
    JP_MB_RW_4X =23,// Read/Write 4X Registers  
    JP_MB_FIFO_Q=24, //Read FIFO Queue  
};

//modbus 子协议
enum{
	JP_MB_RTU   = 0,
	JP_MB_ASCII,
};

//数据到达回调函数
typedef void (WINAPI *JP_DATA_RECEIVED_FUNC)(const char*, UINT, void*);

//modbus tcp data  
//serial, command, memaddr, int len, void* pData, int size, int* errcode, void* userdata
//return: true or false
//pData in char(byte) for JP_MB_RCS(1), JP_MB_RIS(2), in short for JP_MB_RHR(3) , JP_MB_RIR(4)

typedef BOOL (WINAPI *JP_MODBUS_RTU_DATA_FUNC)(UINT ,  int, int, int, void*, int, int*, void*);

typedef void (WINAPI *JP_DATA_SENT_FUNC)(const char*, UINT, void*);


//创建串口，网口，或DIO通信模块，Plc名称只是为了兼容
extern "C" HANDLE PLCCOMM_API jpCreatePlcComm(int module, int sub);

//bWorkSlave是否为从站，通常情况下，PC作为主站
//支持的模块: JP_PC_MODBUS_TCP
//注意: 未注明的模块请使用jpCreatePlcComm创建
extern "C" HANDLE PLCCOMM_API jpCreatePlcCommEx(int module, int sub, BOOL  bWorkSlave);

extern "C" void   PLCCOMM_API jpDestroyPlcComm(HANDLE hComm);


extern "C" void   PLCCOMM_API jppcSetTimeout(HANDLE hComm, int timeout);
extern "C" int    PLCCOMM_API jppcGetTimeout(HANDLE hComm);

//设置消息响应方的反应时间
extern "C" void    PLCCOMM_API jppcSetLatentTime (HANDLE hComm, int msec);
extern "C" int     PLCCOMM_API jppcGetLatentTime (HANDLE hComm);

//这个暂时没有用到，保留
extern "C" void   PLCCOMM_API jppcSetDevID(HANDLE hComm, int id );
extern "C" int    PLCCOMM_API jppcGetDevID(HANDLE hComm);

//modbus rtu 从站地址
extern "C" void   PLCCOMM_API jppcSetDestID(HANDLE hComm, int id);
extern "C" int    PLCCOMM_API jppcGetDestID(HANDLE hComm);

//设置字节顺序
extern "C" void    PLCCOMM_API jppcSetByteOrder(HANDLE hComm, int dataType, int order);
extern "C" int    PLCCOMM_API jppcGetByteOrder(HANDLE hComm, int dataType);



extern "C" BOOL   PLCCOMM_API jppcSetCommOptions(HANDLE hComm, const void* pParamSet,UINT nParamSize);
extern "C" BOOL   PLCCOMM_API jppcSetSerialCommOptions(HANDLE hComm, JP_COMM_OPTIONS options);

extern "C" BOOL   PLCCOMM_API jppcSetTcpipOptions(HANDLE hComm, const char* strIp, int port, BOOL bReconnect);

extern "C" BOOL    PLCCOMM_API jppcGetCommOptions(HANDLE hComm,  void* pParamSet, UINT nSize);

extern "C" BOOL PLCCOMM_API   jppcOpen (HANDLE  hComm);    //by-yy///////////////
extern "C" BOOL	PLCCOMM_API   jppcIsOpened(HANDLE  hComm);
extern "C" void  PLCCOMM_API  jppcClose (HANDLE  hComm);
//extern "C" void  PLCCOMM_API  jppcClearBuff(HANDLE  hComm);

//打开以后，不能修改虚拟状态
//必须在端口关闭状态下进行
extern "C" void  PLCCOMM_API  jppcEnableVirtual(HANDLE  hComm);
extern "C" void  PLCCOMM_API  jppcDisableVirtual(HANDLE  hComm);

extern "C" BOOL  PLCCOMM_API  jppcIsVirtual(HANDLE  hComm);
extern "C" int  PLCCOMM_API   jppcReadVirtual(HANDLE  hComm, char* buffer, int size);
extern "C" int  PLCCOMM_API   jppcWriteVirtual(HANDLE  hComm, const char* buffer, int size);
extern "C" void  PLCCOMM_API  jppcClearVirtual(HANDLE  hComm );
extern "C" BOOL  PLCCOMM_API  jppcSendMsgVirtual(HANDLE  hComm, const char* pMsg, int nMsgSize, char* pRecv, int nAckLen );


extern "C" BOOL    PLCCOMM_API jppcReadBit(HANDLE hComm,  int memtype, int address , char* pValue, int count);
extern "C" BOOL    PLCCOMM_API jppcReadBitE1(HANDLE hComm,  int memtype, int address , char* pValue  );

extern "C" BOOL    PLCCOMM_API jppcReadByte(HANDLE hComm, int memtype, int address ,unsigned char* pValue);

extern "C" BOOL    PLCCOMM_API jppcReadShort(HANDLE hComm, int memtype, int address , short  * pValue); 
extern "C" BOOL    PLCCOMM_API jppcReadInt(HANDLE hComm, int memtype, int address , int* pValue);
extern "C" BOOL    PLCCOMM_API jppcReadFloat(HANDLE hComm, int memtype, int address, float* pValue );

extern "C" BOOL    PLCCOMM_API jppcWriteBit(HANDLE hComm,  int memtype, int address, char nValue, int count);
extern "C" BOOL    PLCCOMM_API jppcWriteBitE1(HANDLE hComm,  int memtype, int address, char nValue );

extern "C" BOOL    PLCCOMM_API jppcWriteByte(HANDLE hComm,  int memtype, int address, unsigned char nValue);
extern "C" BOOL    PLCCOMM_API jppcWriteShort(HANDLE hComm,  int memtype, int address,  short int nValue); //yy
extern "C" BOOL    PLCCOMM_API jppcWriteInt(HANDLE hComm,  int memtype, int address,    int nValue);
extern "C" BOOL    PLCCOMM_API jppcWriteFloat(HANDLE hComm,  int memtype, int address,  float nValue);

extern "C" BOOL    PLCCOMM_API jppcWriteBuffer(HANDLE hComm,  const char* pData, int size);
extern "C" BOOL    PLCCOMM_API jppcReadBuffer(HANDLE hComm,   char* pData, int* pSize);
extern "C" BOOL    PLCCOMM_API jppcReadBufferE1(HANDLE hComm,  int seperator,  char* pData, int* pSize);

//写位数组和写字数组
extern "C" BOOL    PLCCOMM_API jppcWriteBitArray(HANDLE hComm,  int memtype, int address, char* pValueArray, int count);
extern "C" BOOL    PLCCOMM_API jppcWriteWordArray(HANDLE hComm,  int memtype, int address,  short  * pValueArray, int count); 

extern "C" BOOL    PLCCOMM_API jppcReadBitArray(HANDLE hComm,  int memtype, int address, char* pValueArray, int count);
extern "C" BOOL    PLCCOMM_API jppcReadWordArray(HANDLE hComm,  int memtype, int address,  short  * pValueArray, int count); 

extern "C" BOOL    PLCCOMM_API jppcReadText(HANDLE hComm,  int memtype, int address, int dataType,   char* strOut, int size);
extern "C" BOOL    PLCCOMM_API jppcWriteText(HANDLE hComm,  int memtype, int address, int dataType, const char* strText); 

//消息分隔符号
//将输入的消息(消息由上层软件组报)加上校验码,分隔符号后发送
extern "C" BOOL    PLCCOMM_API jppcWriteMessage(HANDLE hComm,  const char* pMsgBuffer, int nMsgSize,  int bcc, int delimeter);

//将接收消息并进行校验,返回的消息包括分隔符号以及校验码
extern "C" BOOL    PLCCOMM_API jppcReadMessage(HANDLE hComm,   char* pRecvBuffer, int* pRecvLen, int bcc, int delimeter);



//
extern "C" BOOL    PLCCOMM_API jppcSendMessage(HANDLE hComm,  const char* pMsg, int nMsgSize,  char* pRecv, int nAckLen);

//extern "C" BOOL    PLCCOMM_API jppcSendMessageV2(HANDLE hComm,  const char* pMsg, int nMsgSize, char terminator, char* pRecv, int* pAckLen);
//extern "C" BOOL    PLCCOMM_API jppcSendMessageV3(HANDLE hComm,  const char* pMsg, int nMsgSize, char* pTerminator, char* pRecv, int* pAckLen);







extern "C" BOOL    PLCCOMM_API jppcIsReadable(HANDLE hComm,  int memtype);
extern "C" BOOL    PLCCOMM_API jppcIsWritable(HANDLE hComm,  int memtype);

extern "C" int    PLCCOMM_API jppcGetLastError(HANDLE hComm );


//
extern "C"   void  PLCCOMM_API jpaxGetTextIp(DWORD dwIp, char* strOut, int size);
extern "C"   DWORD  PLCCOMM_API jpaxGetSolidIp(const char* strIp);

//读数接口没有实现
extern "C" BOOL    PLCCOMM_API jppcReadBatch(HANDLE hComm, int memtype, int dataType, int startAddress ,   void* pValueArray, int& nArraySize);
//写接口
//数据类型必须与对应的数据类型一致
//即：BIT -1字节， BYTE -1字节， WORD -2字节， DWORD, FLOAT -4字节
extern "C" BOOL    PLCCOMM_API jppcWriteBatch(HANDLE hComm, int memtype, int dataType, int startAddress , void* pValueArray, int  nArraySize);


extern "C" void      PLCCOMM_API    jppcSetDataReceivedCallback (HANDLE hComm, JP_DATA_RECEIVED_FUNC fnDataReceivedFunc, void* pUserData);
extern "C" void      PLCCOMM_API    jppcSetDataSentCallback (HANDLE hComm, JP_DATA_SENT_FUNC fnDataSentFunc, void* pUserData);

extern "C" void      PLCCOMM_API    jppcSetModbusRtuDataCallback (HANDLE hComm, JP_MODBUS_RTU_DATA_FUNC fnModbusRtuDataFunc, void* pUserData);




//未来接口，尚未实现
//读任意站点数据,单个内存单元的数据
extern "C" BOOL    PLCCOMM_API jppcReadEx(HANDLE hComm, int remoteAddr, int memtype, int dataType, int startAddress, void* pValue);
extern "C" BOOL    PLCCOMM_API jppcWriteEx(HANDLE hComm, int remoteAddr, int memtype, int dataType, int startAddress ,   void* pValue  );

extern "C" void           PLCCOMM_API jppcSetExtraInfo(HANDLE hComm,  const char* strSerial );
extern "C" const char*    PLCCOMM_API jppcGetExtraInfo(HANDLE hComm);


//GPIO: JP_PC_GPIO
//RS45: JP_PC_TCPIP
//RS232: JP_PC_SCOMM 
extern "C" int PLCCOMM_API jppcGetPortType(HANDLE hComm);




#endif

