#ifndef __PROTOCOL_H
#define __PROTOCOL_H

//#include "raw_sock.h"
#include "ldp.h"

#define COMMON_TIMER_PERIOD   20
#define DEFAULT_ADVERTISE_PERIOD	1
#define MAX_EPOLL_SIZE 5120

#ifndef ETH_P_TP
#define ETH_P_TP 0x8110
#endif

#ifndef PROTOCOL_VERSION
#define PROTOCOL_VERSION 1	/* 协议版本 */
#endif

#ifndef MAGIC_NUM
#define MAGIC_NUM 0xE12B83C7	/* 协议魔数 */
#endif

#ifndef PROTOCOL_BODY_LEN
#define PROTOCOL_BODY_LEN 1472	/* 协议payload最大长度 */
#endif

#ifndef UUID_PREFIX_FMAT
#define UUID_PREFIX_FMAT "3fa1fe68-b915-4053-a3e1-"	/* uuid前缀 */
#endif

#ifndef BROADCAST_MAC_ADDR
#define BROADCAST_MAC_ADDR "FF:FF:FF:FF:FF:FF"
#endif

#define DEV_NAME_V3			"WooLink-SMC-GW-V3"
#define DEV_NAME_V3_LITE	"WooLink2F6280-W-4G"

#define SYS_FLAGS_SYS_CONFIG_STATUS 0x00000001

typedef enum _DESTINATION_TYPE
{
	DESTINATION_TYPE_LOCALHOST = 0,
	DESTINATION_TYPE_OTHERHOST,
	DESTINATION_TYPE_BROADCAST
} DESTINATION_TYPE;

enum PROTOCOL_TYPE
{
	TYPE_BASE = 0,
	TYPE_DISCOVERY,
	TYPE_ADV,
	TYPE_SET_IP,
	TYPE_MAX
};

/* 对应OSI网络分层模型的底下3层，tp私有协议根据数
  * 据包的不同层次分别采用对应的校验和计算方法
  */
enum OSI_LAYER_TYPE
{
	PHYSICAL_LAYER = 1,		/* 物理层 */
	DATALINK_LAYER,		/* 数据链路层 */
	NETWORK_LAYER			/* 网络层 */
};

enum ERROR_CODE
{
	EC_SUCCESS = 0,
	EC_INVALID_ARGUMENT,
	EC_NODE_FULL,
	EC_ALREADY_AUTHED,
	EC_CRC_CHECK_FAIL,
	EC_UNKNOWN_TYPE,
	EC_LENGTH_NOT_MATCH,
	EC_OUT_OF_RANGE,
	EC_MAX
};

enum ME_TYPE
{
	ME_T_BASE = 0,
	ME_T_ADVERTISEMENT, /*主动广播*/
	ME_T_DISCOVERY,		/*被动发现*/
	ME_T_MACADDR,		/*设备mac地址*/
	ME_T_DEVNAME,		/*设备型号*/
	ME_T_DEVSN,			/*设备SN*/
	ME_T_DEVVER,		/*设备固件版本*/
	ME_T_DEVHWVER,		/*设备硬件版本*/
	ME_T_DEVIP,			/*设备IP*/
	ME_T_DEVNETMASK,	/*设备掩码*/
	ME_T_DEVNETMAC,		/*设备MAC*/
	ME_T_DEVSSHPORT,	/*设备SSH端口*/
	ME_T_DEVSSHENC,		/*设备SSH是否秘钥登录*/
	ME_T_MAX
};

/* ----------- 定义ME类型结构 ------------ */
#ifndef DEVNAME_SIZE
#define DEVNAME_SIZE 64	/* 设备名称最大长度 */
#endif

#ifndef DEVSN_SIZE
#define DEVSN_SIZE 64	/* 设备SN最大长度 */
#endif

#ifndef DEVVER_SIZE
#define DEVVER_SIZE 64	/* 设备版本最大长度 */
#endif

#ifndef STR_IP_LEN
#define STR_IP_LEN 16	/* IP地址(点分十进制形式)长度 */
#endif

#ifndef STR_SSH_LEN
#define STR_SSH_LEN 8	/* SSH相关长度，端口和是否私钥登录 */
#endif

#ifndef PROTOCOL_BODY_LEN
#define PROTOCOL_BODY_LEN 1472	/* 协议payload最大长度 */
#endif

#ifndef RAW_PACKET_LEN_MAX
#define RAW_PACKET_LEN_MAX 1514
#endif

#ifndef ADV_FRAME_LEN_MAX
#define ADV_FRAME_LEN_MAX RAW_PACKET_LEN_MAX//max length of adv frame is less than 200
#endif

#ifndef RAW_PACKET_LEN_MIN
#define RAW_PACKET_LEN_MIN 14
#endif

#ifndef STR_MAC_LEN
#define STR_MAC_LEN 18	/* MAC地址串长度 */
#endif

#ifndef MAX_MAC_COUNT
#define MAX_MAC_COUNT 32  /* 设备发现帧中指定MAC最大个数 */
#endif

