#include "sx127x_cmd_process.h"
#include <stdio.h>
#include <stdlib.h>
#include "radio.h"
#include "stm32f10x_it.h"
#include "delay.h"
#include "string.h"
#include "project_config.h"
#include "cJSON.h"
#include "HAL_uart.h"
#include "sx1276-board.h"
#include "sx1276.h"
#include "tb05_control.h"

#define PACKET_NUM 30 // how many packets need to send by default

#define LoRa_LED_PIN GPIO_Pin_8 
#define TB05_LED_PIN GPIO_Pin_15

#define RESPONE_STATUS 10

#define RADIO_OK 0
#define RADIO_FAILED -1

#define CMD_MAX_LENGTH 200
#define RESPONE_MAX_LENGTH 80
#define KEY_MAX_LENGTH 10

#define RADIO_SEND_CMD 1
#define RADIO_RECV_CMD 2
#define RADIO_CAD_CMD 3
#define RADIO_STANDBY_CMD 4
#define RADIO_SLEEP_CMD 5
#define UPDATE_CMD 6
// #define SEND_UPDATE_CMD 6
// #define RECV_UPDATE_CMD 7
// #define CAD_UPDATE_CMD 8

#define SEND_RESPONE_CMD 1
#define RECV_RESPONE_CMD 2
#define CAD_RESPONE_CMD 3
#define STANDBY_RESPONE_CMD 4
#define SLEEP_RESPONE_CMD 5

#define LoRaRxPeriod(time) time*0.015625
#define LoRaSleepPeriod(time) time * 0.015625

static uint8_t radio_init_already = 0;
static uint8_t radio_sleep_ready = 0;
static uint8_t radio_standby_ready = 0;
int g_lora_tx_done = 0;
int g_lora_rx_done = 0;
int g_lora_cad = 0;
uint32_t g_cad_count = 0;

LED_Status_t LoRa_LED_Status = LOW;

typedef enum
{
	IDELE = 0,
	TX_MODE = 1,
	RX_MODE,
	CAD_MODE,
	STAND_BY,
	DEEPSLEEP,
} LoRa_mode_t;
LoRa_mode_t LoRa_realtime_Mode = IDELE;

typedef enum
{
	LOWPOWER,
	RX_DONE,
	RX_TIMEOUT,
	RX_ERROR,
	TX_DONE,
	TX_TIMEOUT,
	CAD_DONE,
} States_t;
States_t State = LOWPOWER;

char *LoRa_Mode_String[6] = {"IDELE", "TX_MODE", "RX_MODE", "CAD_MODE", "STAND_BY", "DEEPSLEEP"};

typedef struct
{
	int modem; // FSK or LoRa
	uint32_t freq;
	int bandwidth;
	int sf;
	int coderate;
	int preambleLen;
	int packetID;
	int packet_rssi;
	int packet_snr;
	int packetNum;
	struct
	{
		char buffer[200];
		int bufferLen;
		int power;
		int interval; // period of tx
	} tx_process_data;

	struct
	{
		uint32_t rxPeriod;
		uint32_t sleepPeriod;
	} cad_process_data;
} Radio_peocess_t;
Radio_peocess_t _radio_peocess = {0};

static RadioEvents_t LoRaRadioEvents;
void radio_status_upload(int type);

/**************************************************/
void LoRa_Timer_init(u16 arr, u16 psc)
{
  	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	TIM2->CR1 |= TIM_CR1_URS;

	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler =psc;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

	//config IRQ PARAMS
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

	TIM_Cmd(TIM2, ENABLE); //
}

void LED_Blink_Start(uint32_t timeoutMs) {
	LoRa_Timer_init((timeoutMs * 10) - 1, 7199);
}

void LED_Blink_Stop(void)
{
	TIM_Cmd(TIM2, DISABLE);
}

void LoRa_LED_Status_set(void)
{
	static bool ble_blink = 0, lora_blink = 0;
	LED_Status_t BLE_STATUS = BLE_STATUS_get();
	switch (LoRa_LED_Status)
	{
	case LOW:
		GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_RESET);
		break;
	case HIGH:
		GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_SET);
		break;
	case TOGGLE:
		if (0 == lora_blink)
		{
			GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_RESET);
			lora_blink = 1;
		}
		else
		{
			GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_SET);
			lora_blink = 0;
		}
		break;
	default:
		break;
	}

	switch (BLE_STATUS)
	{
	case LOW:
		GPIO_WriteBit(GPIOB, TB05_LED_PIN, Bit_RESET);
		break;
	case HIGH:
		GPIO_WriteBit(GPIOB, TB05_LED_PIN, Bit_SET);
		break;
	case TOGGLE:
		if (0 == ble_blink)
		{
			GPIO_WriteBit(GPIOB, TB05_LED_PIN, Bit_RESET);
			ble_blink = 1;
		}
		else
		{
			GPIO_WriteBit(GPIOB, TB05_LED_PIN, Bit_SET);
			ble_blink = 0;
		}
		break;
	default:
		break;
	}
}

void TIM2_IRQHandler(void) ////config IRQ HANDLERS
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
		LoRa_LED_Status_set();
	}
}

/**************************************************/
void rxCycle_Timer_init(u16 arr, u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	TIM4->CR1 |= TIM_CR1_URS;

	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler = psc;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

	// config IRQ PARAMS
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

	TIM_Cmd(TIM4, ENABLE); //
}

void rxPeriod_Stop(void)
{
	TIM_Cmd(TIM4, DISABLE);
}

void sleepPeriod_Stop(void)
{
	TIM_Cmd(TIM4, DISABLE);
}

void rxPeriod_Start(uint32_t timeoutMs)
{
	g_lora_cad = 1;
	Radio.Rx(timeoutMs);
	rxCycle_Timer_init((timeoutMs * 10) - 1, 7199);
}

void sleepPeriod_Start(uint32_t timeoutMs)
{
	g_lora_cad = 0;
	Radio.Sleep();
	rxCycle_Timer_init((timeoutMs * 10) - 1, 7199);
}

