
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "kk_findccu_handle.h"
#include "kk_hal.h"
#include "cJSON.h"

static int kk_findccu_ack(int sockfd,struct sockaddr_in *addr){
	cJSON *json = NULL,*args = NULL;
	cJSON *ccu = NULL;
	char *out = NULL;
	char *tmpBuf = NULL;
	char s_IP[NETWORK_ADDR_LEN] = {0};
	if(addr == NULL || sockfd < 0){
		return -1;
	}
	char ccuid[32] = {0};
	kk_lan_get_ccuid(ccuid);
	json=cJSON_CreateObject();
	if(json){
		args = cJSON_CreateObject();
		if(args){
			cJSON_AddItemToObject(json, "arg", args);
			cJSON_AddStringToObject(args, "zkid", &ccuid[4]);
			cJSON_AddStringToObject(args, "zk", KK_CCU_NAME);
			HAL_Get_IP(s_IP,NULL);
			cJSON_AddStringToObject(args, "ip", s_IP); 
			cJSON_AddBoolToObject(args, "ssl", FALSE);
		}
		cJSON_AddStringToObject(json, "nodeid", "*");
		cJSON_AddStringToObject(json, "opcode", FINDCCU_OPCODE);
		cJSON_AddStringToObject(json, "status", "success");
		out=cJSON_Print(json);
		cJSON_Minify((char*)out);
		tmpBuf = calloc(strlen(out) + 4,1);
		if(tmpBuf == NULL){
			cJSON_Delete(json);
			free(out);
			return -1;
		}
		strcat(tmpBuf,"!");
		strcat(tmpBuf,out);
		strcat(tmpBuf,"$");
		INFO_PRINT("tmpBuf:%s\n",tmpBuf);
		sendto(sockfd, tmpBuf, strlen(tmpBuf), 0, (struct sockaddr*)addr, sizeof(struct sockaddr_in));
		cJSON_Delete(json);
		free(out);
		free(tmpBuf);
	}
	return 0;
}
void *kk_findccu_handle(void *data)
{
	int sockfd;
	struct sockaddr_in saddr;
	int r;
	char recvline[1025] = {0};
	char recvline_tmp[1025] = {0};
	struct sockaddr_in presaddr;
	socklen_t len;
	cJSON *json;
	cJSON *opcode;
	char *pStart = NULL,*pEnd = NULL;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	bzero(&saddr, sizeof(saddr));

	saddr.sin_family = AF_INET;
	saddr.sin_addr.s_addr = htonl(INADDR_ANY);
	saddr.sin_port = htons(FINDCCU_LOCAL_PORT);
	
	if(bind(sockfd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) 
	{
		ERROR_PRINT("bind error...\n"); 
	}
	while (1)
	{
		r = recvfrom(sockfd, recvline, sizeof(recvline), 0 , (struct sockaddr*)&presaddr, &len);
		if (r <= 0){
			WARNING_PRINT("read error....\n"); 
		}else{
			DEBUG_PRINT("findccu recmsg: %s\n", recvline); 
			pStart = strstr(recvline, "!");
			pEnd = strstr(recvline, "$");
			if(pStart != NULL && pEnd != NULL){
				memset(recvline_tmp,0x0,sizeof(recvline_tmp));
				memcpy(recvline_tmp,pStart+1,(pEnd - pStart - 1));
				json=cJSON_Parse(recvline_tmp);
				if (!json) {
					WARNING_PRINT("Error before: [%s]\n","cJSON_Parse");
				}else{
					opcode = cJSON_GetObjectItem(json, OPCODE_STRING);
					if(opcode != NULL){
						if(strcmp(opcode->valuestring,FINDCCU_OPCODE) == 0){
							kk_findccu_ack(sockfd,&presaddr);
						}
					}
					cJSON_Delete(json);
				}
			}else{
				WARNING_PRINT("data error....\n"); 
			}
		}

	}
	return NULL;
}

int kk_findccu_handle_init(void)
{
	int rc = 0;
	size_t s = 1500;
	pthread_t findccu_thread_handle;
	pthread_attr_t findccu_thread_attr;
	//pthread_mutex_init(&s_data_mutex, NULL);
	/*创建线程*/
	pthread_attr_init(&findccu_thread_attr);
	pthread_attr_setstacksize(&findccu_thread_attr, s);
	pthread_attr_setdetachstate(&findccu_thread_attr, PTHREAD_CREATE_DETACHED);
	rc = pthread_create(&findccu_thread_handle, &findccu_thread_attr, kk_findccu_handle, (void *)NULL);   //收数据
	if (rc)
	{
		WARNING_PRINT("Error : unable to create thread udp_recv \r\n");
		return -1;
	}
	pthread_attr_destroy(&findccu_thread_attr);
	return 0;
}