#include <stdio.h>
#include <string.h>
#include "LORA.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "y_ringbuf.h"
#include <inttypes.h>
#include "driver/gpio.h"
#include "freertos/timers.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_check.h"
#include "esp_sleep.h"
#include "soc/uart_pins.h"
#include "driver/uart.h"
#include "driver/gpio.h"

#include "driver/rtc_io.h"
#include "sdkconfig.h"
#include "../../main/user_sleep.h"
#include "esp_sleep.h"

QueueHandle_t lora_receiveQueue;


SemaphoreHandle_t debug_Mutex;

extern struct RINGBUF_st;
RINGBUF_st *lora_ringbuf;
uint8_t rssi;
uart_status_t lora_uart_status =  uart_idle;
//声明一个TimerHandle_t类型的变量，用于存储定时器句柄
TimerHandle_t lora_uart_Timerout;


bool is_change_chanel = false;


static const char *LOG_TAG = "LORA";


//static char lora_rx_buf[32] = {};

uint8_t rawData_16[1024];
extern QueueHandle_t lora_data_queue;
uint8_t rec_rssi;
static const int LORA_BUF_SIZE = 1024;

static bool half_packet_flag =false;

static QueueHandle_t lora_queue;


LORA_CFG_T lora_cfg_data;

uint8_t lora_rssi_data = 0;
uint8_t lora_software_version = 0;

bool is_uart_wake = false;




//static int lora_analytic_data(const uint8_t* data_buf,int len);
static int lora_set_receive(const uint8_t* data,size_t len);
static int send_lora_queue(const uint8_t* data_buf,int len);
static esp_err_t uart_wakeup_config(void);


// #if USER_QIXIN   //添加的初始化代码


TaskHandle_t lora_uart_tx_handle;


QueueHandle_t lora_uart_Queue;  //串口接受队列

TimerHandle_t lora_cmd_Timerout; //初始化命令超时函数


QueueHandle_t lora_dealhandle;  //开始处理逻辑的数据



//沃进初始化命令配置

