#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <errno.h>

#include "libnetlinku.h"
#include "policyconf.h"
#include "commuapinl.h"

#ifdef NLDEBUG_ACK_COOKIES
#define CFG_DEBUG_ACK_COOKIES
#endif

struct upmnl_handle cfgnlh;


int set_cfg_debug_waitack()
{
	struct nlmsghdr *ack = NULL;	
	struct nlmsghdr **answer = &ack;	
	unsigned char debug_msg_type[]={"17"};/*需要发送的数据*/
	int msg_len = strlen((const char *)debug_msg_type);

	struct {
	  struct nlmsghdr	  n;
	  char			  buf[1024];
	} req = {
	  .n.nlmsg_len = NLMSG_LENGTH(0),
#ifdef CFG_DEBUG_ACK_COOKIES
	  	.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,/*set NLM_F_ACK:use kernel auto ack*/
#else
	  .n.nlmsg_flags = NLM_F_REQUEST,/*not use kernel auto ack*/
#endif
	  .n.nlmsg_type = COMMNMSG_CFG_DEBUGFS,
	  .n.nlmsg_pid = getpid(),
	};
	  
	printf("set_cfg_debug_waitack\r\n");

	/*可选属性*/
	commnl_addattr_l(&req.n, sizeof(req), NLDEBUG_MSG_TYPE, debug_msg_type, msg_len);
	
	printf("cfg send debugfs msg to kernel:srcip_len =%d.req.n.nlmsg_type =%d\r\n",msg_len,req.n.nlmsg_type);


	/*发送组装好的netlink消息*/
	if (commcfg_talk(&req.n, answer) < 0)
		{
		printf("set_cfg_debug_waitack rcv ack msg faild.\r\n");
		return -2;
		}
	else{
		printf("set_cfg_debug_waitack rcv ack msg sucess.\r\n");
		}

	if(*answer != NULL)
		{
		printf("set_cfg_debug_waitack rcv answer.\r\n");
		
		}
	else{
		printf("set_cfg_debug_waitack rcv answer error.\r\n");
		return -3;
	}


#ifdef CFG_DEBUG_ACK_COOKIES
		/*recv answer*/
		if((*answer)->nlmsg_type == NLMSG_ERROR){
			nl_debugfs_extack(*answer);
		}
		else{
			printf("set_cfg_debug_waitack nlmsg_type is=0x%x,not debugfsmsg ack.\r\n",ack->nlmsg_type);
		}
#else
		if((*answer)->nlmsg_type == COMMNMSG_CFG_DEBUGFS){
			nl_debugfs(*answer);	
		}
		else{
			printf("set_cfg_debug_waitack nlmsg_type is=0x%x,not COMMNMSG_CFG_DEBUGFS ack.\r\n",ack->nlmsg_type);
		}
#endif



	return 0;

}


int set_cfg_debug_nowaitack()
{
	unsigned char debug_msg_type[]={"17"};/*需要发送的数据*/
	int msg_len = strlen((const char *)debug_msg_type);

	struct {
	  struct nlmsghdr	  n;
	  struct policyconfmsg   ncm;
	  char			  buf[1024];
	} req = {
	  .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct policyconfmsg)),
	  .n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
	  .n.nlmsg_type = COMMNMSG_CFG_DEBUGFS,
	  .ncm.policy_id = 17,
	  .n.nlmsg_pid = getpid(),
	};
	  
	printf("set_cfg_debug_nowaitack\r\n");
	
	/*可选属性*/
	commnl_addattr_l(&req.n, sizeof(req), NLDEBUG_MSG_TYPE, debug_msg_type, msg_len);
	
	printf("msg_len =%d.req.n.nlmsg_type =%d\r\n",msg_len,req.n.nlmsg_type);
	
	/*发送组装好的netlink消息*/
	if (commcfg_send(&req.n) < 0)
		return -2;

	
	return 0;

}


int main( int argc, char **argv)
{	
	int ret = -1; 


	printf("cfgchannel main begin:\r\n");
	
	/*创建通道*/
	ret = commcfgnl_open();
	if(ret < 0)
	{
		printf("pdelivnl_open fail,exit.\r\n");
		return -1;
	}

	/*下发配置到内核态*/
	//ret = set_cfg_debug_nowaitack();
	ret = set_cfg_debug_waitack();
	if(ret < 0)
	{
		printf("set_cfg_debug_waitack failed.\r\n");
		return -1;
	}


	/*关闭netlink通道*/
	commcfgnl_close();

	printf("cfgchannel main exit!\r\n");
	return 0;
}