void TIM4_IRQHandler(void) ////config IRQ HANDLERS
{
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
		TIM_Cmd(TIM4, DISABLE);
		if (CAD_MODE == LoRa_realtime_Mode)
		{
			switch (g_lora_cad)
			{
			case 0:
				// GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_RESET);
				rxPeriod_Start(LoRaRxPeriod(_radio_peocess.cad_process_data.rxPeriod));
				g_lora_cad = 1;
				break;
			case 1:
				// GPIO_WriteBit(GPIOA, LoRa_LED_PIN, Bit_SET);
				sleepPeriod_Start(LoRaSleepPeriod(_radio_peocess.cad_process_data.sleepPeriod));
				g_lora_cad = 0;
				break;
			default:
				break;
			}
		}
	}
}

/**************************************************/
/* STATUS LED */
void LoRa_LED_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = LoRa_LED_PIN;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = TB05_LED_PIN;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	LED_Blink_Start(100);
}

void LoRaOnCadDone(bool channelActivityDetected)
{
	Radio.Rx(LORA_RX_TIMEOUT_VALUE);
	Radio.Standby();
	State = CAD_DONE;
	printf("CadDone\r\n");
}

void LoRaOnTxDone(void)
{
	LoRa_LED_Status = TOGGLE;
	Radio.Sleep();
	State = TX_DONE;
	printf("TxDone\r\n");
}

void LoRaOnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
{
	LoRa_LED_Status = TOGGLE;
	_radio_peocess.packet_rssi = rssi;
	_radio_peocess.packet_snr = snr;
	Radio.Sleep();
	State = RX_DONE;
	if (CAD_MODE == LoRa_realtime_Mode)
	{
		g_cad_count = 0;
	}
	printf("RxDone\r\nrssi:%d\r\nsnr:%d\r\nsize:%d\r\ndata:payload:%s\r\n", rssi, snr, size, payload);
}

void LoRaOnTxTimeout(void)
{
	LoRa_LED_Status = LOW;
	Radio.Sleep();
	State = TX_TIMEOUT;
	printf("TxTIMEOUT\r\n");
}

void LoRaOnRxTimeout(void)
{
	LoRa_LED_Status = LOW;
	Radio.Sleep();
	State = RX_TIMEOUT;
}

void LoRaOnRxError(void)
{
	LoRa_LED_Status = LOW;
	Radio.Sleep();
	State = RX_ERROR;
	printf("RxError\r\n");
}

void LoRa_state_process(void)
{
	switch (State)
	{
	case TX_DONE:
		g_lora_tx_done = 1;
		g_lora_rx_done = 0;
		_radio_peocess.packetID++;
		if (_radio_peocess.packetID <= _radio_peocess.packetNum)
		{
			radio_status_upload(SEND_RESPONE_CMD);
		}
		State = LOWPOWER;
		break;
	case TX_TIMEOUT:
		if (TX_MODE == LoRa_realtime_Mode)
		{
			Radio.Send((uint8_t *)_radio_peocess.tx_process_data.buffer, _radio_peocess.tx_process_data.bufferLen);
		}
		State = LOWPOWER;
		break;
	case RX_DONE:
		g_lora_tx_done = 0;
		g_lora_rx_done = 1;
		if (RX_MODE == LoRa_realtime_Mode || CAD_MODE == LoRa_realtime_Mode)
		{
			// if (_radio_peocess.packetID < _radio_peocess.packetNum)
			// {
				_radio_peocess.packetID++;
				radio_status_upload(RECV_RESPONE_CMD);
				Radio.Rx(LORA_RX_TIMEOUT_VALUE);
			// }
		}
		State = LOWPOWER;
		break;
	case RX_TIMEOUT:
		if (RX_MODE == LoRa_realtime_Mode)
		{
			Radio.Rx(LORA_RX_TIMEOUT_VALUE);
		}
		State = LOWPOWER;
		break;
	case RX_ERROR:
		if (RX_MODE == LoRa_realtime_Mode)
		{
			Radio.Rx(LORA_RX_TIMEOUT_VALUE);
		}
		State = LOWPOWER;
		break;
	case CAD_DONE:
		// Radio.Rx(LORA_RX_TIMEOUT_VALUE);
		radio_status_upload(CAD_RESPONE_CMD);
		State = LOWPOWER;
		break;
	default:
		delay_ms(10);
		break;
	}
}

/* LoRa module init */
static void LoRaRadioInit(void)
{
	if (0 == radio_init_already)
	{
		LoRaRadioEvents.TxDone = LoRaOnTxDone;
		LoRaRadioEvents.RxDone = LoRaOnRxDone;
		LoRaRadioEvents.TxTimeout = LoRaOnTxTimeout;
		LoRaRadioEvents.RxTimeout = LoRaOnRxTimeout;
		LoRaRadioEvents.RxError = LoRaOnRxError;
		LoRaRadioEvents.CadDone = LoRaOnCadDone;
		LoRa_LED_init();
		Radio.Init(&LoRaRadioEvents);
		radio_init_already = 1;
		printf("RadioInit\r\n");
	}
	else
	{
		Radio.ReInit();
		printf("RadioReInit\r\n");
	}
}