lora_cmd_t  lora_cmd[]=
    {
    #if 0
    { {0x03,0x26,0x01,0x8E},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*测试AT*/
    { {0x03,0x01,0x15,0x27},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*恢复默认设置*/
    { {0x03,0x26,0x00,0x89},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*设置工作频率*/
    //{ {0x03,0x26,0x01},"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*设置波特率115200*/
    #else

    { .cmd_mode = 0x01, .lora_send_cmd_handler = lora_set_config_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},   /*进入配置模式*/
    { .cmd_mode = LORA_CHANENL,.lora_send_cmd_handler = lora_set_channel,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},/*设置信道模式*/
    { .cmd_mode = 0x06, .lora_send_cmd_handler = lora_set_bps,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},           /*设置波特率*/
    



        //设置设备ID 地址  0xFFFFFFFF 
    { .cmd_mode = 0x00000001, .lora_send_cmd_handler = lora_set_device_id,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander}, 
    //设置目标地址  0xFFFFFFFF   所有都可以接收到
    { .cmd_mode = 0xFFFFFFFF, .lora_send_cmd_handler = lora_set_dst_device_id,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},  


    
    { .cmd_mode = 0x07, .lora_send_cmd_handler = lora_get_rssi,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},           /*rssi*/
    //{ .cmd_mode = 0x01, .lora_send_cmd_handler = lora_set_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},           /*设置透传模式*/
    { .cmd_mode = 0x00, .lora_send_cmd_handler = lora_set_config_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},   /*退出配置模式*/
    #endif
    };

// lora_cmd_t  lora_cmd_rssi[]=
//     {
//     #if 0
//     { {0x03,0x26,0x01,0x8E},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*测试AT*/
//     { {0x03,0x01,0x15,0x27},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*恢复默认设置*/
//     { {0x03,0x26,0x00,0x89},4,"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*设置工作频率*/
//     //{ {0x03,0x26,0x01},"",lora_cmd_success_Hander,lora_cmd_timerout_Hander},/*设置波特率115200*/
//     #else

//     { .cmd_mode = 0x01, .lora_send_cmd_handler = lora_set_config_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},   /*进入配置模式*/
//     { .cmd_mode = 0x07, .lora_send_cmd_handler = lora_get_rssi,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},           /*rssi*/
//     //{ .cmd_mode = 0x01, .lora_send_cmd_handler = lora_set_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},           /*设置透传模式*/
//     { .cmd_mode = 0x00, .lora_send_cmd_handler = lora_set_config_mode,.success_hanlder =lora_cmd_success_Hander,.timeout_hanlder=lora_cmd_timerout_Hander},   /*退出配置模式*/
//     #endif
//     };




//初始化结构体
Lora_t  lora = {
    .lora_mode = Lora_Cmd_Mode,
    .lora_cmd = lora_cmd,
    .cmd_index = 0,
    .timerout =false,
    .cmd_type =  lora_cmd_system_type,
};


/*********************************************************************************
* function   :   lora_cmd_success_Hander     
* Description :  lora AT命令配置回复成功
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
void lora_cmd_success_Hander(unsigned char *cmd,unsigned char *cmd_rsp,int len)
{
	ESP_LOGE(LOG_TAG,"%s,cmd = %s,cmd rsp =%s len = %d\r\n",__FUNCTION__,cmd,cmd_rsp,len);
}

/*********************************************************************************
* function   :   lora_sendData     
* Description :  lora AT命令配置回复超时或失败
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
void lora_cmd_timerout_Hander(unsigned char *cmd,unsigned char *cmd_rsp,int len)
{
	printf("%s,cmd = %s,cmd rsp =%s len = %d\r\n",__FUNCTION__,cmd,cmd_rsp,len);
}

/*********************************************************************************
* function   :   lora_sendData     
* Description :  lora 发送数据函数
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
int lora_sendData(unsigned char* data,int len)
{
    //const int len = strlen(data);


   int txBytes = 0;

    int offset = 0;

#if  1
    #define MAX_LEN    64//50*2
    #define TIME_SET   50
#else
  
    #define MAX_LEN 200
    #define TIME_SET   30
#endif
              
       offset=0;
          while(len>0)
          {
            if(len>MAX_LEN)
            {
                     	
                      #if 0
                      send_lora_data(result+offset,MAX_LEN);
                      #else
                      txBytes = uart_write_bytes(LORA_UART, data+offset, MAX_LEN);
                      vTaskDelay(TIME_SET / portTICK_PERIOD_MS);
                      #endif
                      offset=offset+MAX_LEN;
                      len=len-MAX_LEN;
            }else{
                      
                      #if 0
                      send_lora_data(result+offset,len);
                      #else

                      txBytes = uart_write_bytes(LORA_UART, data+offset, len);
                      vTaskDelay(TIME_SET / portTICK_PERIOD_MS);
                      #endif

                      len=0;
                      //Serial.println("send end packet.");
                }

          }


     #if 0      //可以发送的
    const int txBytes = uart_write_bytes(LORA_UART, data, len);
    #endif
    //printf("Write %d bytes\r\n", txBytes);
    return txBytes;
}

/*********************************************************************************
* function   :   lora_send_index_init_cmd     
* Description :  lora 发送初始化指定索引位置命令函数
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
void lora_send_index_init_cmd(uint8_t index)
{

      if(index >=(sizeof(lora_cmd)/sizeof(lora_cmd[0])))
       return;

      if(lora_cmd[index].lora_send_cmd_handler != NULL)
      {
            lora_cmd[index].lora_send_cmd_handler( lora_cmd[index].cmd_mode);
      }


   
}
int find_value(const unsigned char *hex_array, size_t array_size, unsigned char target_value) {
    for (size_t i = 0; i < array_size; i++) {
        if (hex_array[i] == target_value) {
            return (int)i;
        }
    }
    return -1;
}


/*********************************************************************************
* function   :   lora_cmd_timerout_Callback     
* Description :  lora AT命令配置回复超时定时器
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
void lora_cmd_timerout_Callback(TimerHandle_t xTimer) {

  lora.timerout = true;
  printf("lora_cmd_timerout_Callback\r\n");
}

void lora_init_cmd_handler(unsigned char * data,void *param)
{

#if VJ_LORA_ENABLE

                uint16_t len =  *(uint16_t*)param;

                if((find_value(data,len,LORA_SUCCESS)!= -1) ||(find_value(data,len,0x07)!= -1))
                      //if(strncmp((char*)data,(char *)lora_cmd[lora.cmd_index].cmd_rsp,strlen((char *)lora_cmd[lora.cmd_index].cmd_rsp)) == 0 )
                {
                      //printf("cmd is ok %d\r\n",lora.cmd_index);

                      if(lora.cmd_index==(sizeof(lora_cmd)/sizeof(lora_cmd[0]) -1))
                      {
                           xTimerStop(lora_cmd_Timerout,0);
                            lora.lora_mode =  Lora_UART_Mode;
                            gpio_set_level(LORA_SET_PIN, 1);

                            // if(is_change_chanel == true)
                            // {
                            //     is_change_chanel = false;
                            // }
                            //uart_set_baudrate(LORA_UART,115200);
                            printf("lora at all cmd init ok \r\n");

#if 0
                            extern void user_i2s_init(void);
                            user_i2s_init();
#else
//ota_init();    


void lora_send_test_handler();

	//xTaskCreate(lora_send_test_handler, "lora_send_test_task", 1024*4, NULL, configMAX_PRIORITIES, NULL);
#endif                            
                      }else
                      {
                          xTimerStop(lora_cmd_Timerout,0);
                          lora.cmd_index +=1;
                          #if 0
                          lora_sendData((unsigned char*)lora_cmd[lora.cmd_index].cmd,4);
                          #else
                          lora_send_index_init_cmd(lora.cmd_index);
                          #endif
                          xTimerStart(lora_cmd_Timerout, 0);
                      }
                }else if(find_value(data,len,LORA_FAIL)!= -1)
                { 

                  printf("cmd is fail\r\n");
                  if(lora.timerout == true)
                  {
                    lora.timerout =false;
                  }

                    if(lora.retry_times>=MAX_RETRY_NUM)
                    {

                        lora.retry_times = 0;
                           //xTimerStop(lora_cmd_Timerout,0);

                           printf("cmd is running retry_times max  contiune next cmd\r\n");
                           return;
                     }

                  lora.retry_times+=1;


                } 



#endif
                    // xTimerStart(lora_cmd_Timerout, 30);
                    // if(xTimerIsTimerActive(lora_cmd_Timerout) != pdFALSE)
                    // {
                    //     xTimerReset(lora_cmd_Timerout,0);
                    //     //printf("receiving\r\n");
                    //     //printf("timer is running");
                    // }


}


/*********************************************************************************
* function   :   dymatic_change_chanel     
* Description :  lora AT命令配置动态切换信道
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 10.23
**********************************************************************************/	
void dymatic_change_chanel(uint8_t chanel)
{
    // ESP_LOGW(LOG_TAG,"切换chanel = %d ",chanel);
    lora.cmd_index = 0;
    lora.lora_mode = Lora_Cmd_Mode;    //设置进入命令模式
    lora_cmd[1].cmd_mode = chanel;   //设置信道
    lora_send_index_init_cmd(lora.cmd_index);  //
    xTimerStart(lora_cmd_Timerout, 0); 
}




/*********************************************************************************
* function   :   dymatic_change_device_id     
* Description :  lora AT命令配置动态修改设备ID
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 10.23
**********************************************************************************/	
void dymatic_change_device_id(uint32_t id)
{
   for(int i = 0;i<sizeof(lora_cmd)/sizeof(lora_cmd[0]);i++)
   {
        if(lora_cmd[i].lora_send_cmd_handler == lora_set_device_id)
        {
            lora_cmd[i].cmd_mode = id;
            printf("cmd index %ld,index %d\r\n",id,i);
            break;
        }
   }
}



/*********************************************************************************
* function   :   dymatic_change_dst_device_id     
* Description :  lora AT命令配置动态修改目的地址
* Input       :  
* Output      :  
* Author      :  祁鑫                  Data : 2023 10.23
**********************************************************************************/	
void dymatic_change_dst_device_id(uint32_t id)
{
       for(int i = 0;i<sizeof(lora_cmd)/sizeof(lora_cmd[0]);i++)
   {
        if(lora_cmd[i].lora_send_cmd_handler == lora_set_dst_device_id)
        {
            lora_cmd[i].cmd_mode = id;
            printf("cmd index %ld,index %d\r\n",id,i);
            break;
        }
   }
   
   
}








/*********************************************************************************
* function   :   lora_set_device_id     
* Description :  lora AT命令配置LORA设备ID
* Input       :   4个字节数据
* Output      :  
* Author      :  祁鑫                  Data : 2023 10.23
**********************************************************************************/	
void lora_set_device_id(uint32_t id)
{
 printf("%s id = %ld\r\n",__FUNCTION__,id);

  uint8_t temp = 0x00;
  uint32_t ID = id; 
  #if 1
  uint8_t lorabuf[7];
   lorabuf[0]=0x06;
   lorabuf[1]=0x0D;

#if 0
   lorabuf[2]=id&0xff;
   lorabuf[3]=(id>>8)&0xff;
   lorabuf[4]=(id>>16)&0xff;
   lorabuf[5]=(id>>24)&0xff;
#else

   temp = (ID>>0)&0xff;
   lorabuf[2]=temp;
   temp = (ID>>8)&0xff;
   lorabuf[3]=temp;
   temp = (ID>>16)&0xff;
   lorabuf[4]=temp;
   temp = (ID>>24)&0xff;
   lorabuf[5]=temp;

#endif

   lorabuf[6]=crc8(lorabuf,6,0x55,0x07);
  lora_sendData(lorabuf,sizeof(lorabuf));
   #endif       
}

/*********************************************************************************
* function   :   lora_set_dst_device_id     
* Description :  lora AT命令配置LORA目标设备ID
* Input       :   4个字节数据
* Output      :  
* Author      :  祁鑫                  Data : 2023 10.23
**********************************************************************************/	
void lora_set_dst_device_id(uint32_t id)
{
   printf("%s id = %ld\r\n",__FUNCTION__,id);
  #if 1
  uint8_t lorabuf[7];

  uint8_t temp = 0x00;
  uint32_t ID = id; 


   lorabuf[0]=0x06;
   lorabuf[1]=0x0E;

#if 0
   lorabuf[2]=id&0xff;
   lorabuf[3]=(id>>8)&0xff;
   lorabuf[4]=(id>>16)&0xff;
   lorabuf[5]=(id>>24)&0xff;
#else


   temp = (ID>>0)&0xff;
   lorabuf[2]=temp;
   temp = (ID>>8)&0xff;
   lorabuf[3]=temp;
   temp = (ID>>16)&0xff;
   lorabuf[4]=temp;
   temp = (ID>>24)&0xff;
   lorabuf[5]=temp;




#endif


   lorabuf[6]=crc8(lorabuf,6,0x55,0x07);
  lora_sendData(lorabuf,sizeof(lorabuf));
   #endif  
}

uint8_t set_lora(uint8_t new_channel,uint8_t eflag)
{
  uint8_t ret = 0;
  uint8_t  data[50] = {0};
  int user_size = 0;
        

  lora.lora_mode = Lora_Cmd_Mode;

  gpio_set_level(LORA_SET_PIN, 0);

  lora_set_config_mode(0x01);
  vTaskDelay(100/ portTICK_PERIOD_MS);

  user_size = y_ringbuf_get_used_size(lora_ringbuf);
  y_ringbuf_read_clear(lora_ringbuf, data, user_size);
  if(user_size!=0)
  {
      printf("rsp len = %d\r\n",user_size);
      for(int i = 0;i<user_size;i++)
      printf("%02x",data[i]);
  }


  lora_set_channel(new_channel);
  vTaskDelay(100/ portTICK_PERIOD_MS);

  user_size = y_ringbuf_get_used_size(lora_ringbuf);
  y_ringbuf_read_clear(lora_ringbuf, data, user_size);

// while(1)
// {
//        if((data[0] == 0x03)&&(data[1] == 0xee))
//         {
//              printf("error rsp fail len = %d\r\n",user_size);
//             lora_set_channel(new_channel);
//             vTaskDelay(100/ portTICK_PERIOD_MS);
//             user_size = y_ringbuf_get_used_size(lora_ringbuf);
//             y_ringbuf_read_clear(lora_ringbuf, data, user_size);
//         }
        
//          if((data[0] == 0x03)&&(data[1] == 0x55))
//         {
//               printf("set config ok\r\n");
//               break;
//         }

      if(user_size!=0)
      {
          printf("rsp len = %d\r\n",user_size);
          for(int i = 0;i<user_size;i++)
          printf("%02x",data[i]);
      }

//   vTaskDelay(100/ portTICK_PERIOD_MS);
// }
     


  lora_set_bps(6);
  vTaskDelay(100/ portTICK_PERIOD_MS);

  user_size = y_ringbuf_get_used_size(lora_ringbuf);
  y_ringbuf_read_clear(lora_ringbuf, data, user_size);
  if(user_size!=0)
  {
        printf("rsp len = %d\r\n",user_size);
      for(int i = 0;i<user_size;i++)
      printf("%02x",data[i]);
  }


  lora_set_device_id(eflag+1);
  vTaskDelay(100/ portTICK_PERIOD_MS);

  user_size = y_ringbuf_get_used_size(lora_ringbuf);
  y_ringbuf_read_clear(lora_ringbuf, data, user_size);

  if(user_size!=0)
  {
        printf("rsp len = %d\r\n",user_size);
      for(int i = 0;i<user_size;i++)
      printf("%02x",data[i]);
  }


  lora_set_dst_device_id(0x00000001);
  vTaskDelay(100/ portTICK_PERIOD_MS);

  user_size = y_ringbuf_get_used_size(lora_ringbuf);
  y_ringbuf_read_clear(lora_ringbuf, data, user_size);

  if(user_size!=0)
  {
    
        printf("rsp len = %d\r\n",user_size);
      for(int i = 0;i<user_size;i++)
      printf("%02x",data[i]);
  }


    lora_get_rssi(0x07);
    vTaskDelay(100/ portTICK_PERIOD_MS);

    user_size = y_ringbuf_get_used_size(lora_ringbuf);
    y_ringbuf_read_clear(lora_ringbuf, data, user_size);
    if(user_size!=0)
    {
        ret = data[2];
        printf("rssi = %d\r\n",ret);
    }

          


    lora_set_config_mode(0x00);
    vTaskDelay(100/ portTICK_PERIOD_MS);

    user_size = y_ringbuf_get_used_size(lora_ringbuf);
    y_ringbuf_read_clear(lora_ringbuf, data, user_size);

    if(user_size!=0)
    {
        
          printf("rsp len = %d\r\n",user_size);
        for(int i = 0;i<user_size;i++)
        printf("%02x",data[i]);
    }
    lora.lora_mode =  Lora_UART_Mode;
    gpio_set_level(LORA_SET_PIN, 1);
    return ret;
}
void reset_lora(void)
{


      gpio_set_level(LORA_SET_PIN, 0);
        //for(int index = 0;index<sizeof(lora_cmd)/sizeof(lora_cmd[0]);index++)
      {

           uint8_t  data[50] = {0};

           int user_size = 0;
   

          lora.lora_mode = Lora_Cmd_Mode;




          lora_set_config_mode(0x01);

          vTaskDelay(100/ portTICK_PERIOD_MS);

           user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
              printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }





          
          lora_set_channel(LORA_CHANENL);
          vTaskDelay(100/ portTICK_PERIOD_MS);

          user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);
          if(data[1] == 0xee)
          {
            lora_set_channel(LORA_CHANENL);
            vTaskDelay(100/ portTICK_PERIOD_MS);
            user_size = y_ringbuf_get_used_size(lora_ringbuf);
            y_ringbuf_read_clear(lora_ringbuf, data, user_size);
          }
          if(user_size!=0 )
          {
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }


          lora_set_bps(6);

          vTaskDelay(100/ portTICK_PERIOD_MS);


          user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }



          lora_set_device_id(0x00000001);

          vTaskDelay(100/ portTICK_PERIOD_MS);

          user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }


          lora_set_dst_device_id(0xFFFFFFFF);

           vTaskDelay(100/ portTICK_PERIOD_MS);

       user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
           
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }


          lora_get_rssi(0x07);

        vTaskDelay(100/ portTICK_PERIOD_MS);

                 user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
              
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }

          

         
          lora_set_config_mode(0x00);
           vTaskDelay(100/ portTICK_PERIOD_MS);



         user_size = y_ringbuf_get_used_size(lora_ringbuf);
       
          y_ringbuf_read_clear(lora_ringbuf, data, user_size);

          if(user_size!=0)
          {
              
                printf("rsp len = %d\r\n",user_size);
              for(int i = 0;i<user_size;i++)
              printf("%02x",data[i]);
          }



             lora.lora_mode =  Lora_UART_Mode;
             gpio_set_level(LORA_SET_PIN, 1);

      

        //free(data);
      }




}

