/*
 ============================================================================
 Name        : ble_ciss.c
 Author      : JinXin
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "myType.h"
#include "portserial.h"
#include "buffer_queue.h"
#include "mqtt.h"
#include "user_config.h"
#include <semaphore.h>
#include "at_command.h"
#include "watchdog.h"

static pthread_t thread_id_uart;
static pthread_t thread_id_ble;
static pthread_t thread_id_sendMqtt;

sem_t semSend;
sem_t semBle;

static AT_CMD_EVT_ENUM report_evt = 0;
static POST_DATA_TYPE_ENUM post_data_type = 0;

#define UART_BUFFER_SIZE 512

static CHAR UartRevBuffer[UART_BUFFER_SIZE] ={0};
static USHORT UartRevBytes = 0;

static int bFlagCommOver = 0;

static void thread_uart(void *pvParam)
{

	while(1)
	{
		prvbMBPortSerialRead(UartRevBuffer, UART_BUFFER_SIZE, &UartRevBytes);
		bFlagCommOver = 1;
		if(UartRevBytes > 0)
		{
			//printf("receive data size = %d\r\n", UartRevBytes);
			buffer_queue_PushBytes(UartRevBuffer, UartRevBytes);
			//printf("queue size = %d\r\n", buffer_queue_GetDataSize());
		}

		if(Uart_frame_over(UartRevBuffer, UartRevBytes))
		{

			UCHAR temp_buf_cmd[512] ={0};
			USHORT temp_len = buffer_queue_GetDataSize();

			//printf("command rev, and process start !\r\n");
			buffer_queue_PopBytes(temp_buf_cmd, temp_len);
			at_command_process(temp_buf_cmd, temp_len);


		}

		usleep(1000);
	}

	return;
}



static void thread_ble_state(void *pvParam)
{
	usleep(500000);
	///reset the ble module when process start working
	ciss_enable_RESET_Module();
	printf("wait ble disconnect<<<<<<<<<<<<\r\n");
	sleep(3);
	printf("10 seconds over >>>>>>>>>>>>>>>\r\n");

	/*
	printf("##############################\r\n");
	ciss_disconnect_dev(m_cfg_val.ciss_mac);
	printf("##############################\r\n");
	ciss_enable_IT_dev(m_cfg_val.ciss_mac);
	printf("##############################\r\n");
	ciss_enable_ET_dev(m_cfg_val.ciss_mac);
	printf("##############################\r\n");
	ciss_enable_sample_dev(m_cfg_val.ciss_mac, 100, 1);
	printf("##############################\r\n");
	*/
	while(1)
	{
		if(sem_wait(&semBle) == 0)
		{
			printf("@@@@@@@@@@@@@@@@@@@@@@@@--evt == %x !\r\n", report_evt);
			switch(report_evt)
			{
			case EVT_CONNECT_SUCCESS:
				usleep(100000);	///delay 100ms
				if((m_cfg_val.ciss_mode & 0x01) == 0x01)
					ciss_enable_IT_dev(m_cfg_val.ciss_mac, true);
				else
					ciss_enable_IT_dev(m_cfg_val.ciss_mac, false);
				break;
			case EVT_CONNECT_FAIL:
				sleep(3);	///delay 5s
				ciss_connect_dev(m_cfg_val.ciss_mac);
				break;
			case EVT_OPEN_IT_CH:
				usleep(100000);	///delay 100ms
				if((m_cfg_val.ciss_mode & 0x02) == 0x02)
					ciss_enable_ET_dev(m_cfg_val.ciss_mac, true);
				else
					ciss_enable_ET_dev(m_cfg_val.ciss_mac, false);
				break;
			case EVT_OPEN_ET_CH:
				usleep(100000);	///delay 100ms
				ciss_enable_sample_dev(m_cfg_val.ciss_mac, m_cfg_val.ciss_freq,
						m_cfg_val.ciss_mode);
				break;
			case EVT_START_SAMPLE:
				printf("start **********************!!\r\n");
				break;
			case EVT_STOP_SAMPLE:
				break;
			case EVT_DISCONNECT:
				sleep(2);	///delay 5s
				ciss_connect_dev(m_cfg_val.ciss_mac);
				break;
			case EVT_RESET:	///power on, and need wait 3 second, then connect again
				usleep(m_cfg_val.ciss_delay*1000);
				////start connect ciss
				printf("auto auto === %d!\r\n", m_cfg_val.ciss_auto);
				if(m_cfg_val.ciss_auto == 1)
				{
					printf("auto connect the ciss!\r\n");
					ciss_connect_dev(m_cfg_val.ciss_mac);
				}
				break;
			case EVT_CMD_ERROR:
				printf("start xxxxxxxxxxxxxxxxxxxxxx!!\r\n");
				break;
			}

		}
	}

	return;
}

static void thread_send_mqtt(void *pvParam)
{
	while(1)
	{
		if(sem_wait(&semSend) == 0)
		{
			//printf("mqtt-----------!\r\n");
			Mqtt_process();
		}
	}

	return;
}


void Ciss_data_post(POST_DATA_TYPE_ENUM typ)
{
	post_data_type = typ;
	sem_post(&semSend);
}

POST_DATA_TYPE_ENUM Ciss_get_post_data_type(void)
{
	return post_data_type;
}

void Ciss_ble_evt_post(AT_CMD_EVT_ENUM evt)
{
	report_evt = evt;
	sem_post(&semBle);
}


void Ciss_master_init(void)
{
	int ret = 0;

	sem_init(&semSend, 0, 0);
	sem_init(&semBle, 0, 0);

	ret=pthread_create(&thread_id_uart,NULL,(void  *) thread_uart,NULL);

	if(ret!=0)
	{
		printf("Create uart pthread error!\n");
		return ;
	}
	else
	{
		printf("Create uart pthread success!\n");
		///reset the ble module when process start working
		///ciss_enable_RESET_Module();
	}

	ret=pthread_create(&thread_id_ble,NULL,(void  *) thread_ble_state,NULL);
	if(ret!=0)
	{
		printf("Create ble pthread error!\n");
		return ;
	}
	else
	{
		printf("Create ble pthread success!\n");
	}

	ret=pthread_create(&thread_id_sendMqtt,NULL,(void  *) thread_send_mqtt,NULL);

	if(ret!=0)
	{
		printf("Create mqtt send pthread error!\n");
		return ;
	}
	else
	{
		printf("Create mqtt send pthread success!\n");
	}

}


int main(void)
{
	struct appsrv_connection *pCONN;

	////ini file init
	if(config_file_read() == 0)
	{
		printf("load config file data success!\r\n");
	}
	else
	{
		printf("can't read the config file!");
		config_file_default();
	}

	/* Add watchdog init by witium. */
	watchdog_init();

	///thread init
	Ciss_master_init();
	////mqtt init
	Mqtt_init();
	////uart init
	xMBPortSerialInit(5, 230400, 8, MB_PAR_NONE);

	////ble app init

	while(1)
	{
		sleep(10);
		/* Add watchdog refresh by witium. */
		watchdog_refresh(10); // refresh for 30 seconds.

	}
	return EXIT_SUCCESS;
}