typedef struct _PROTOCOL_HDR
{
	unsigned char  version;				/* protocol version */
	unsigned char  type;					/* protocol type */
	unsigned char  hlen;					/* header length */
	unsigned char  rsvd;					/* reserved */
	unsigned int   magicnum;				/* magic number */
	unsigned short checksum;				/* checksum */
	unsigned short dlen;					/* data length */
	unsigned short seqnum;				/* sequence number */
} __attribute__ ((__packed__)) PROTOCOL_HDR;

#define PROTOCOL_HDR_SIZE   sizeof(PROTOCOL_HDR)

typedef struct _MSG_ELEMENT_HDR
{
	unsigned short type;			/* me type */
	unsigned short length;		/* me data length */
	unsigned char  data[0];		/* me data */
} __attribute__ ((__packed__)) MSG_ELEMENT_HDR;

typedef struct _IP_SET_PARAMETER
{
	char* devname;
	char ip[STR_IP_LEN];
	char netmask[STR_IP_LEN];
	char gateway[STR_IP_LEN];
} IP_SET_PARAMETER; /* ip set thread parameter struct */


typedef struct _ME_DEVNAME
{
	char name[DEVNAME_SIZE];	/* device name string */
} __attribute__ ((__packed__)) ME_DEVNAME;

typedef struct _ME_DEVSN
{
	char sn[DEVSN_SIZE];	/* device sn string */
} __attribute__ ((__packed__)) ME_DEVSN;

typedef struct _ME_DEVVER
{
	char ver[DEVVER_SIZE];	/* device ver string */
} __attribute__ ((__packed__)) ME_DEVVER;

typedef struct _ME_DEVHWVER
{
	char hwver[DEVVER_SIZE];	/* device ver string */
} __attribute__ ((__packed__)) ME_DEVHWVER;

typedef struct _ME_IPADDR
{
	char ip[STR_IP_LEN];		/* ip addr */
} __attribute__ ((__packed__)) ME_IPADDR;

typedef struct _ME_NETMASK
{
	char netmask[STR_IP_LEN];		/* ip addr */
} __attribute__ ((__packed__)) ME_NETMASK;

typedef struct _ME_SSHPORT
{
	unsigned int sshport;		/* ssh port */
} __attribute__ ((__packed__)) ME_SSHPORT;

typedef struct _ME_SSHENC
{
	unsigned int sshenc;		/* ssh key login on/off */
} __attribute__ ((__packed__)) ME_SSHENC;

typedef struct _ME_MACADDR
{
	char mac[STR_MAC_LEN];	/* mac address */
} __attribute__ ((__packed__)) ME_MACADDR;


/* ------------ 定义报文相关结构 ------------ */

/* advertisement frame */
typedef struct _ADV_CONTENT
{
	ME_DEVNAME		dev_name;
	ME_DEVSN		dev_sn;
	ME_DEVVER		dev_ver;
	ME_DEVHWVER		dev_hwver;
	ME_IPADDR		dev_ip;
	ME_NETMASK		dev_netmask;
	ME_MACADDR		dev_mac;
	ME_SSHPORT		dev_sshport;
	ME_SSHENC		dev_sshenc;
} ADV_CONTENT;

typedef struct _ADV_FRAME
{
	ADV_CONTENT content;

	int    data_len;  /* 帧长度 */
	char frame[RAW_PACKET_LEN_MAX];  /* 缓存整个信息帧(包括以太网头部) */
	
	pthread_mutex_t mutex;
} ADV_FRAME;

extern ADV_FRAME g_adv_frame;
extern char g_adv_buf[ADV_FRAME_LEN_MAX];  /* 缓存整个信息帧(包括以太网头部) */
extern char g_wan_ifname[MAX_IFNAME_LENGTH];


/* udpsend sock */
typedef struct _UDP_SEND_SOCK
{
	struct sockaddr *sock_addr;
	int sock;
} UDP_SEND_SOCK;

extern UDP_SEND_SOCK g_udp_send;
extern int g_raw_sock;

typedef struct ether_addr ETH_ADDR;
typedef struct ether_header ETH_HEADER;


/* 函数声明 */
STATUS advertisement_buf_init();
STATUS advertisement_buf_deinit(void);

STATUS protocol_handler(PROTOCOL_HDR *ph, ETH_ADDR *smac, DESTINATION_TYPE des_type);

STATUS check_hdr_validity(PROTOCOL_HDR *ph, enum OSI_LAYER_TYPE layer);

BOOL parse_discovery_frame(PROTOCOL_HDR *ph);

BOOL advertisement_content_update();

STATUS advertisement_buf_update(enum OSI_LAYER_TYPE layer);

STATUS send_advertisement_frame();
STATUS protocol_mac_handler(char *param);

STATUS get_local_ipaddr(char *dev_name, char *ipaddr);
STATUS get_local_netmask(char *dev_name, char *netmask);
STATUS get_local_macaddr(char *dev_name, char *mac);

STATUS get_local_ssh_port(unsigned int * port);
unsigned int get_local_ssh_enc_status(void);

extern int get_product_name(char *product_name);
extern int get_board_sn(char *sn);
extern int get_software_ver(char *ver);
extern int get_hardware_ver(char *ver);


#endif //__PROTOCOL_H