static void tx_task(void *arg)
{

	//Cmd_t cmd;
	int index = 0;
	unsigned char receivedMessage[30];

//发送lora初始化AT指令
#if HPD_LORA_ENABLE
lora_sendData((unsigned char*)lora_cmd[lora.cmd_index].cmd,strlen((char *)lora_cmd[lora.cmd_index].cmd));
#endif


#if VJ_LORA_ENABLE
#if 1

  reset_lora();


//lora_sendData((unsigned char*)lora_cmd[lora.cmd_index].cmd,4);
#else
lora_send_index_init_cmd(lora.cmd_index);
#endif
#endif


 //xTimerStart(lora_cmd_Timerout, 0); 

  while (1) 
  {
     	vTaskDelay(1000 / portTICK_PERIOD_MS);
  }

}
static void rx_task(void *arg)
{

	uart_event_t event;
	int length = 0, uart = 0;
	unsigned char receivedMessage[30];
  static const char *RX_TASK_TAG = "RX_TASK";
  esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
  uint8_t* data = (uint8_t*) malloc(RX_MAX_LENGTH+1);
	int receive_len = 0;

#if 1

while(1){
 			if (xQueueReceive(lora_uart_Queue, (void *)&event, (TickType_t)portMAX_DELAY)) {
	
				switch (event.type){
				//Event of UART receving data
				/*We'd better handler data event fast, there would be much more data events than
				other types of events. If we take too much time on data event, the queue might
				be full.*/
				case UART_DATA:


					    //xSemaphoreTake( debug_Mutex, portMAX_DELAY );
						if(event.size > 0)
						{
							// 启动定时器，第二个参数为定时器超时时间，设置为0表示立即启动
							if(lora_uart_status == uart_idle)
							{
								lora_uart_status = uart_receving;
								xTimerStart(lora_uart_Timerout, 0);
								//printf("first rev\r\n");
							}else if(lora_uart_status == uart_receving)
							{
								if(xTimerIsTimerActive(lora_uart_Timerout) != pdFALSE)
								{
								xTimerReset(lora_uart_Timerout,0);
								//printf("receiving\r\n");
								//printf("timer is running");
								}else{
									//printf("timer is run ok");
								
								}
									//portTICK_PERIOD_MS
									if(event.size <= uart_fifo_size)
									{
											lora_uart_status = uart_receving;
									}
							}


							receive_len =  event.size;
							int len = uart_read_bytes(LORA_UART, data, event.size,/*uart_timerout_times / portTICK_PERIOD_MS*/portMAX_DELAY);
                             
							receive_len =  len;


						
						
							y_ringbuf_write(lora_ringbuf, data, receive_len);
						

					}
					// xSemaphoreGive( debug_Mutex );

					break;
		
				//Event of HW FIFO overflow detected
				case UART_FIFO_OVF:
					printf("UART_FIFO_OVF\r\n");
					// If fifo overflow happened, you should consider adding flow control for your application.
					// The ISR has already reset the rx FIFO,
					// As an example, we directly flush the rx buffer here in order to read more data.
					uart_flush_input(LORA_UART);
					xQueueReset(lora_uart_Queue);
					break;
		
				//Event of UART ring buffer full
				case UART_BUFFER_FULL:
					printf("UART_BUFFER_FULL\r\n");
					// If buffer full happened, you should consider encreasing your buffer size
					// As an example, we directly flush the rx buffer here in order to read more data.
					uart_flush_input(LORA_UART);
					xQueueReset(lora_uart_Queue);
					break;
		
				//Event of UART RX break detected
				case UART_BREAK:
					// printf("UART_BREAK\r\n");
					break;
		
				//Event of UART parity check error
				case UART_PARITY_ERR:
					printf("UART_PARITY_ERR\r\n");
					break;
		
				//Event of UART frame error
				case UART_FRAME_ERR:
					printf("UART_FRAME_ERR\r\n");
					break;
		
				//UART_PATTERN_DET
				case UART_PATTERN_DET:
					printf("UART_PATTERN_DET\r\n");

					break;

                // Event of waking up by UART
                        case UART_WAKEUP:
                        printf("uart wakeup\r\n");
                        if(xTimerIsTimerActive(lora_uart_Timerout) != pdFALSE)
						{    
                            printf("uart timer run\r\n");
								xTimerReset(lora_uart_Timerout,0);
						}else
                        {
                              printf("uart timer not run\r\n");
                        }
                    break;
		
				//Others
				default:
					printf("other error\r\n");
					break;
			}
 		}
}
#endif
    free(data);
    //free(cmd);
}






void lora_receive_callback_handler()
{
  int length = 0;

  uint8_t* data = (uint8_t*) malloc(buffer_size+1);
  //int length = 0;
  // uint8_t* result = (uint8_t*) malloc(buffer_size+1);

  int user_size = 0;


// #include "../../main/yc_protocol.h"
// extern YC_DATA_T yc_data;



    while (1) 
    {
      // 从队列中接收数据
        if (xQueueReceive(lora_receiveQueue, &length, portMAX_DELAY) == pdPASS){
          
              user_size = y_ringbuf_get_used_size(lora_ringbuf);
              if(lora.lora_mode == Lora_Cmd_Mode)
              {
                //y_ringbuf_read_clear(lora_ringbuf, data, user_size);
                //printf("user_size = %d\r\n",user_size);
                  //lora 命令模式处理
                  // if(lora.cmd_type ==  lora_cmd_system_type)
                  // {
                  //     for(int i = 0;i<user_size;i++)
                  //     {
                  //       printf("%02x,",data[i]);
                  //       if((data[i] == 0x03)&&(data[i+1] == 0x07))
                  //       {
                  //         //printf("-->rssi = %02x----,",data[i+2]);
                  //         if(data[i+2] >100)
                  //           rssi = 100;
                  //         else
                  //           rssi = data[i+2];
                  //       }
                  //     }

                      
                  //     #if 1
                  //     lora_init_cmd_handler(data,&user_size);
                  //     #else
                  //   //发送回复显示
                  //     lora_sendData(data,user_size);

                  //     #endif
                  // }
              
              }else if(lora.lora_mode == Lora_UART_Mode)
              {
                  //   //lora 透传模式处理
                  // for(int i = 0;i<user_size;i++)
                  // printf("_%02x",data[i]);
                  // printf("\r\n");


                        //printf("string =%s\r\n",data);
                        printf("%.*s\n", user_size, data);
                        //发送消息处理
                        #if 0
                        xQueueSend(lora_dealhandle, &length, portMAX_DELAY);
                        #else

                        if (xQueueSend(lora_dealhandle, &length, portMAX_DELAY) == pdPASS) {
                            // 消息发送成功
                            ESP_LOGW(LOG_TAG,"send ok");
                        } else {
                            // 消息发送失败，可能是消息队列已满
                            ESP_LOGE(LOG_TAG,"send fail");
                        }
                }
              }
    }
    free(data);
}

















#if VJ_LORA_ENABLE

/**沃进方案校验和计算法
 * @funtion:crc8多项式冗余校验
 * @param 1:pData,计算数据源地址
 * @param 2:dataLen,计算数据源长度
 * @param 3:initialValue,crc结果初值
 * @param 4:polynomial,多项式
 * 
 * @return :校验结果
*/
uint8_t crc8( uint8_t *pData, 
                    uint16_t dataLen,
                    uint8_t initialValue, 
                    uint8_t polynomial )
{
    uint8_t i;
    uint8_t crc;

    crc = initialValue;
    while (dataLen --)
    {
        crc ^= *pData ++;
        for( i = 0; i < 8; i++ )
        {
            if(crc & 0x80)
            {
                crc <<= 1; // shift left once
                crc ^= polynomial; // XOR with polynomial
            }
            else
            { 
                crc <<= 1; // shift left once
            }
        }
    }

    return crc;
}