int radio_tx_process(void)
{
	if (1 == radio_sleep_ready)
	{
		radio_sleep_ready = 0;
		radio_status_upload(SLEEP_RESPONE_CMD);
	}
	if (1 == radio_standby_ready)
	{
		radio_standby_ready = 0;
		radio_status_upload(STANDBY_RESPONE_CMD);
	}
	LoRaRadioInit();
	Radio.Standby();
	switch (_radio_peocess.modem)
	{
	case 0:
		return RADIO_FAILED;
	case 1:
		if (_radio_peocess.freq < 410000000 || _radio_peocess.freq > 930000000)
		{
			printf("error freq\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.sf < 5 || _radio_peocess.sf > 12)
		{
			printf("error sf\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.bandwidth < 0 || _radio_peocess.bandwidth > 2)
		{
			printf("error bandwidth\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.coderate < 1 || _radio_peocess.coderate > 4)
		{
			printf("error coderate\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.tx_process_data.power < 0 || _radio_peocess.tx_process_data.power > 22)
		{
			printf("error power\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.preambleLen < 1 || _radio_peocess.preambleLen > 500)
		{
			printf("error preambleLen\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.packetNum < 1)
		{
			printf("error packetNum\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.tx_process_data.interval < 1)
		{
			printf("error interval\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.tx_process_data.bufferLen < 1)
		{
			printf("error bufferLen\r\n");
			return RADIO_FAILED;
		}
		// if (TX_MODE == LoRa_realtime_Mode)
		// {
		// 	SX1276RxTimeoutTimerStop();
		// }
		Radio.SetChannel(_radio_peocess.freq);
		Radio.SetTxConfig(MODEM_LORA, _radio_peocess.tx_process_data.power, 0, _radio_peocess.bandwidth,
						  _radio_peocess.sf, _radio_peocess.coderate,
						  _radio_peocess.preambleLen, LORA_FIX_LENGTH_PAYLOAD_ON,
						  true, 0, 0, LORA_IQ_INVERSION_ON, 1000);
		Radio.Send((uint8_t *)_radio_peocess.tx_process_data.buffer, _radio_peocess.tx_process_data.bufferLen);
		return RADIO_OK;
	default:
		return RADIO_FAILED;
	}
}

int radio_rx_process(void)
{
	if (1 == radio_sleep_ready)
	{
		radio_sleep_ready = 0;
		radio_status_upload(SLEEP_RESPONE_CMD);
	}
	if (1 == radio_standby_ready)
	{
		radio_standby_ready = 0;
		radio_status_upload(STANDBY_RESPONE_CMD);
	}
	LoRaRadioInit();
	Radio.Standby();
	switch (_radio_peocess.modem)
	{
	case 0:
		return RADIO_FAILED;
	case 1:
		if (_radio_peocess.freq < 410000000 || _radio_peocess.freq > 930000000)
		{
			return RADIO_FAILED;
		}
		if (_radio_peocess.sf < 5 || _radio_peocess.sf > 12)
		{
			return RADIO_FAILED;
		}
		if (_radio_peocess.bandwidth < 0 || _radio_peocess.bandwidth > 2)
		{
			return RADIO_FAILED;
		}
		if (_radio_peocess.coderate < 1 || _radio_peocess.coderate > 4)
		{
			return RADIO_FAILED;
		}
		if (_radio_peocess.preambleLen < 1 || _radio_peocess.preambleLen > 500)
		{
			return RADIO_FAILED;
		}
		if (_radio_peocess.packetNum < 1)
		{
			return RADIO_FAILED;
		}
		// if (RX_MODE == LoRa_realtime_Mode)
		// {
		// 	SX1276TxTimeoutTimerStop();
		// }
		Radio.SetChannel(_radio_peocess.freq);
		Radio.SetRxConfig(MODEM_LORA, _radio_peocess.bandwidth, _radio_peocess.sf,
						  _radio_peocess.coderate, 0, _radio_peocess.preambleLen,
						  LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
						  0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
		Radio.Rx(LORA_RX_TIMEOUT_VALUE);
		printf("start radio receive modem: %s, freq: %d\r\n", (_radio_peocess.modem == 1) ? "LoRa" : " FSK", _radio_peocess.freq);
		printf("start radio transmit bandwidth: %d, sf: %d, coderate: %d, preambleLen: %d\r\n", _radio_peocess.bandwidth, _radio_peocess.sf, _radio_peocess.coderate, _radio_peocess.preambleLen);
		return RADIO_OK;
	default:
		return RADIO_FAILED;
	}
}

int radio_cad_process(void)
{
	if (1 == radio_sleep_ready)
	{
		radio_sleep_ready = 0;
		radio_status_upload(SLEEP_RESPONE_CMD);
	}
	if (1 == radio_standby_ready)
	{
		radio_standby_ready = 0;
		radio_status_upload(STANDBY_RESPONE_CMD);
	}
	LoRaRadioInit();
	Radio.Standby();
	printf("freq:%d \r\n", _radio_peocess.freq);
	printf("sf:%d\r\n", _radio_peocess.sf);
	printf("bandwidth:%d\r\n", _radio_peocess.bandwidth);
	printf("coderate:%d\r\n", _radio_peocess.coderate);
	printf("preambleLen:%d\r\n", _radio_peocess.preambleLen);
	printf("rxPeriod:%d\r\n", _radio_peocess.cad_process_data.rxPeriod);
	printf("sleepPeriod:%d\r\n", _radio_peocess.cad_process_data.sleepPeriod);
	switch (_radio_peocess.modem)
	{
	case 0:
		return RADIO_FAILED;
	case 1:
		if (_radio_peocess.freq < 410000000 || _radio_peocess.freq > 930000000)
		{
			printf("freq RADIO_FAILED\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.sf < 5 || _radio_peocess.sf > 12)
		{
			printf("sf RADIO_FAILED\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.bandwidth < 0 || _radio_peocess.bandwidth > 2)
		{
			printf("bandwidth RADIO_FAILED\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.coderate < 1 || _radio_peocess.coderate > 4)
		{
			printf("coderate RADIO_FAILED\r\n");
			return RADIO_FAILED;
		}
		if (_radio_peocess.preambleLen < 1 || _radio_peocess.preambleLen > 500)
		{
			printf("preambleLen RADIO_FAILED: %d\r\n", _radio_peocess.preambleLen);
			return RADIO_FAILED;
		}
		if (_radio_peocess.cad_process_data.rxPeriod < 1)
		{
			printf("rxPeriod RADIO_FAILED:%d \r\n", _radio_peocess.cad_process_data.rxPeriod);
			return RADIO_FAILED;
		}
		if (_radio_peocess.cad_process_data.sleepPeriod < 1)
		{
			printf("sleepPeriod RADIO_FAILED: %d\r\n", _radio_peocess.cad_process_data.sleepPeriod);
			return RADIO_FAILED;
		}
		// Ra03sch_RxMode_Set();
		Radio.SetChannel(_radio_peocess.freq);
		Radio.SetRxConfig(MODEM_LORA, _radio_peocess.bandwidth, _radio_peocess.sf,
						  _radio_peocess.coderate, 0, _radio_peocess.preambleLen,
						  LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
						  0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
		// SX1276StartCad();
		// Radio.Rx(LORA_RX_TIMEOUT_VALUE);
		rxPeriod_Start(LoRaRxPeriod(_radio_peocess.cad_process_data.rxPeriod));
		//		SetCadParams(LORA_CAD_02_SYMBOL, 22, 10, LORA_CAD_RX, 192000);
		//		Radio.SetRxDutyCycle(_radio_peocess.cad_process_data.rxPeriod, _radio_peocess.cad_process_data.sleepPeriod);
		printf("start radio cad\r\n");
		return RADIO_OK;
	default:
		return RADIO_FAILED;
	}
}

int radio_standby_process(void)
{
	if (1 == radio_sleep_ready)
	{
		radio_sleep_ready = 0;
		radio_status_upload(SLEEP_RESPONE_CMD);
	}
	LoRaRadioInit();
	Radio.Standby();
	radio_standby_ready = 1;
	return RADIO_OK;
}

int radio_sleep_process(void)
{
	if (1 == radio_standby_ready)
	{
		radio_standby_ready = 0;
		radio_status_upload(STANDBY_RESPONE_CMD);
	}
	LoRaRadioInit();
	Radio.Sleep();
	radio_sleep_ready = 1;
	return RADIO_OK;
}

void tb05_status_respone(int type, int status)
{
	char cmd_data[RESPONE_MAX_LENGTH] = {0};
	memset(cmd_data, 0, RESPONE_MAX_LENGTH);
	if (type > 0 && type < 6)
	{
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\": %d,\"status\":%d}", type, status);
		tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1));
	}
}

/* reporting the operating status */
void radio_status_upload(int type)
{
	char cmd_data[RESPONE_MAX_LENGTH] = {0};
	float per = 0, temp = 0;
	memset(cmd_data, 0, RESPONE_MAX_LENGTH);
	switch (type)
	{
	case SEND_RESPONE_CMD:
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\":21,\"TxDoneNum\":%d}", _radio_peocess.packetID);
		if (0 == tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1)))
			printf("SEND_RESPONE_CMD status upload\r\n");
		break;
	case RECV_RESPONE_CMD:
		temp = (_radio_peocess.packetNum - _radio_peocess.packetID) * 100;
		per = temp / _radio_peocess.packetNum;
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\":22,\"rssi\":%d,\"snr\":%d,\"RxNum\":%d,\"per\":%02f}", _radio_peocess.packet_rssi, _radio_peocess.packet_snr, _radio_peocess.packetID, per);
		if (0 == tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1)))
			printf("RECV_RESPONE_CMD status upload, temp: %02f, per: %02f\r\n", temp, per);
		break;
	case CAD_RESPONE_CMD:
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\":23,\"rssi\":%d,\"snr\":%d,\"awake\":1,\"RxNum\":%d}", _radio_peocess.packet_rssi, _radio_peocess.packet_snr, _radio_peocess.packetID);
		if (0 == tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1)))
			printf("CAD_RESPONE_CMD status upload\r\n");
		break;
	case STANDBY_RESPONE_CMD:
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\":24,\"awake\":1}");
		if (0 == tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1)))
			printf("STANDBY_RESPONE_CMD status upload\r\n");
		break;
	case SLEEP_RESPONE_CMD:
		snprintf(cmd_data, sizeof(cmd_data), "{\"type\":25,\"awake\":1}");
		if (0 == tb05_radio_respone(cmd_data, (strlen(cmd_data) + 1)))
			printf("SLEEP_RESPONE_CMD status upload\r\n");
		break;
	default:
		break;
	}
	// free(cmd_data);
}

/* upload all config once connected (Synchronous configuration) */
void radio_setting_update(LoRa_mode_t realtime_Mode)
{
	// char cmd_data[200] = "{\"type\":1,\"modem\":1,\"frq\":\"470000000\",\"sf\":7,\"bw\":0,\"cr\":1,\"pwr\":22,\"preambleLength\":8,\"packetNum\":101,\"interval\":200,\"dataLength\":5,\"data\":\"hello\"}";
	int JSON_Length = 0;
	cJSON *root = cJSON_CreateObject();
	cJSON_AddItemToObject(root, "type", cJSON_CreateNumber(realtime_Mode)); // add tpye
	printf("update setting\r\n");
	switch (realtime_Mode)
	{
	case TX_MODE:
		cJSON_AddItemToObject(root, "modem", cJSON_CreateNumber(_radio_peocess.modem));
		cJSON_AddItemToObject(root, "frq", cJSON_CreateNumber(_radio_peocess.freq));
		cJSON_AddItemToObject(root, "sf", cJSON_CreateNumber(_radio_peocess.sf));
		cJSON_AddItemToObject(root, "bw", cJSON_CreateNumber(_radio_peocess.bandwidth));
		cJSON_AddItemToObject(root, "cr", cJSON_CreateNumber(_radio_peocess.coderate));
		cJSON_AddItemToObject(root, "pwr", cJSON_CreateNumber(_radio_peocess.tx_process_data.power));
		cJSON_AddItemToObject(root, "preambleLength", cJSON_CreateNumber(_radio_peocess.preambleLen));
		cJSON_AddItemToObject(root, "packetNum", cJSON_CreateNumber(_radio_peocess.packetNum));
		cJSON_AddItemToObject(root, "interval", cJSON_CreateNumber(_radio_peocess.tx_process_data.interval));
		cJSON_AddItemToObject(root, "dataLength", cJSON_CreateNumber(_radio_peocess.tx_process_data.bufferLen));
		cJSON_AddItemToObject(root, "data", cJSON_CreateString(_radio_peocess.tx_process_data.buffer));
		break;
	case RX_MODE:
		// printf("send RX_MODE data: ");
		cJSON_AddItemToObject(root, "modem", cJSON_CreateNumber(_radio_peocess.modem));
		cJSON_AddItemToObject(root, "frq", cJSON_CreateNumber(_radio_peocess.freq));
		cJSON_AddItemToObject(root, "sf", cJSON_CreateNumber(_radio_peocess.sf));
		cJSON_AddItemToObject(root, "bw", cJSON_CreateNumber(_radio_peocess.bandwidth));
		cJSON_AddItemToObject(root, "cr", cJSON_CreateNumber(_radio_peocess.coderate));
		cJSON_AddItemToObject(root, "preambleLength", cJSON_CreateNumber(_radio_peocess.preambleLen));
		cJSON_AddItemToObject(root, "packetNum", cJSON_CreateNumber(_radio_peocess.packetNum));
		break;
	case CAD_MODE:
		// printf("send CAD_MODE data: ");
		cJSON_AddItemToObject(root, "modem", cJSON_CreateNumber(_radio_peocess.modem));
		cJSON_AddItemToObject(root, "frq", cJSON_CreateNumber(_radio_peocess.freq));
		cJSON_AddItemToObject(root, "sf", cJSON_CreateNumber(_radio_peocess.sf));
		cJSON_AddItemToObject(root, "bw", cJSON_CreateNumber(_radio_peocess.bandwidth));
		cJSON_AddItemToObject(root, "cr", cJSON_CreateNumber(_radio_peocess.coderate));
		cJSON_AddItemToObject(root, "preambleLength", cJSON_CreateNumber(_radio_peocess.preambleLen));
		cJSON_AddItemToObject(root, "rxPeriod", cJSON_CreateNumber(_radio_peocess.cad_process_data.rxPeriod));
		cJSON_AddItemToObject(root, "sleepPeriod", cJSON_CreateNumber(_radio_peocess.cad_process_data.sleepPeriod));
		break;
	case STAND_BY: //{"type":4}
		// printf("send STAND_BY data: ");
		break;
	case DEEPSLEEP: //{"type":5}
		// printf("send DEEPSLEEP data: ");
		break;
	default:
		break;
	}
	char *json_data = cJSON_PrintUnformatted(root);
	// printf("send json_data: %s\r\n", json_data);
	JSON_Length = strlen(json_data);
	if (realtime_Mode > 1 || realtime_Mode < 6)
	{
		tb05_radio_respone(json_data, JSON_Length);
	}
	free(json_data);
	cJSON_free(root);
}

/* send data by default when power on */
void LoRa_init_process(void)
{
	// /*
	memset(&_radio_peocess, 0, sizeof(Radio_peocess_t));

	_radio_peocess.modem = LORA_MODE;
	_radio_peocess.freq = LORA_FRE;
	_radio_peocess.tx_process_data.power = LORA_TX_OUTPUT_POWER;
	_radio_peocess.bandwidth = LORA_BANDWIDTH;
	_radio_peocess.sf = LORA_SPREADING_FACTOR;
	_radio_peocess.coderate = LORA_CODINGRATE;
	_radio_peocess.tx_process_data.interval = TX_INTERVAL;
	_radio_peocess.preambleLen = LORA_PREAMBLE_LENGTH;
	memcpy(_radio_peocess.tx_process_data.buffer, TX_BUFFER, sizeof(TX_BUFFER));
	_radio_peocess.tx_process_data.bufferLen = TX_BUFFER_LEN;
	_radio_peocess.packetID = 0;
	_radio_peocess.packet_rssi = 0;
	_radio_peocess.packet_snr = 0;
	_radio_peocess.packetNum = PACKET_NUM;
	LoRaRadioInit();

	Radio.SetChannel(_radio_peocess.freq);
	Radio.SetTxConfig(MODEM_LORA, _radio_peocess.tx_process_data.power, 0, _radio_peocess.bandwidth,
					  _radio_peocess.sf, _radio_peocess.coderate,
					  _radio_peocess.preambleLen, LORA_FIX_LENGTH_PAYLOAD_ON,
					  true, 0, 0, LORA_IQ_INVERSION_ON, 60000);
	printf("start radio transmit modem: %s, freq: %d\r\n", (_radio_peocess.modem == 1) ? "LoRa" : " FSK", _radio_peocess.freq);
	printf("start radio transmit power: %d, bandwidth: %d, sf: %d, coderate: %d, preambleLen: %d\r\n", _radio_peocess.tx_process_data.power, _radio_peocess.bandwidth, _radio_peocess.sf, _radio_peocess.coderate, _radio_peocess.preambleLen);
	// printf("start radio transmit length: %d,body: %s\r\n", _radio_peocess.tx_process_data.bufferLen, _radio_peocess.tx_process_data.buffer);
	Radio.Send((uint8_t *)_radio_peocess.tx_process_data.buffer, _radio_peocess.tx_process_data.bufferLen);
	LoRa_realtime_Mode = TX_MODE;
	// */
	/*
	memset(&_radio_peocess, 0, sizeof(Radio_peocess_t));
	_radio_peocess.modem = LORA_MODE;
	_radio_peocess.freq = LORA_FRE;
	_radio_peocess.bandwidth = LORA_BANDWIDTH;
	_radio_peocess.sf = LORA_SPREADING_FACTOR;
	_radio_peocess.coderate = LORA_CODINGRATE;
	_radio_peocess.preambleLen = LORA_PREAMBLE_LENGTH;
	_radio_peocess.packetID = 0;
	_radio_peocess.packetNum = 100;
	_radio_peocess.cad_process_data.rxPeriod = 1280; // n*15.625   20ms
	_radio_peocess.cad_process_data.sleepPeriod = 16000; // n*15.625 280ms
	LoRaRadioInit();

	Radio.SetChannel(_radio_peocess.freq);
	Radio.SetRxConfig(MODEM_LORA, _radio_peocess.bandwidth, _radio_peocess.sf,
	_radio_peocess.coderate, 0, _radio_peocess.preambleLen,
	LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
	0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
	Radio.Rx(LORA_RX_TIMEOUT_VALUE);
	LoRa_realtime_Mode = RX_MODE;
	printf("start radio transmit modem: %s, freq: %d\r\n", (_radio_peocess.modem == 1) ? "LoRa" : " FSK", _radio_peocess.freq);
	printf("start radio bandwidth: %d, sf: %d, coderate: %d, preambleLen: %d\r\n", _radio_peocess.bandwidth, _radio_peocess.sf, _radio_peocess.coderate, _radio_peocess.preambleLen);
	*/
	/*
	uint32_t cad_rxPeriod_ms = 0;

	memset(&_radio_peocess, 0, sizeof(Radio_peocess_t));
	_radio_peocess.modem = LORA_MODE;
	_radio_peocess.freq = LORA_FRE;
	_radio_peocess.bandwidth = LORA_BANDWIDTH;
	_radio_peocess.sf = LORA_SPREADING_FACTOR;
	_radio_peocess.coderate = LORA_CODINGRATE;
	_radio_peocess.preambleLen = LORA_PREAMBLE_LENGTH;
	_radio_peocess.packetID = 0;
	_radio_peocess.packetNum = 100;
	_radio_peocess.cad_process_data.rxPeriod = 12800;	 // n*15.625   200ms
	_radio_peocess.cad_process_data.sleepPeriod = 12000; // n*15.625 250ms
	cad_rxPeriod_ms = LoRaRxPeriod(_radio_peocess.cad_process_data.rxPeriod);
	LoRaRadioInit();

	Radio.SetChannel(_radio_peocess.freq);
	Radio.SetRxConfig(MODEM_LORA, _radio_peocess.bandwidth, _radio_peocess.sf,
					  _radio_peocess.coderate, 0, _radio_peocess.preambleLen,
					  LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
					  0, true, 0, 0, LORA_IQ_INVERSION_ON, true);

	// Radio.Standby();
	// SX1276StartCad();
	// Radio.Rx(LORA_RX_TIMEOUT_VALUE);
	LoRa_realtime_Mode = CAD_MODE;
	printf("start radio transmit modem: %s, freq: %d\r\n", (_radio_peocess.modem == 1) ? "LoRa" : " FSK", _radio_peocess.freq);
	printf("start radio bandwidth: %d, sf: %d, coderate: %d, preambleLen: %d\r\n", _radio_peocess.bandwidth, _radio_peocess.sf, _radio_peocess.coderate, _radio_peocess.preambleLen);
	// int i = 0;
	printf("CAD RX PERIOD TIME: %d\r\n", cad_rxPeriod_ms);
	Radio.Standby();
	rxPeriod_Start(cad_rxPeriod_ms);
	// SX1276StartCad();
	// printf("lora IRQ Status:%02x\r\n", Radio.GetStatus());
	// while(1){
	// 	// if(i++ > 82){
	// 	// 	i = 0;
	// 		Radio.Standby();
	// 		SX1276StartCad();
	// 		printf("lora IRQ Status:%02x\r\n", Radio.GetStatus());
	// 	// }
	// 	delay_ms(820);
	// }
	*/
}

/*lora config data parse and process*/
void LoRa_cmd_process(void)
{
	char radio_freq[KEY_MAX_LENGTH] = {0};
	char radio_data[KEY_MAX_LENGTH] = {0};
	char radio_preambleLen[KEY_MAX_LENGTH] = {0};
	int cmd_type_int = 0, key_len = 0;
	cJSON *pJsonRoot, *pJSON_cmd_type, *pJSON_radio_modem, *pJSON_radio_freq,
		*pJSON_radio_sf, *pJSON_radio_bw, *pJSON_radio_cr, *pJSON_radio_power,
		*pJSON_radio_packetNum, *pJSON_radio_interval, *pJSON_radio_dataLen,
		*pJSON_radio_data, *pJSON_radio_preambleLen;
	memset(radio_freq, 0, KEY_MAX_LENGTH);
	memset(radio_data, 0, KEY_MAX_LENGTH);
	memset(radio_preambleLen, 0, KEY_MAX_LENGTH);
	// printf("Got cmd length: %d\r\nbody: %s\r\n", TB05_Fram_Record_Struct.InfBit.FramLength, TB05_Fram_Record_Struct.Data_RX_BUF);
	pJsonRoot = cJSON_Parse(TB05_Fram_Record_Struct.Data_RX_BUF);
	if (pJsonRoot != NULL)
	{
		pJSON_cmd_type = cJSON_GetObjectItem(pJsonRoot, "type");
		if (pJSON_cmd_type != NULL)
		{
			cmd_type_int = pJSON_cmd_type->valueint;
			switch (cmd_type_int)
			{
			case RADIO_SEND_CMD:
				printf("RADIO_SEND_CMD\r\n");
				// {
				// 	"type":1,
				// 	"modem":1,
				// 	"frq":"470000000",
				// 	"sf":7,
				// 	"bw":0,
				// 	"cr":1,
				// 	"pwr":22,
				//  "preambleLength":8,
				// 	"packetNum":101,
				// 	"interval":200,
				// 	"dataLength":5,
				// 	"data":"hello"
				// }
				pJSON_radio_modem = cJSON_GetObjectItem(pJsonRoot, "modem");
				if (pJSON_radio_modem != NULL)
				{
					_radio_peocess.modem = pJSON_radio_modem->valueint;
					printf("Got cmd modem: %d\r\n", _radio_peocess.modem);
				}
				pJSON_radio_freq = cJSON_GetObjectItem(pJsonRoot, "frq");
				if (pJSON_radio_freq != NULL)
				{
					key_len = strlen(pJSON_radio_freq->valuestring);
					memcpy(radio_freq, pJSON_radio_freq->valuestring, key_len);
					radio_freq[key_len + 1] = '\0';
					_radio_peocess.freq = atol(radio_freq);
					printf("Got cmd frq: %u\r\n", _radio_peocess.freq);
				}
				pJSON_radio_sf = cJSON_GetObjectItem(pJsonRoot, "sf");
				if (pJSON_radio_sf != NULL)
				{
					_radio_peocess.sf = pJSON_radio_sf->valueint;
					printf("Got cmd sf: %d\r\n", _radio_peocess.sf);
				}
				pJSON_radio_bw = cJSON_GetObjectItem(pJsonRoot, "bw");
				if (pJSON_radio_bw != NULL)
				{
					_radio_peocess.bandwidth = pJSON_radio_bw->valueint;
					printf("Got cmd bw: %d\r\n", _radio_peocess.bandwidth);
				}
				pJSON_radio_cr = cJSON_GetObjectItem(pJsonRoot, "cr");
				if (pJSON_radio_cr != NULL)
				{
					_radio_peocess.coderate = pJSON_radio_cr->valueint;
					printf("Got cmd cr: %d\r\n", _radio_peocess.coderate);
				}
				pJSON_radio_preambleLen = cJSON_GetObjectItem(pJsonRoot, "preambleLength");
				if (pJSON_radio_preambleLen != NULL)
				{
					_radio_peocess.preambleLen = pJSON_radio_preambleLen->valueint;
					printf("Got cmd preambleLen: %d\r\n", _radio_peocess.preambleLen);
				}
				pJSON_radio_power = cJSON_GetObjectItem(pJsonRoot, "pwr");
				if (pJSON_radio_power != NULL)
				{
					_radio_peocess.tx_process_data.power = pJSON_radio_power->valueint;
					printf("Got cmd pwr: %d\r\n", _radio_peocess.tx_process_data.power);
				}
				pJSON_radio_packetNum = cJSON_GetObjectItem(pJsonRoot, "packetNum");
				if (pJSON_radio_packetNum != NULL)
				{
					_radio_peocess.packetNum = pJSON_radio_packetNum->valueint;
					printf("Got cmd packetNum: %d\r\n", _radio_peocess.packetNum);
				}
				pJSON_radio_interval = cJSON_GetObjectItem(pJsonRoot, "interval");
				if (pJSON_radio_interval != NULL)
				{
					_radio_peocess.tx_process_data.interval = pJSON_radio_interval->valueint;
					printf("Got cmd interval: %d\r\n", _radio_peocess.tx_process_data.interval);
				}
				pJSON_radio_dataLen = cJSON_GetObjectItem(pJsonRoot, "dataLength");
				if (pJSON_radio_dataLen != NULL)
				{
					_radio_peocess.tx_process_data.bufferLen = pJSON_radio_dataLen->valueint;
					printf("Got cmd dataLength: %d\r\n", _radio_peocess.tx_process_data.bufferLen);
				}
				pJSON_radio_data = cJSON_GetObjectItem(pJsonRoot, "data");
				if (pJSON_radio_data != NULL)
				{
					memcpy(_radio_peocess.tx_process_data.buffer, pJSON_radio_data->valuestring, _radio_peocess.tx_process_data.bufferLen);
					_radio_peocess.tx_process_data.buffer[_radio_peocess.tx_process_data.bufferLen] = '\0';
					printf("Got cmd data: %s\r\n", _radio_peocess.tx_process_data.buffer);
				}
				_radio_peocess.packetID = 0;
				if (RADIO_OK == radio_tx_process())
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 1);
					LoRa_realtime_Mode = TX_MODE;
				}
				else
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 0);
				}
				break;
			case RADIO_RECV_CMD:
				printf("RADIO_RECV_CMD\r\n");
				pJSON_radio_modem = cJSON_GetObjectItem(pJsonRoot, "modem");
				if (pJSON_radio_modem != NULL)
				{
					_radio_peocess.modem = pJSON_radio_modem->valueint;
					printf("Got cmd modem: %d\r\n", _radio_peocess.modem);
				}
				pJSON_radio_freq = cJSON_GetObjectItem(pJsonRoot, "frq");
				if (pJSON_radio_freq != NULL)
				{
					key_len = strlen(pJSON_radio_freq->valuestring);
					memcpy(radio_freq, pJSON_radio_freq->valuestring, key_len);
					radio_freq[key_len + 1] = '\0';
					_radio_peocess.freq = atol(radio_freq);
					printf("Got cmd frq: %u\r\n", _radio_peocess.freq);
				}
				pJSON_radio_sf = cJSON_GetObjectItem(pJsonRoot, "sf");
				if (pJSON_radio_sf != NULL)
				{
					_radio_peocess.sf = pJSON_radio_sf->valueint;
					printf("Got cmd sf: %d\r\n", _radio_peocess.sf);
				}
				pJSON_radio_bw = cJSON_GetObjectItem(pJsonRoot, "bw");
				if (pJSON_radio_bw != NULL)
				{
					_radio_peocess.bandwidth = pJSON_radio_bw->valueint;
					printf("Got cmd bw: %d\r\n", _radio_peocess.bandwidth);
				}
				pJSON_radio_cr = cJSON_GetObjectItem(pJsonRoot, "cr");
				if (pJSON_radio_cr != NULL)
				{
					_radio_peocess.coderate = pJSON_radio_cr->valueint;
					printf("Got cmd bw: %d\r\n", _radio_peocess.coderate);
				}
				pJSON_radio_preambleLen = cJSON_GetObjectItem(pJsonRoot, "preambleLength");
				if (pJSON_radio_preambleLen != NULL)
				{
					_radio_peocess.preambleLen = pJSON_radio_preambleLen->valueint;
					printf("Got cmd preambleLen: %d\r\n", _radio_peocess.preambleLen);
				}
				pJSON_radio_packetNum = cJSON_GetObjectItem(pJsonRoot, "packetNum");
				if (pJSON_radio_packetNum != NULL)
				{
					_radio_peocess.packetNum = pJSON_radio_packetNum->valueint;
					printf("Got cmd packetNum: %d\r\n", _radio_peocess.packetNum);
				}
				_radio_peocess.packetID = 0;
				if (RADIO_OK == radio_rx_process())
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 1);
					LoRa_realtime_Mode = RX_MODE;
				}
				else
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 0);
				}
				break;
			case RADIO_CAD_CMD:
				printf("RADIO_CAD_CMD\r\n");
				// {
				// 	"type": 3,
				// 	"modem":1,
				// 	"preambleLength":8,
				// 	"frq":"470000000",
				// 	"sf":7,
				// 	"bw":0,
				// 	"cr":1,
				// 	"rxPeriod":6400	  #单位，秒（15.625 µs），RxDuration = 6400 * 15.625 µs = 100ms
				// 	"sleepPeriod":6400  #单位，秒（15.625 µs），sleepDuration = 6400 * 15.625 µs = 100ms
				// }
				pJSON_radio_modem = cJSON_GetObjectItem(pJsonRoot, "modem");
				if (pJSON_radio_modem != NULL)
				{
					_radio_peocess.modem = pJSON_radio_modem->valueint;
					printf("Got cmd modem: %d\r\n", _radio_peocess.modem);
				}
				pJSON_radio_freq = cJSON_GetObjectItem(pJsonRoot, "frq");
				if (pJSON_radio_freq != NULL)
				{
					key_len = strlen(pJSON_radio_freq->valuestring);
					memcpy(radio_freq, pJSON_radio_freq->valuestring, key_len);
					radio_freq[key_len + 1] = '\0';
					_radio_peocess.freq = atol(radio_freq);
					printf("Got cmd frq: %u\r\n", _radio_peocess.freq);
				}
				pJSON_radio_sf = cJSON_GetObjectItem(pJsonRoot, "sf");
				if (pJSON_radio_sf != NULL)
				{
					_radio_peocess.sf = pJSON_radio_sf->valueint;
					printf("Got cmd sf: %d\r\n", _radio_peocess.sf);
				}
				pJSON_radio_bw = cJSON_GetObjectItem(pJsonRoot, "bw");
				if (pJSON_radio_bw != NULL)
				{
					_radio_peocess.bandwidth = pJSON_radio_bw->valueint;
					printf("Got cmd bw: %d\r\n", _radio_peocess.bandwidth);
				}
				pJSON_radio_cr = cJSON_GetObjectItem(pJsonRoot, "cr");
				if (pJSON_radio_cr != NULL)
				{
					_radio_peocess.coderate = pJSON_radio_cr->valueint;
					printf("Got cmd bw: %d\r\n", _radio_peocess.coderate);
				}
				pJSON_radio_preambleLen = cJSON_GetObjectItem(pJsonRoot, "preambleLength");
				if (pJSON_radio_preambleLen != NULL)
				{
					_radio_peocess.preambleLen = pJSON_radio_preambleLen->valueint;
					printf("Got cmd preambleLen: %d\r\n", _radio_peocess.preambleLen);
				}
				pJSON_radio_packetNum = cJSON_GetObjectItem(pJsonRoot, "rxPeriod");
				if (pJSON_radio_packetNum != NULL)
				{
					_radio_peocess.cad_process_data.rxPeriod = pJSON_radio_packetNum->valueint;
					printf("Got cmd packetNum: %d\r\n", _radio_peocess.cad_process_data.rxPeriod);
				}
				pJSON_radio_interval = cJSON_GetObjectItem(pJsonRoot, "sleepPeriod");
				if (pJSON_radio_interval != NULL)
				{
					_radio_peocess.cad_process_data.sleepPeriod = pJSON_radio_interval->valueint;
					printf("Got cmd packetNum: %d\r\n", _radio_peocess.cad_process_data.sleepPeriod);
				}
				_radio_peocess.packetID = 0;
				if (RADIO_OK == radio_cad_process())
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 1);
					LoRa_realtime_Mode = CAD_MODE;
				}
				else
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 0);
				}
				break;
			case RADIO_STANDBY_CMD:
				//{"type":4}
				printf("RADIO_STANDBY_CMD\r\n");
				if (RADIO_OK == radio_standby_process())
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 1);
					LoRa_realtime_Mode = STAND_BY;
				}
				else
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 0);
				}
				break;
			case RADIO_SLEEP_CMD:
				//{"type":5}
				printf("RADIO_SLEEP_CMD\r\n");
				if (RADIO_OK == radio_sleep_process())
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 1);
					LoRa_realtime_Mode = DEEPSLEEP;
				}
				else
				{
					tb05_status_respone(cmd_type_int + RESPONE_STATUS, 0);
				}
				break;
			case UPDATE_CMD:
				printf("SEND UPDATE DATA\r\n");
				radio_setting_update(LoRa_realtime_Mode);
				break;
			default:
				printf("error command\r\n");
				break;
			}
			LoRa_LED_Status = LOW;
		}
		else
		{
			printf("error type\r\n");
		}
	}
	else
	{
		printf("data is not an JSON\r\n");
	}
	cJSON_Delete(pJsonRoot);
}

void LoRa_IRQ_Handle(void)
{
	static int tx_interval = 0;
	LoRa_state_process();
	if (1 == g_lora_tx_done && TX_MODE == LoRa_realtime_Mode)
	{
		if (tx_interval > _radio_peocess.tx_process_data.interval/20)
		{
			if (_radio_peocess.packetID < _radio_peocess.packetNum)
			{
				Radio.Send((uint8_t *)_radio_peocess.tx_process_data.buffer, _radio_peocess.tx_process_data.bufferLen);
			}else{
				LoRa_LED_Status = LOW;
			}
			g_lora_tx_done = 0;
			tx_interval = 0;
		}
		tx_interval++;
		g_lora_rx_done = 0;
	}
	if (CAD_MODE == LoRa_realtime_Mode)
	{
		g_cad_count ++;
		if (g_cad_count > 250)
		{
			LoRa_LED_Status = LOW;
		}
	}
}
