#ifndef NODE_ACCESS_H
#define NODE_ACCESS_H

/*!
  \file
  \brief 他ノードへのアクセス

  \author Satofumi KAMIMURA

  $Id: nodeAccess.h 286 2008-10-20 09:40:22Z satofumi $
*/


enum {
  WAIT_PACKET_HEADER,
  HEADER_RECEIVED,
  PACKET_RECEIVED,

  NODE_INFO_MAX = 8,
};


/*!
  \brief ノードの情報管理
*/
typedef struct {
  int num;
  unsigned char *address[NODE_INFO_MAX];
  long target_id[NODE_INFO_MAX];
} nodeInfo_t;


/*!
  \brief パケットの情報管理
*/
typedef struct {
  unsigned char *top;
  unsigned char *buffer;
  unsigned char *data_top;
  long first_tag;
  unsigned long length;
  long target_id;
  long unique_id;
  unsigned char type;
  unsigned char reply;
  unsigned char header_checksum;
  unsigned char data_num;
  unsigned char packet_checksum;
} packetInfo_t;


enum {
  NODE_ACCESS_RETRY_TIMES = 3,
  NODE_ACCESS_PACKET_HEADER_SIZE = 16,

  PACKET_UNKNOWN = -1,
  PACKET_WRITE_REQUEST = 0x1,
  PACKET_WRITE_RESPONSE = 0x2,
  PACKET_READ_REQUEST = 0x4,
  PACKET_READ_RESPONSE = 0x6,

  PACKET_FIRST_TAG = 0x42f27b,
};


#define ADD_PACKET_DATA(A, B) addPacketData(A,(unsigned char *)&(B),sizeof(B))
#define ADD_WRITE_PACKET_DATA(A, B, C) { B = C; addPacketData(A,(unsigned char *)&(B),sizeof(B)); }


extern void initNodeInfo(nodeInfo_t *node);
extern int registerStructInfo(nodeInfo_t *node,
			      unsigned char *top, long target_id);
extern long getStructId(nodeInfo_t *node, unsigned char *top);
extern void initPacketInfo(packetInfo_t *pa, unsigned char *buffer,
			   unsigned char *top,
			   unsigned char type, long target_id, long unique_id);
extern int terminatePacketInfo(packetInfo_t *pa);
extern char getPacketType(unsigned char *packet_data);
extern long getPacketLength(unsigned char *packet_data);
extern long getPacketUniqueId(unsigned char *packet_data);
extern void writeFromPacketData(unsigned char *packet_data,
						unsigned char *top);
extern void addPacketData(packetInfo_t *na, unsigned char *offset,
			  unsigned char size);
extern void setPacketReply(packetInfo_t *na, unsigned char reply);
extern int checkHeaderFormat(unsigned char *buffer);
extern int checkFirstTag(unsigned char *buffer);
extern int checkPacketFormat(unsigned char *buffer, int length);
extern long createReadResponsePacket(unsigned char *buffer,
				     unsigned char *top);
extern long createWriteResponsePacket(unsigned char *buffer,
				      unsigned char *top);
extern int removeInvalidPacketHeader(unsigned char *recv_buffer, int filled);

#endif /* !NODE_ACCESS_H */