//=0，在配置模式下，退出配置模式，非配置模式下，认为是透传数据
//=1，进入配置模式，此时可以配置其他命令
void VJ_Lora_set_cfg_mode(uint8_t mode)
{
  uint8_t cmd[4]={0};

   cmd[0]=0x03;
   cmd[1]=0x26;
   cmd[2]=mode;
   cmd[3]=crc8(cmd,3,0x55,0x07);
  printf("cmd[3] = %02x\r\n",cmd[3]);
   lora_sendData(cmd,sizeof(cmd));
}

/**沃进方案设置无线信道**********************************************
范围：0~31
具体对应的频率与无线频段范围和信道间隔带宽的设置相关。
比如信道间隔 1MHz，无线频段范围为 433MHz 频段时，
=0，对应 433MHz
=1，对应 434MHz
…
=31，对应 464MHz
无线频段范围为 868MHz 频段时，
=0，对应 868MHz
=1，对应 869MHz
…
=31，对应 899MHz
默认为 0 信道
设置立即生效，支持掉电保存
******************************************************************/
int vjlora_set_Wireless_Channel(uint8_t Channel)
{
  int ret = 0;
  VJ_Lora_set_cfg_mode(1);
  //ret=vjlora_set_by_serial(0x01,Channel);
  VJ_Lora_set_cfg_mode(0);
  return ret;
}



#endif










#if 0
/*********************************************************************************
* function   :   lora_uart_is_normal     
* Description :  判断通信是否正常
* Input       :   boatu
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_uart_is_normal(int Baud)
{


 uint8_t i = 0, times = 0,length = 0;
     #if 1

     String  cmd = "AH";
     String cmd_rsp = "OK";

      loraSerial.begin(Baud,SERIAL_8N1,LORA_RX,LORA_TX);  // 启动串口通讯，波特率设置为115200,并配置对应端口  TX48   RX45
    
      bool is = lora_send_cmd(cmd,cmd_rsp);

      if(is)
      {
        return true;
      }else{

        return false;
      }


     #else


    loraSerial.begin(Baud,SERIAL_8N1,LORA_RX,LORA_TX);  // 启动串口通讯，波特率设置为115200,并配置对应端口  TX48   RX45
    //loraSerial.println("AH");/* code */
     
     while (1)
     {
        times++;

        //while(loraSerial.read() >0){}
        //loraSerial.flush();
        loraSerial.println("AH");/* code */
        //delay(200);
          memset(receive_buf,0x00,sizeof(receive_buf));
          i=0;
          while (loraSerial.available()>0)
          {
              //if(loraSerial.available() == 4)
              {
               
                //for(i = 0;i<4;i++)
                receive_buf[i]= loraSerial.read();
                //i++;
                delay(100);
                i++;
                //break;
              }
          }
#if 1
        Serial.println("receive data = ");
        for(int j = 0;j<20;j++)
        Serial.println(receive_buf[j],HEX);
        Serial.println("receive data ok");
#endif
          if(receive_buf[0]=='O' && receive_buf[1]=='K')
          {
             
             //Serial.print("uart init ok\r\n");

             return true;
             break;
          }
          //if(receive_buf.find("OK"))
          // {             
          //    //Serial.print("uart init ok\r\n");
          //    return true;
          //    break;

          // }
          else {


            //Serial.print("uart init fail\r\n");
            if(times>AT_MAX_RETRY_TIMES)
            {
                return false;
                break;
            }
            delay(200);
          }
     }
     
 
     #endif


}

/*********************************************************************************
* function   :   lora_send_cmd     
* Description :  发送AT字符串命令并判断返回字符串
* Input       :   
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_send_cmd(String cmd,String cmd_rsp)
{
     uint8_t i = 0, times = 0;

     bool is = false;
     String read_str;


     #if 1
     while (1)
     {
        times++;
        loraSerial.println(cmd);/* code */
        //delay(200);
          memset(receive_buf,0x00,sizeof(receive_buf));
          i=0;



          while (loraSerial.available()>0)
          {

            Serial.println(loraSerial.available());
            #if 1
            delay(20);
            read_str = loraSerial.readString();

             
            #else
            receive_buf[i] = loraSerial.read();
            #endif
            i++;
          }
        
#if 0
        Serial.println("receive data = ");
        Serial.println(read_str);
        //Serial.println(receive_buf[1],HEX);
#endif


            //if(read_str.equals(cmd_rsp))
            if(read_str.startsWith(cmd_rsp)  || read_str.startsWith("OK"))
            {
                //Serial.println("cmd rsp is ok");
                is = true;
                break;
               
            }else{
                    if(times>AT_MAX_RETRY_TIMES)
                    {
                        //Serial.println("cmd rsp is fail");
                        is = false;
                        break;
                    }
                    delay(20);
            }
     
     }

      if(is)
      {
        return true;
      }else
      {
        return false;
      }
      
     
 
     #endif



}

/*********************************************************************************
* function   :   lora_set_Baud     
* Description :  设置波特率
* Input       :  baud   1-8  
* Output      :  X 取值 1-8,可设置波特率为 1200bps、 2400bps、 4800bps、
9600bps、 19200bps、 38400bps、 57600bps 和 115200bps。
出厂默认为 9600bps。
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_set_Baud(int baud)
{

  //char baute[6] = {0};
  bool is = false;
  String baute     = LORA_CMD_AH_BAUDRATE;
  String baute_rsp = LORA_CMD_AH_BAUDRATE_RSP;


if(baud == 1){
    baute.concat("1");
    baute_rsp.concat("1");
    is = lora_send_cmd(baute,baute_rsp);

}else if(baud == 2)
{
    baute.concat("2");
    baute_rsp.concat("2");
    is = lora_send_cmd(baute,baute_rsp);
}else if(baud == 3)
{
        baute.concat("3");
    baute_rsp.concat("3");
    is = lora_send_cmd(baute,baute_rsp);
}
else if(baud == 4)
{
        baute.concat("4");
    baute_rsp.concat("4");
    is = lora_send_cmd(baute,baute_rsp);
}
else if(baud == 5)
{
        baute.concat("5");
    baute_rsp.concat("5");
    is = lora_send_cmd(baute,baute_rsp);
}
else if(baud == 6)
{
        baute.concat("6");
    baute_rsp.concat("6");
    is = lora_send_cmd(baute,baute_rsp);
}
else if(baud == 7)
{
        baute.concat("7");
    baute_rsp.concat("7");
    is = lora_send_cmd(baute,baute_rsp);
}
else if(baud == 8)
{
        baute.concat("8");
    baute_rsp.concat("8");
    is = lora_send_cmd(baute,baute_rsp);
}


      if(is)
      {
        return true;
      }else
      {
        return false;
      }
      

    #if 0
    switch (baud)
    {
    case 1  :
    baute.concat("1");
    baute_rsp.concat("1");
    is = lora_send_cmd(baute,baute_rsp);

    break;
    case 2  :
    baute.concat("2");
    baute_rsp.concat("2");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 3  :
    baute.concat("3");
    baute_rsp.concat("3");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 4  :
    baute.concat("4");
    baute_rsp.concat("4");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 5  :
    baute.concat("5");
    baute_rsp.concat("5");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 6  :
    baute.concat("6");
    baute_rsp.concat("6");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 7  :
    baute.concat("7");
    baute_rsp.concat("7");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    case 8  :
    baute.concat("8");
    baute_rsp.concat("8");
    is = lora_send_cmd(baute,baute_rsp);
    break;
    default:

        break;
    }

    #endif


}




/*********************************************************************************
* function   :   lora_set_default     
* Description :  设置默认参数
* Input       :   
* Output      : 
模组出厂设置参数为：
串口波特率 9600bps， 1 停止位， 8 数据位，无奇偶校验；
通信频率： 433.92MHz
发射功率： P8（ Max） =21dBm
LoRa 参数： SF=9、 BW=125KHz、 CR=4/5
模组 ID： 0000
当前数据包 RSSI 状态： OFF
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	

bool lora_set_default()
{

 bool is = false;
  String   cmd  = "AH+D";

  String   cmd_rsp = "OK+DEFAULT";


 is = lora_send_cmd(cmd,cmd_rsp);

       if(is)
      {
         Serial.println("lora_set_default ok");
        return true;
      }else
      {
         Serial.println("lora_set_default fail");
        return false;
      }
}





/*********************************************************************************
* function   :   lora_set_work_freq     
* Description :  更改射频中心频率（通信频率或工作频率）
* Input       :  baud   1-8  
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
bool lora_set_work_freq(String freq)
{


  bool is = false;
  String   cmd  = "AH+C";
  String   cmd_rsp = "OK+C";

  cmd.concat(freq);
  cmd_rsp.concat(freq);


 is = lora_send_cmd(cmd,cmd_rsp);

       if(is)
      {
         Serial.println("lora_set_work_freq ok");
        return true;
      }else
      {
         Serial.println("lora_set_work_freq fail");
        return false;
      }


}







/*********************************************************************************
* function   :   lora_set_send_power     
* Description :  设置发射功率
* Input       :  baud   1-8  
* Output      :  X 取值 1-8，出厂默认设置为 8，发射功率最大。发射功率等级设置
为 1，发射功率最小。
X 值 1 2 3 4 5 6 7 8 对应模块发射功率 -1 2 5 8 11 14 17 21，
发射功率单位 dBm
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_set_send_power(int baud)
{
  bool is = false;
  String cmd     = "AH+P";
  String cmd_rsp = "OK+P";


if(baud == 1){
    cmd.concat("1");
    cmd_rsp.concat("1");
    is = lora_send_cmd(cmd,cmd_rsp);

}else if(baud == 2)
{
    cmd.concat("2");
    cmd_rsp.concat("2");
       is = lora_send_cmd(cmd,cmd_rsp);
}else if(baud == 3)
{
        cmd.concat("3");
    cmd_rsp.concat("3");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 4)
{
        cmd.concat("4");
    cmd_rsp.concat("4");
       is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 5)
{
        cmd.concat("5");
    cmd_rsp.concat("5");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 6)
{
        cmd.concat("6");
    cmd_rsp.concat("6");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 7)
{
        cmd.concat("7");
    cmd_rsp.concat("7");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 8)
{
        cmd.concat("8");
    cmd_rsp.concat("8");
        is = lora_send_cmd(cmd,cmd_rsp);
}


      if(is)
      {
        return true;
      }else
      {
        return false;
      }
      
}






/*********************************************************************************
* function   :   lora_set_sf     
* Description :  设置 Lora 扩频因子(SF)值
* Input       :  baud   1-8  
* Output      :  X 取值 1-8， 分别对应 SF5、 SF6、 SF7、 SF8、 SF9、 SF10、 SF11、
SF12
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_set_sf(int baud)
{
  bool is = false;
  String cmd     = "AH+S";
  String cmd_rsp = "OK+S";


if(baud == 1){
    cmd.concat("1");
    cmd_rsp.concat("1");
    is = lora_send_cmd(cmd,cmd_rsp);

}else if(baud == 2)
{
    cmd.concat("2");
    cmd_rsp.concat("2");
       is = lora_send_cmd(cmd,cmd_rsp);
}else if(baud == 3)
{
        cmd.concat("3");
    cmd_rsp.concat("3");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 4)
{
        cmd.concat("4");
    cmd_rsp.concat("4");
       is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 5)
{
        cmd.concat("5");
    cmd_rsp.concat("5");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 6)
{
        cmd.concat("6");
    cmd_rsp.concat("6");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 7)
{
        cmd.concat("7");
    cmd_rsp.concat("7");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 8)
{
        cmd.concat("8");
    cmd_rsp.concat("8");
        is = lora_send_cmd(cmd,cmd_rsp);
}


      if(is)
      {
        return true;
      }else
      {
        return false;
      }
      
}











/*********************************************************************************
* function   :   lora_set_bw     
* Description :  设置 Lora 带宽(BW)
* Input       :   
* Output      :  X 取值 0-9， 分别对应 7.81 kHz、 10.42 kHz、 15.63 kHz、 20.83
kHz、 31.25 kHz、 41.67 kHz、 62.50 kHz、 125 kHz、 250 kHz、 500
kHz。
* Author      :  祁鑫                  Data : 2023 7.10
**********************************************************************************/	
bool lora_set_bw(int baud)
{
  bool is = false;
  String cmd     = "AH+W";
  String cmd_rsp = "OK+W";


if(baud == 1){
    cmd.concat("1");
    cmd_rsp.concat("1");
    is = lora_send_cmd(cmd,cmd_rsp);

}else if(baud == 2)
{
    cmd.concat("2");
    cmd_rsp.concat("2");
       is = lora_send_cmd(cmd,cmd_rsp);
}else if(baud == 3)
{
        cmd.concat("3");
    cmd_rsp.concat("3");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 4)
{
        cmd.concat("4");
    cmd_rsp.concat("4");
       is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 5)
{
        cmd.concat("5");
    cmd_rsp.concat("5");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 6)
{
        cmd.concat("6");
    cmd_rsp.concat("6");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 7)
{
        cmd.concat("7");
    cmd_rsp.concat("7");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 8)
{
        cmd.concat("8");
    cmd_rsp.concat("8");
        is = lora_send_cmd(cmd,cmd_rsp);
}
else if(baud == 9)
{
        cmd.concat("9");
    cmd_rsp.concat("9");
        is = lora_send_cmd(cmd,cmd_rsp);
}


      if(is)
      {
        return true;
      }else
      {
        return false;
      }
      
}








/*********************************************************************************
* function   :   lora_set_net_id     
* Description :  设置模组网络 ID
* Input       :  X 为 0-9， 可以设置 0000-9999 
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
bool lora_set_net_id(String id)
{


  bool is = false;
  String   cmd  = "AH+I";
  String   cmd_rsp = "OK+I";

  cmd.concat(id);
  cmd_rsp.concat(id);


 is = lora_send_cmd(cmd,cmd_rsp);

       if(is)
      {
         Serial.println("lora_set_net_id ok");
        return true;
      }else
      {
         Serial.println("lora_set_net_id fail");
        return false;
      }


}


/*********************************************************************************
* function   :   lora_set_rssi     
* Description :  设置当前数据包 RSSI 状态 
* Input       :  X=0 RSSI 状态为 OFF， X=1 RSSI 状态为 0N
* Output      :  
* Author      :  祁鑫                  Data : 2023 7.18
**********************************************************************************/	
bool lora_set_rssi(int rssi)
{


  bool is = false;
  String   cmd  = "AH+Q";
  String   cmd_rsp = "OK+Q";




if(rssi == 0){
    cmd.concat("0");
    cmd_rsp.concat("0");
    is = lora_send_cmd(cmd,cmd_rsp);

}else if(rssi == 1)
{
    cmd.concat("1");
    cmd_rsp.concat("1");
       is = lora_send_cmd(cmd,cmd_rsp);
}

       if(is)
      {                 
        if(rssi == 0){
          Serial.println("lora_set_rssi off ok");
        }else if(rssi == 1){

          Serial.println("lora_set_rssi on ok");
        }
                        
        return true;
      }else
      {
          if(rssi == 0){
          Serial.println("lora_set_rssi off fail");
        }else if(rssi == 1){

          Serial.println("lora_set_rssi on fail");
        }
        return false;
      }


}
#endif



















void lora_set_config_mode(uint8_t mode)
{
  //printf("%s\r\n",__FUNCTION__);
#if 1
   uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x26;
   lorabuf[2]=mode;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);

  lora_sendData(lorabuf,sizeof(lorabuf));
    
 #endif
}





void lora_set_into_config_mode()
{

#if 1
   uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x26;
   lorabuf[2]=0x01;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);

  lora_sendData(lorabuf,sizeof(lorabuf));
    
 #endif
}




void lora_set_exit_config_mode()
{

  #if 1
   uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x00;
   lorabuf[2]=0x01;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);

  lora_sendData(lorabuf,sizeof(lorabuf));
    
 #endif
}








void lora_set_channel(uint8_t channel)
{
  //printf("%s\r\n",__FUNCTION__);
#if 1
   uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x01;
   lorabuf[2]=channel;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);

  lora_sendData(lorabuf,sizeof(lorabuf));
 #endif     
}





/**设置无线波特率************************************************************
范围：0~6
=0, 预留
=1, 预留
=2, 对应 1220bps（默认）
=3, 对应 2440bps
=4, 对应 5000bps
=5, 对应 12500bps
=6, 对应 37500bps
=其他，无效
设置重启生效，支持掉电保存
越低的无线波特率可以获得更
远的通讯距离
***************************************************************************/
void lora_set_bps(uint8_t bps)
{
    //printf("%s\r\n",__FUNCTION__);
  #if 1
  uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x04;
   lorabuf[2]=bps;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);
  lora_sendData(lorabuf,sizeof(lorabuf));
   #endif    

}

/*设置透传模式*/
void lora_set_mode(uint8_t mode)
{
      printf("%s\r\n",__FUNCTION__);
  #if 1
  uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=0x08;
   lorabuf[2]=mode;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);
  lora_sendData(lorabuf,sizeof(lorabuf));
   #endif    


}

/*出厂默认配置回复*/
void lora_factory_config()
{

  printf("%s\r\n",__FUNCTION__);
    #if 1
    uint8_t lorabuf[4];
    lorabuf[0]=0x03;
    lorabuf[1]=0x21;
    lorabuf[2]=0x01;
    lorabuf[3]=crc8(lorabuf,3,0x55,0x07);
    lora_sendData(lorabuf,sizeof(lorabuf));
  #endif    


}





void lora_software_reset()
{

#if 0
   uint8_t lorabuf[8];
   lorabuf[0]=0x03;
   lorabuf[1]=0x22;
   lorabuf[2]=0x01;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);
   lorabuf[4]=0x00;
   loraSerial.write((char *)lorabuf,4);
   Serial.write((char *)lorabuf,4);

  //delay(100);
     while(1)
    {
            if(lora_packetComplete==true)
            {
                lora_packetComplete =false;
              
              #if 0
               printf("len =%d\r\n",lora_get_len);
                for(int i = 0;i<lora_get_len;i++)
                {
                  printf("%02x",Lora_Receivebuffer[i]);
                }
                printf("\r\n");
              #endif

                if((Lora_Receivebuffer[0] == 0x03 )&& (Lora_Receivebuffer[1] == 0x55 ))
                {
                                    lora_packetComplete =false;
                  lora_get_len =0x00;
                  //数据解析完成释放内存
                  heap_caps_free(Lora_Receivebuffer);
                  lora_max_buffer_size = MAX_BUFFER_SIZE;

                        return true;
                }else if((Lora_Receivebuffer[0] == 0x03 )&& (Lora_Receivebuffer[1] == 0xEE ))
                {
                                    lora_packetComplete =false;
                  lora_get_len =0x00;
                  //数据解析完成释放内存
                  heap_caps_free(Lora_Receivebuffer);
                  lora_max_buffer_size = MAX_BUFFER_SIZE;

                        return false;
                } 
            }

               delay(100);
      }


#endif

}


void lora_send_ack(uint8_t cmd,uint8_t *mac,int id_num,uint8_t *cmd_index,uint8_t status)
{
  int index =0;
  int crc = 0;
  uint8_t buffer[200]={0};

  buffer[0] = 0x55;
  buffer[1] = 0x51;
  buffer[2] = crc;

  buffer[3] = mac[0];
  buffer[4] = mac[1];
  buffer[5] = mac[2];
  buffer[6] = mac[3];
  buffer[7] = mac[4];
  buffer[8] = mac[5];

  buffer[9] = id_num;  //id
  buffer[10] = cmd;  //cmd

  buffer[11] = cmd_index[0];  
  buffer[12] = cmd_index[1]; 

  buffer[13] = 0x00;  
  buffer[14] = 0x01; //len

  buffer[15] = status;



crc =  
(buffer[0]+buffer[1]+ 
buffer[3]+buffer[4]+
buffer[5]+buffer[6]+
buffer[7]+buffer[8]+
buffer[9]+buffer[10] +
buffer[11]+buffer[12] +
buffer[13]+buffer[14] +buffer[15])&0xff; 

buffer[2] = crc; 

lora_sendData((unsigned char *)buffer, 16);


}








///////////////////////////////////////////////////////

#endif


void lora_uart_timerout_Callback(TimerHandle_t xTimer);


void uart_sleep_in_config()
{
  uart_driver_delete(UART_NUM_1);
}


void uart_sleep_out_config()
{


    // gpio_reset_pin(LORA_TXD_PIN);
    // gpio_reset_pin(LORA_RXD_PIN);

    #if VJ_LORA_ENABLE 
          const uart_config_t uart_config = {
          .baud_rate = 115200,
          .data_bits = UART_DATA_8_BITS,
          .parity = UART_PARITY_DISABLE,
          .stop_bits = UART_STOP_BITS_1,
          .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
          .source_clk = UART_SCLK_DEFAULT,
      };
  #endif
    // We won't use a buffer for sending data.
       esp_err_t err = ESP_OK;

  if( !uart_is_driver_installed(LORA_UART))
{
  // printf("uart not init\r\n");
    err = uart_driver_install(LORA_UART, RX_MAX_LENGTH * 2, 0, 300, &lora_uart_Queue, 0);
    if(err !=ESP_OK)
    {
      printf("uart driver install fail err code %x\r\n",err);
    }

}
    err =uart_param_config(LORA_UART, &uart_config);
        if(err !=ESP_OK)
    {
      printf("uart_param_config fail err code %x\r\n",err);
    }
    err = uart_set_pin(LORA_UART, LORA_TXD_PIN, LORA_RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

      if(err !=ESP_OK)
    {
    printf("uart_set_pin fail err code %x\r\n",err);
    }
	  uart_flush(LORA_UART);


}

void timer_wake_uart_sleep_out_config()
{


    gpio_reset_pin(LORA_TXD_PIN);
    gpio_reset_pin(LORA_RXD_PIN);

    #if VJ_LORA_ENABLE 
          const uart_config_t uart_config = {
          .baud_rate = 115200,
          .data_bits = UART_DATA_8_BITS,
          .parity = UART_PARITY_DISABLE,
          .stop_bits = UART_STOP_BITS_1,
          .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
          .source_clk = UART_SCLK_DEFAULT,
      };
  #endif
    // We won't use a buffer for sending data.
       esp_err_t err = ESP_OK;
    err = uart_driver_install(LORA_UART, RX_MAX_LENGTH * 2, 0, 300, &lora_uart_Queue, 0);
    if(err !=ESP_OK)
    {
      printf("uart driver install fail err code %x\r\n",err);
    }
    err =uart_param_config(LORA_UART, &uart_config);
        if(err !=ESP_OK)
    {
      printf("uart_param_config fail err code %x\r\n",err);
    }
    err = uart_set_pin(LORA_UART, LORA_TXD_PIN, LORA_RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

      if(err !=ESP_OK)
    {
    printf("uart_set_pin fail err code %x\r\n",err);
    }
	  uart_flush(LORA_UART);

    //xTaskCreate(rx_task, "lora_uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL);

}

void lora_init(void)
{
    #if !USER_QIXIN
    // lora_uart_pin_init();
    // //lora_get_cfg();
    // lora_get_rssi();
    // lora_set_Wireless_Channel(lora_channel);
    // lora_set_Wireless_bps(6);
    // //lora_set_auto_ack(0);

    // //创建ringbuffer
    // lora_ringbuf = y_ringbuf_create(ringbuffer_size);
    // if (lora_ringbuf == NULL) 
    // {
    //    printf("lora_ringbuf init fail");
    // }
    #else


#if 0
    //配置lora电源控制引脚
    gpio_config_t lora_power_pin_cfg = {};
    lora_power_pin_cfg.intr_type = GPIO_INTR_DISABLE;
    lora_power_pin_cfg.mode = GPIO_MODE_OUTPUT;
    lora_power_pin_cfg.pin_bit_mask =(1ULL<<LORA_POWER_PIN);
    lora_power_pin_cfg.pull_down_en = 0;
    lora_power_pin_cfg.pull_up_en = 0;
    gpio_config(&lora_power_pin_cfg);

    lora_set_power_level(1);
#endif


    



#if USER_DEEP_SLEEP_ENABLE
gpio_reset_pin(LORA_POWER_PIN);

        // 配置调试引脚为输入模式
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;  // 禁用中断触发
    io_conf.mode = GPIO_MODE_OUTPUT;         // 配置为输入模式
    io_conf.pin_bit_mask = (1ULL << LORA_POWER_PIN);
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; // 可根据需要启用或禁用下拉电阻
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE;     // 可根据需要启用或禁用上拉电阻
    gpio_config(&io_conf);
    gpio_set_level(LORA_POWER_PIN, 1);

#endif

#if USER_LIGHT_SLEEP_ENABLE


  #if 1
  rtc_gpio_init(LORA_POWER_PIN);
  rtc_gpio_set_direction(LORA_POWER_PIN, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_pullup_dis(LORA_POWER_PIN);
  rtc_gpio_pulldown_dis(LORA_POWER_PIN);
  rtc_gpio_set_level(LORA_POWER_PIN, 1);
  //rtc_gpio_hold_en(LORA_POWER_PIN);
  #else

          // 配置调试引脚为输入模式
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;  // 禁用中断触发
    io_conf.mode = GPIO_MODE_OUTPUT;         // 配置为输入模式
    io_conf.pin_bit_mask = (1ULL << LORA_POWER_PIN);
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; // 可根据需要启用或禁用下拉电阻
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE;     // 可根据需要启用或禁用上拉电阻
    gpio_config(&io_conf);
    gpio_set_level(LORA_POWER_PIN, 1);



  #endif

#endif

     /* Set the GPIO as a push/pull output */
    //gpio_set_direction(LORA_POWER_PIN, GPIO_MODE_OUTPUT);
    gpio_set_direction(LORA_SET_PIN, GPIO_MODE_OUTPUT);

    #if 0
    gpio_set_level(LORA_SET_PIN, 0);
    #else
    gpio_set_level(LORA_SET_PIN, 1);
    #endif

    
#if HPD_LORA_ENABLE 
        const uart_config_t uart_config = {
        .baud_rate = 9600,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
#endif



#if VJ_LORA_ENABLE 
        const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
#endif

    // We won't use a buffer for sending data.
    uart_driver_install(LORA_UART, RX_MAX_LENGTH * 2, 0, 300, &lora_uart_Queue, 0);
    uart_param_config(LORA_UART, &uart_config);
    uart_set_pin(LORA_UART, LORA_TXD_PIN, LORA_RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
	  uart_flush(LORA_UART);



    //uart_disable_rx_intr(LORA_UART);
    //uart_disable_tx_intr(LORA_UART);
    
 	//创建队列
  	//lora_sendQueue = xQueueCreate(10,    sizeof(100));
  	lora_receiveQueue = xQueueCreate(10, sizeof(100));

#if 1
	//创建串口超时定时器
	lora_uart_Timerout = xTimerCreate(
	    "lora_uart_Timer",              // 定时器名称（可以为NULL）
	    pdMS_TO_TICKS(uart_timerout_times),     // 定时器超时时间（以毫秒为单位）
	    pdFALSE,                 // 定时器为周期性（pdTRUE）还是单次（pdFALSE）
	    0,                      // 定时器ID（可以为0）
	    lora_uart_timerout_Callback          // 定时器回调函数
	);


	//创建命令回复超时定时器
	lora_cmd_Timerout = xTimerCreate(
	    "lora_cmd_Timer",              // 定时器名称（可以为NULL）
	    pdMS_TO_TICKS(1000),     // 定时器超时时间（以毫秒为单位）
	    pdFALSE,                 // 定时器为周期性（pdTRUE）还是单次（pdFALSE）
	    0,                      // 定时器ID（可以为0）
	    lora_cmd_timerout_Callback // 定时器回调函数
	);


    lora_ringbuf = y_ringbuf_create(buffer_size);
    if (lora_ringbuf == NULL) {
       printf("lora_ringbuf init fail");
    }

#endif

  #if 0

  lora_set_config_mode(0x01);

  vTaskDelay(1000 / portTICK_PERIOD_MS);

  lora_factory_config();

  vTaskDelay(5000 / portTICK_PERIOD_MS);
  #else


  #endif


  xTaskCreate(rx_task, "lora_uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL);



#if USER_NOT_SLEEP_ENABLE || USER_LIGHT_SLEEP_ENABLE ||  USER_DEEP_SLEEP_ENABLE


int  reson = is_wake_up_reson();  //返回唤醒的原因


if ((reson != ESP_SLEEP_WAKEUP_ULP) && (reson != ESP_SLEEP_WAKEUP_TIMER)&& (reson != ESP_SLEEP_WAKEUP_EXT0)) 
{
    printf("lora cmd init start\r\n");

    xTaskCreate(tx_task, "uart_tx_task", 1024*2, NULL, configMAX_PRIORITIES-1, &lora_uart_tx_handle);

}else
{
  printf("wake up lora cmd init not need init\r\n");


  lora.lora_mode = Lora_UART_Mode;   //复位直接进入透传模式
}
#endif


	xTaskCreate(lora_receive_callback_handler, "lora_at_cmd_task", 1024*4, NULL, configMAX_PRIORITIES, NULL);



    //配置串口唤醒
    #if 0
    uart_wakeup_config();
    #else
    //修复唤醒是串口会多一个
//     gpio_sleep_set_direction(LORA_RXD_PIN, GPIO_MODE_OUTPUT);
//     gpio_sleep_set_pull_mode(LORA_RXD_PIN, GPIO_FLOATING);
//     gpio_sleep_set_direction(LORA_TXD_PIN, GPIO_MODE_OUTPUT);
//     gpio_sleep_set_pull_mode(LORA_TXD_PIN, GPIO_FLOATING            /*!< Pad pull down          */
// );

//   gpio_sleep_set_direction(LORA_RXD_PIN, GPIO_MODE_INPUT);
//   gpio_sleep_set_pull_mode(LORA_RXD_PIN,  GPIO_PULLUP_ONLY            /*!< Pad pull down          */
// );



    // uart_wakeup_config();
    // //禁止串口唤醒
    // esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_UART);
    
    #endif
  // vTaskDelay(1000 / portTICK_PERIOD_MS);
    #if 0
	xTaskCreate(lora_send_callback_handler, "lora_send_cmd_task", 1024*4, NULL, configMAX_PRIORITIES, NULL);
    #endif




#if 0
VJ_Lora_set_cfg_mode(1);
VJ_Lora_set_cfg_mode(0);

uint8_t crc8( uint8_t *pData,
                    uint16_t dataLen,
                    uint8_t initialValue,
                    uint8_t polynomial );
uint8_t cmd[4]={0};

   cmd[0]=0x03;
   cmd[1]=0x01;
   cmd[2]=0x15;
   cmd[3]=crc8(cmd,3,0x55,0x07);

   printf("cmd[3] = %02x\r\n",cmd[3]);
#endif
  printf("lora init\r\n");




if ((reson != ESP_SLEEP_WAKEUP_ULP) && (reson != ESP_SLEEP_WAKEUP_TIMER)) 
{
  vTaskDelay(2000 / portTICK_PERIOD_MS);
}






    #endif
}

#define EXAMPLE_UART_WAKEUP_THRESHOLD   3

static esp_err_t uart_wakeup_config(void)
{
    /* UART will wakeup the chip up from light sleep if the edges that RX pin received has reached the threshold
     * Besides, the Rx pin need extra configuration to enable it can work during light sleep */
    gpio_sleep_set_direction(LORA_RXD_PIN, GPIO_MODE_INPUT);
    gpio_sleep_set_pull_mode(LORA_RXD_PIN, GPIO_PULLUP_ONLY);
    uart_set_wakeup_threshold(UART_NUM_1, EXAMPLE_UART_WAKEUP_THRESHOLD);
    /* Only uart0 and uart1 (if has) support to be configured as wakeup source */
    esp_sleep_enable_uart_wakeup(UART_NUM_1);
    return ESP_OK;
}

void lora_uart_pin_init(void)
{
    const uart_config_t lora_uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };

    uart_driver_install(UART_NUM_1, LORA_BUF_SIZE * 2, LORA_BUF_SIZE * 2, 20, &lora_queue, 0);
    uart_param_config(UART_NUM_1, &lora_uart_config);
    uart_set_pin(UART_NUM_1, LORA_TXD_PIN, LORA_RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);



#if 0
    gpio_config_t lora_power_pin_cfg = {};

    lora_power_pin_cfg.intr_type = GPIO_INTR_DISABLE;
    lora_power_pin_cfg.mode = GPIO_MODE_OUTPUT;
    lora_power_pin_cfg.pin_bit_mask =(1ULL<<LORA_POWER_PIN);
    lora_power_pin_cfg.pull_down_en = 0;
    lora_power_pin_cfg.pull_up_en = 0;
    gpio_config(&lora_power_pin_cfg);

    lora_set_power_level(1);

#else

  rtc_gpio_init(LORA_POWER_PIN);
  rtc_gpio_set_direction(LORA_POWER_PIN, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_level(LORA_POWER_PIN, 1);


#endif



    gpio_config_t lora_busy_pin_cfg = {};

    lora_busy_pin_cfg.intr_type = GPIO_INTR_DISABLE;
    lora_busy_pin_cfg.mode = GPIO_MODE_INPUT;
    lora_busy_pin_cfg.pin_bit_mask =(1ULL<<LORA_BUSY_PIN);
    lora_busy_pin_cfg.pull_down_en = 0;
    lora_busy_pin_cfg.pull_up_en = 0;
    gpio_config(&lora_busy_pin_cfg);



    //创建串口超时定时器
	  lora_uart_Timerout = xTimerCreate(
	    "lora_uart_Timer",              // 定时器名称（可以为NULL）
	    pdMS_TO_TICKS(uart_timerout_times),     // 定时器超时时间（以毫秒为单位）
	    pdFALSE,                 // 定时器为周期性（pdTRUE）还是单次（pdFALSE）
	    0,                      // 定时器ID（可以为0）
	    lora_uart_timerout_Callback          // 定时器回调函数
	);



//配置串口唤醒
uart_wakeup_config();

    

}


int get_lora_busy_pin()
{
    return  gpio_get_level(LORA_BUSY_PIN);
}

void lora_set_power_level(int level)
{
  #if 1
    gpio_set_level(LORA_POWER_PIN,level);
  #else
    rtc_gpio_set_level(LORA_POWER_PIN, level);

  #endif
}


void lora_uart_timerout_Callback(TimerHandle_t xTimer) {
    // 在这里执行定时器超时后的任务
    // 注意：回调函数中不要执行耗时的操作，避免影响其他任务的运行

	int length = 0 ;

	if(lora_uart_status == uart_idle)
	{
		return ;
	}
	else if(lora_uart_status == uart_receving)
	{
		//printf("uart_receving-----%s----\r\n",__FUNCTION__);
		xQueueSend(lora_receiveQueue, &length, portMAX_DELAY);
		lora_uart_status = uart_idle;
	}else if(lora_uart_status == uart_receive_complete)
	{
		//printf("uart_receive_complete-----%s----\r\n",__FUNCTION__);
		lora_uart_status = uart_idle;
	}

}


static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t* dtmp = (uint8_t*) malloc(LORA_BUF_SIZE);
    uint8_t* half_buf = NULL;
    int receive_len = 0;

    for(;;) {
        //Waiting for UART event.
        if(xQueueReceive(lora_queue, (void * )&event, (TickType_t)portMAX_DELAY)) {
            bzero(dtmp, LORA_BUF_SIZE);
            ESP_LOGD(LOG_TAG, "LORA event:");
            switch(event.type) {
                //Event of UART receving data
                /*We'd better handler data event fast, there would be much more data events than
                other types of events. If we take too much time on data event, the queue might
                be full.*/
                case UART_DATA:

                printf("uart data len = %d\r\n",event.size);
             
                #if 0
                    ESP_LOGD(LOG_TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(UART_NUM_1, dtmp, event.size, portMAX_DELAY);
                    ESP_LOGD(LOG_TAG, "[uart_rx] = %s",dtmp);
                    send_lora_queue(dtmp,event.size);
                #else
                	    if(event.size > 0)
						{
							// 启动定时器，第二个参数为定时器超时时间，设置为0表示立即启动
							if(lora_uart_status == uart_idle)
							{
								lora_uart_status = uart_receving;
								xTimerStart(lora_uart_Timerout, 0);
								//printf("first rev\r\n");
							}else if(lora_uart_status == uart_receving)
							{
								if(xTimerIsTimerActive(lora_uart_Timerout) != pdFALSE)
								{
								    xTimerReset(lora_uart_Timerout,0);
								    //printf("receiving\r\n");
								    //printf("timer is running");
								}else{
									//printf("timer is run ok");
								
								}
                                //portTICK_PERIOD_MS
                                if(event.size <= uart_fifo_size)
                                {
                                    lora_uart_status = uart_receving;
                                }
							}


							receive_len =  event.size;
							int len = uart_read_bytes(UART_NUM_1, dtmp, event.size,/*uart_timerout_times / portTICK_PERIOD_MS*/portMAX_DELAY);
                             


                    for(int i = 0;i<event.size;i++)
                    printf("-%02X",dtmp[i]);
                    printf("\r\n");
							receive_len =  len;
	
							y_ringbuf_write_remalloc_memory(lora_ringbuf, dtmp, receive_len);

					}

                #endif
                    // lora_set_receive(dtmp,event.size);
                    // lora_analytic_data(dtmp,event.size);
                    //rx_to_rawData(dtmp,rawData_16);
                    // ESP_LOGI(LOG_TAG, "[uart_rx] = %x",(int)dtmp);
                    //uart_write_bytes(UART_NUM_1, (const char*) dtmp, event.size);
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    ESP_LOGI(LOG_TAG, "hw fifo overflow");
                    // If fifo overflow happened, you should consider adding flow control for your application.
                    // The ISR has already reset the rx FIFO,
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(UART_NUM_1);
                    xQueueReset(lora_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(LOG_TAG, "ring buffer full");
                    // If buffer full happened, you should consider increasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(UART_NUM_1);
                    xQueueReset(lora_queue);
                    break;
                //Event of UART RX break detected
                case UART_BREAK:
                    ESP_LOGI(LOG_TAG, "uart rx break");
                    break;
                //Event of UART parity check error
                case UART_PARITY_ERR:
                    ESP_LOGI(LOG_TAG, "uart parity error");
                    break;
                //Event of UART frame error
                case UART_FRAME_ERR:
                    ESP_LOGI(LOG_TAG, "uart frame error");
                    break;
                //UART_PATTERN_DET
                case UART_PATTERN_DET:
                    uart_get_buffered_data_len(UART_NUM_1, &buffered_size);
                    int pos = uart_pattern_pop_pos(UART_NUM_1);
                    ESP_LOGI(LOG_TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
                    if (pos == -1) {
                        // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
                        // record the position. We should set a larger queue size.
                        // As an example, we directly flush the rx buffer here.
                        uart_flush_input(UART_NUM_1);
                    } else {
                        uart_read_bytes(UART_NUM_1, dtmp, pos, 100 / portTICK_PERIOD_MS);
                        //uint8_t pat[PATTERN_CHR_NUM + 1];
                        uint8_t pat[1024 + 1];
                        memset(pat, 0, sizeof(pat));
                        uart_read_bytes(UART_NUM_1, pat, 1024, 100 / portTICK_PERIOD_MS);
                        ESP_LOGI(LOG_TAG, "read data: %s", dtmp);
                        ESP_LOGI(LOG_TAG, "read pat : %s", pat);
                    }
                    break;
                        // Event of waking up by UART
                        case UART_WAKEUP:
                        printf("uart wakeup\r\n");
                        if(xTimerIsTimerActive(lora_uart_Timerout) != pdFALSE)
						{    
                            printf("uart timer run\r\n");
								xTimerReset(lora_uart_Timerout,0);
						}else
                        {
                              printf("uart timer not run\r\n");
                        }
                    break;
                //Others
                default:
                    printf("uart event type: %d", event.type);
                    break;
            }
        }
        // else{vTaskDelay(100 / portTICK_PERIOD_MS);}
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
    ESP_LOGE(LOG_TAG, "vTaskDelete(NULL)");
}
void lora_event_task(void *pvParameters)
{
    uart_event_task(pvParameters);
}

/**沃进方案校验和计算法
 * @funtion:crc8多项式冗余校验
 * @param 1:pData,计算数据源地址
 * @param 2:dataLen,计算数据源长度
 * @param 3:initialValue,crc结果初值
 * @param 4:polynomial,多项式
 * 
 * @return :校验结果
*/
uint8_t lora_crc8( uint8_t *pData, 
                    uint16_t dataLen,
                    uint8_t initialValue, 
                    uint8_t polynomial )
{
    uint8_t i;
    uint8_t crc;

    crc = initialValue;
    while (dataLen --)
    {
        crc ^= *pData ++;
        for( i = 0; i < 8; i++ )
        {
            if(crc & 0x80)
            {
                crc <<= 1; // shift left once
                crc ^= polynomial; // XOR with polynomial
            }
            else
            { 
                crc <<= 1; // shift left once
            }
        }
    }

    return crc;
}
int lora_set_by_serial(uint8_t cmd,uint8_t value)
{
    uint8_t lora_tx_buf[5];
    lora_tx_buf[0]=0x03;
    lora_tx_buf[1]=cmd;
    lora_tx_buf[2]=value;
    lora_tx_buf[3]=lora_crc8(lora_tx_buf,3,0x55,0x07);
    lora_tx_buf[4]=0x00;

    return uart_write_bytes(UART_NUM_1, (const char*) lora_tx_buf, 4);
}

int lora_set_cfg_mode(uint8_t mode)
{
  return lora_set_by_serial(0x26,mode);
}

int lora_reset_software(void)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x22,1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_factory(void)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x21,1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_wireless_channel_interval_bandwidth(uint8_t bandwidth)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x0B,bandwidth);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_data_outdir(uint8_t dir)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x0a,dir);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_auto_ack(uint8_t ack)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x09,ack);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
  
}

int lora_set_packet_fmt(uint8_t fmt)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x08,fmt);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_Wireless_Channel (uint8_t Channel)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x01,Channel);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
}

int lora_set_tx_power(uint8_t power)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x03,power);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return ret;
 
}

int lora_set_Wireless_bps(uint8_t bps)
{
    int ret;
    lora_set_cfg_mode(1);
    vTaskDelay(10 / portTICK_PERIOD_MS);
    ret = lora_set_by_serial(0x04,bps);
    vTaskDelay(10 / portTICK_PERIOD_MS);
    lora_set_cfg_mode(0);
    vTaskDelay(10 / portTICK_PERIOD_MS);
    return ret;
}

int lora_set_serial_bps(uint8_t bps)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x05,bps);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return  ret;
}

int lora_get_rssi(uint32_t rssi)
{
  #if 0
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x07,1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return  ret;
  #else

  #if 1
   uint8_t lorabuf[4];
   lorabuf[0]=0x03;
   lorabuf[1]=rssi;
   lorabuf[2]=0x01;
   lorabuf[3]=crc8(lorabuf,3,0x55,0x07);

  lora_sendData(lorabuf,sizeof(lorabuf));
    
 #endif

  return 0;
  #endif
}

int lora_get_version(void)
{
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x25,1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return  ret;

}
int lora_get_cfg(void)
{
    printf("cfg\n");
  int ret;
  lora_set_cfg_mode(1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  ret=lora_set_by_serial(0x24,1);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  lora_set_cfg_mode(0);
  vTaskDelay(10 / portTICK_PERIOD_MS);
  return  ret;
}

int lora_send_data(const char* lora_data,int lora_data_len)
{
    return uart_write_bytes(UART_NUM_1, (const char*) lora_data, lora_data_len);
}
static int lora_set_receive(const uint8_t* data,size_t len)
{
    //ESP_LOGI(LOG_TAG,"data len:[%d]",len);
    if(len == 0x04)//0x03+1
    {

        switch (data[1])
        {
        case 0x55:
            ESP_LOGD(LOG_TAG,"lora set is ok");
            break;
        case 0xee:
            ESP_LOGE(LOG_TAG,"lora set is fail");
        break;
        case 0x07:
            rec_rssi = data[2];
            ESP_LOGW(LOG_TAG,"rssi:%02x",data[2]);
        break;
        case 0x25:
            ESP_LOGW(LOG_TAG,"version:%02x",data[2]);
        break;        
        default:

            break;
        }
        return -1;
    }
    else if(len == 0x16)//0x15+1
    {
        if(data[1] != 0x24)
        {
            ESP_LOGE(LOG_TAG,"get lora cfg is fail");
            return -1;
        }

        ESP_LOGI(LOG_TAG,"get lora cfg is ok");
        lora_cfg_data.version = data[2];
        lora_cfg_data.wireless_ch = data[12];
        lora_cfg_data.wireless_freq_range = data[13];
        lora_cfg_data.wireless_tx_power = data[14];
        lora_cfg_data.wireless_bps = data[15];
        lora_cfg_data.serial_bps = data[16];
        lora_cfg_data.packet_fmt = data[17];
        lora_cfg_data.auto_ack = data[18];
        lora_cfg_data.outdir =data[19];
        lora_cfg_data.wireless_ch_interval_bandwidth = data[20];
        return -1;
    }
    return 1;
}
// static int lora_analytic_data(const uint8_t* data_buf,int len)
// {
//     LORA_DATA_T tmp_data;

//     memcpy((char*)tmp_data.data_buf,(char*)data_buf,len); 
//     tmp_data.data_len = len;
//     if((tmp_data.data_buf[2] == 0x5a) && (tmp_data.data_buf[3] == 0x51))
//     {   
//         // if(tmp_data.data_buf[11] != 0x01)
//         // {
//         //     ESP_LOGE(LOG_TAG," err:eflag:0x%02x",tmp_data.data_buf[9]);
//         //     printf("row:");
//         //     for(int i=0;i<len;i++)
//         //     {
//         //         printf("0x%02x ",tmp_data.data_buf[i]);
//         //     }
//         //     printf("\n");
//         //     return -1;
//         // }

//         // ESP_LOGD(LOG_TAG,"data is ok terminal number is %d,len is %d",tmp_data.data_buf[11],len);
//         if(xQueueSend(lora_data_queue,&tmp_data,0) != true)
//         {
//             ESP_LOGE(LOG_TAG,"lora queue send is fail");
//             return -1;
//         }
//         return 1;
//     }

    
//     return 1;
// }
static int send_lora_queue(const uint8_t* data_buf,int len)
{

    if(1 != lora_set_receive(data_buf,len))
    {
        return -1;
    }
    LORA_DATA_T tmp_data;

    memcpy((char*)tmp_data.data_buf,(char*)data_buf,len); 
    tmp_data.data_len = len;

    if(xQueueSend(lora_data_queue,&tmp_data,0) != true)
    {
        ESP_LOGE(LOG_TAG,"lora queue send is fail");
        return -1;
    }
    return 1;
}



void lora_send_queue_callback(uint8_t* data_buf,int len)
{

   send_lora_queue(data_buf,len);

}






