nrf52810蓝牙插座通用模块 包含大数据透传,蓝牙串口接收到数据,再由蓝牙发送到手机端的数据动态透传,数据量极大



#ifndef __AT_H
#define __AT_H




//#define at_busyTaskPrio        1
//#define at_busyTaskQueueLen    4


//#define ali
#include <stdint.h>


#define at_recvTaskPrio        0
#define at_recvTaskQueueLen    64


#define at_procTaskPrio        1
#define at_procTaskQueueLen    1


#define at_backOk        printf("\r\nOK\r\n")
#define at_backError     printf("\r\nERROR1\r\n")
#define at_backTeError   "+CTE ERROR: %d\r\n"


typedef enum{
  at_statIdle,
  at_statRecving,
  at_statProcess,
  at_statIpSending,
  at_statIpSended,
  at_statIpTraning
}at_stateType;


typedef enum{
  m_init,
  m_wact,
  m_gotip,
  m_linked,
  m_unlink,
  m_wdact
}at_mdStateType;


typedef struct
{
char *at_cmdName;
int8_t at_cmdLen;
  void (*at_testCmd)(uint8_t id);
  void (*at_queryCmd)(uint8_t id);
  void (*at_setupCmd)(uint8_t id, char *pPara);
  void (*at_exeCmd)(uint8_t id);
}at_funcationType;


typedef struct
{
  uint32_t baud;
  uint32_t saved;
}at_uartType;


void at_init(void);
void at_cmdProcess(uint8_t *pAtRcvData);


#endif



#ifndef __AT_CMD_H
#define __AT_CMD_H


#include <stdint.h>
#include <string.h>
#include "at.h"


typedef void (*at_sched_handler_t)(void);






void at_procTask(void );


extern void at_recvTask(void);


void scheduler_at_proc_task(at_sched_handler_t at_func);


#endif


#include <stdint.h>
#include <string.h>
#include <stdbool.h>


#include "at.h"
#include "at_cmd.h"
#include "app_uart.h"
#include "nrf_log.h"
#include "app_scheduler.h"
#include "uart_at_work.h"


#define at_cmdNum   14


void at_exeCmdGmr(uint8_t id)
{

printf("\r\n at_exeCmdGmr \r\n");


}


at_funcationType at_fun[at_cmdNum] = {

  {NULL, 0, NULL, NULL, NULL, NULL},
  {"E", 1, NULL, NULL, NULL, NULL},
  {"+RST", 4, NULL, NULL, NULL, NULL},
  {"+GMR", 4, NULL, NULL, NULL, at_exeCmdGmr},
  {"+BDS", 4, NULL, NULL, NULL, NULL},
{"+PID", 4, NULL, GetProductID, NULL, NULL},
{"+DID", 4, NULL, GetDeviceId, NULL, NULL},
{"+MAD", 4, NULL, GetMacAddr, NULL, NULL},
{"+SWV", 4, NULL, GetSoftWarmVerion, NULL, NULL},
{"+RTC", 4, NULL, GetRtcTime, NULL, NULL},
{"+RSY", 4, NULL, NULL, NULL, ResetSystem},
{"+SHC", 4, NULL, NULL, SwitchOpera, NULL},
{"+PTE", 4, NULL, NULL, ProductTest, NULL},
{"+URBT", 5, NULL, NULL,UartRxBleSend,NULL},
};


static int16_t at_cmdSearch(int8_t cmdLen, uint8_t *pCmd)
{
  int16_t i;


  if(cmdLen == 0)
  {
    return 0;
  }
  else if(cmdLen > 0)
  {
    for(i=1; i<at_cmdNum; i++)
    {
//      os_printf("%d len %d\r\n", cmdLen, at_fun[i].at_cmdLen);
      if(cmdLen == at_fun[i].at_cmdLen)
      {
//        os_printf("%s cmp %s\r\n", pCmd, at_fun[i].at_cmdName);
        if(memcmp(pCmd, at_fun[i].at_cmdName, cmdLen) == 0) //think add cmp len first
        {
          return i;
        }
      }
    }
  }
  return -1;
}


static int8_t at_getCmdLen(uint8_t *pCmd)
{
  uint8_t n,i;


  n = 0;
  i = 128;


  while(i--)
  {
    if((*pCmd == '\r') || (*pCmd == '=') || (*pCmd == '?') || ((*pCmd >= '0')&&(*pCmd <= '9')))
    {
      return n;
    }
    else
    {
      pCmd++;
      n++;
    }
  }
  return -1;
}


/**
  * @brief  Distinguish commad and to execution.
  * @param  pAtRcvData: point to received (command) 
  * @retval None
  */
void at_cmdProcess(uint8_t *pAtRcvData)
{
 // char tempStr[32];


  int16_t cmdId;
  int8_t cmdLen;
//  uint16_t i;


  cmdLen = at_getCmdLen(pAtRcvData);
  if(cmdLen != -1)
  {
    cmdId = at_cmdSearch(cmdLen, pAtRcvData);
  }
  else 
  {
  cmdId = -1;
  }
  if(cmdId != -1)
  {
//    os_printf("cmd id: %d\r\n", cmdId);
    pAtRcvData += cmdLen;
    if(*pAtRcvData == '\r')
    {
      if(at_fun[cmdId].at_exeCmd)
      {
        at_fun[cmdId].at_exeCmd(cmdId);
      }
      else
      {
        at_backError;
      }
    }
    else if(*pAtRcvData == '?' && (pAtRcvData[1] == '\r'))
    {
      if(at_fun[cmdId].at_queryCmd)
      {
        at_fun[cmdId].at_queryCmd(cmdId);
      }
      else
      {
        at_backError;
      }
    }
    else if((*pAtRcvData == '=') && (pAtRcvData[1] == '?') && (pAtRcvData[2] == '\r'))
    {
      if(at_fun[cmdId].at_testCmd)
      {
        at_fun[cmdId].at_testCmd(cmdId);
      }
      else
      {
        at_backError;
      }
    }
    else if((*pAtRcvData >= '0') && (*pAtRcvData <= '9') || (*pAtRcvData == '='))
    {
      if(at_fun[cmdId].at_setupCmd)
      {
        at_fun[cmdId].at_setupCmd(cmdId, (char *)pAtRcvData);
      }
      else
      {
//        uart0_sendStr("no this fun\r\n"); //Relax, it's just a code.
        at_backError;
      }
    }
    else
    {
      at_backError;
    }
  }
  else 
  {
  at_backError;
  }
}


#define at_cmdLenMax 128
#define at_dataLenMax 2048


at_stateType  at_state;


bool echoFlag = true;


static uint8_t at_cmdLine[at_cmdLenMax];


uint8_t *pDataLine;
uint8_t at_dataLine[at_dataLenMax];/////
uint16_t at_sendLen;


bool specialAtState = true;


void at_recvTask(void)
{
static uint8_t atHead[2];
static uint8_t *pCmdLine;
uint8_t temp;
    uint32_t       err_code;


    app_uart_get(&temp);

    if(at_state != at_statIpTraning) {


if((temp != '\n') && (echoFlag))  {

err_code = app_uart_put(temp);


if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) {

NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
APP_ERROR_CHECK(err_code);
}
}
    }


    switch(at_state)
    {
case at_statIdle: //serch "AT" head
atHead[0] = atHead[1];
atHead[1] = temp;
if((memcmp(atHead, "AT", 2) == 0) || (memcmp(atHead, "at", 2) == 0))
{
 printf("at_statRecving AT++++++  \r\n");
at_state = at_statRecving;
pCmdLine = at_cmdLine;
atHead[1] = 0x00;
}
else if(temp == '\n') //only get enter
{
printf("\r\nERROR\r\n");
}
break;



case at_statRecving: //push receive data to cmd line
*pCmdLine = temp;
if(temp == '\n')
{
printf("at_statProcess   \r\n");
pCmdLine++;
*pCmdLine = '\0';
at_state = at_statProcess;
if(echoFlag)
{
printf("\r\n"); ///////////
}
//post_at_semaphone();
scheduler_at_proc_task(at_procTask);


}
else if(pCmdLine >= &at_cmdLine[at_cmdLenMax - 1])
{
at_state = at_statIdle;
}
pCmdLine++;
      break;
    case at_statProcess: //process data
      if(temp == '\n')
      {
        printf("\r\nbusy p...\r\n");
      }
      break;
    case at_statIpSending:
      *pDataLine = temp;
      if((pDataLine >= &at_dataLine[at_sendLen - 1]) || (pDataLine >= &at_dataLine[at_dataLenMax - 1]))
      {
        //system_os_post(at_procTaskPrio, 0, 0);
        at_state = at_statIpSended;
      }
      else
      {
        pDataLine++;
      }


      break;

default:
if(temp == '\n')
{
}
break;


}


}






void at_procTask(void )
{
  if(at_state == at_statProcess)
  {
printf("at_procTask     \r\n"); ///////////
    at_cmdProcess(at_cmdLine);
    if(specialAtState)
    {
      at_state = at_statIdle;
    }
  }
  else if(at_state == at_statIpSended)
  {
   // at_ipDataSending(at_dataLine);//UartDev.rcv_buff.pRcvMsgBuff);
    if(specialAtState)
    {
      at_state = at_statIdle;
    }
  }
  else if(at_state == at_statIpTraning)
  {
    //at_ipDataSendNow();//UartDev.rcv_buff.pRcvMsgBuff);
  }
}






void scheduler_at_proc_task(at_sched_handler_t at_func)
{


 app_sched_event_put(NULL, 0, (app_sched_event_handler_t)at_func);


    NRF_LOG_INFO("scheduler_at_proc_task");
}






/**
  * @}

  */

#ifndef  _BIG_DATA_TASK_H_ 
#define  _BIG_DATA_TASK_H_ 






#include <stdint.h>




#define  BIG_DATA_START_EVT    1
#define  BIG_DATA_SEND_EVT     2




#define  BIG_DATA_HEADER     0x48
#define  UART_FRAME_LENTH    20
#define  SERIAL_NUM_SIZE     2


#define  START_SERIAL_NUM    1
#define  FILL_BOX_NUM        100
#define  START_MAX_SERIAL    100
#define  BIG_DATA_RX_CMD     BIG_DATA_HEADER
#define  BIG_DATA_START_CMD    0x4A
#define  BIG_DATA_END_CMD      0x49
#define  FRAME_PUT_IN_MAX_NUM  100




extern void   UartBigDataCmdProcess(uint8_t *UartFrameCmdDat);
extern void  big_data_evt_create(void);
void  FillBigDataReplyString(uint8_t *ReplyStr,  uint8_t FillSize);


void  BigDataTaskAction(uint8_t TaskId, uint16_t TaskDelay);
void  BleBigDataReplyProcess(void);



#endif





#include  "ble_nus.h"  
#include  "app_timer.h"
#include  "string.h"
#include  "uart_big_data.h"
#include  "big_data_task.h"
#include  "sk_flash.h"




static  uint8_t  BigDataRxStatus = 0;
static  uint8_t  FrameFillSerial = START_SERIAL_NUM;  
static  uint8_t  FrameFillIndex  = 0;


static  uint8_t  InvalidUartFrameNum;
static  uint8_t  InvalidUartFramePos[FILL_BOX_NUM];
static  uint8_t  BigDataCmdSta;
static  bool  BigDataBleTxStart;




#define  BLE_TX_DATA_MAX_SIZE    20
#define  BLE_REPLY_SIZE          15


#define  HEADER_SIZE         1


#define  CENTRAL_BIG_DATA_RX_START_CMD    0x4D
#define  CENTRAL_BIG_DATA_RX_END_CMD      0x4E
#define  CENTRAL_BIG_DATA_RX_PROGRE_CMD   0x4F










typedef  struct
{
uint8_t  CentralBleBigDataRxCmdType;
    uint8_t  CentralBleTxStoreBuf[BLE_TX_DATA_MAX_SIZE];
 uint16_t  CentralBleRxBytes;
 uint8_t  CentralBleReply[BLE_REPLY_SIZE];
 uint8_t  CentralReplyLenth;
}BleBigDataTx_t;


static BleBigDataTx_t   BleBigDataTx;


APP_TIMER_DEF(BigDataClock);
APP_TIMER_DEF(BigDataTxClock);


void BigDataStartHandle(void * p_context);
void BigDataTxProgreHandle(void * p_context);
uint32_t  BleAirDataTxStartCmdSend(BleBigDataTx_t *BleBigDataTx);




void  UartBigDataRxHandle(uint8_t *UartFrameData, uint8_t *RxStaCtrlType)
{
   uint8_t   i;
   uint16_t  CurSerialNum;
   bool  IsFrameHeadOk = true;
   uint8_t  UartBigDataFrame[UART_FRAME_LENTH];
   
   if(UartFrameData[0] != BIG_DATA_HEADER)
{
printf("\r\nbig data frame header error  0x48 is ok\r\n");
 IsFrameHeadOk  = false;
}


i = 0;
      while((UartFrameData[i] != '\n') || (i < (GetUartFrameDataLenth() + SERIAL_NUM_SIZE + HEADER_SIZE + 1)))
      {
i++;
}


DubegStringPut(&i, 1);
      if(i != (GetUartFrameDataLenth() + SERIAL_NUM_SIZE + HEADER_SIZE + 1))
      {
printf("\nuart frame lenth error  23 bytes is ok\n");
 return;
}

if(IsFrameHeadOk == false)
{
return;
}

CurSerialNum = (((uint16_t)UartFrameData[1]) << 8) | ((uint16_t)UartFrameData[2]);

switch(BigDataRxStatus)
      {
case  0: 
if(CurSerialNum != FrameFillSerial)
{
printf("\r\nstart frame serial number error\r\n");
   return;
}
else
{
   printf("\r\nUart frame buffer fill in ok\r\n");
   SetUartFrameInvalidPosSeriNum(FrameFillIndex, CurSerialNum);
   memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
   FillUartFrameToCorrectAdd(FrameFillIndex, UartBigDataFrame);
   
   SetCurMaxFrameSeriNum(CurSerialNum);
   SetCurTxFrameSerial(START_SERIAL_NUM);
   
   FrameFillIndex++;
   FrameFillSerial++;
   
   if(FrameFillIndex >= FILL_BOX_NUM)
{
FrameFillIndex  = 0;
 FrameFillSerial = START_SERIAL_NUM;
 BigDataRxStatus = 1;
 SetCurMaxFrameSeriNum(START_MAX_SERIAL);
 SetCurTxFrameSerial(START_SERIAL_NUM);
 *RxStaCtrlType  = 2;
}
}
break;
 
case  1:
 
  if(GetCurMaxFrameSeriNum() >= GetUartFrameMaxRxSeri())
{
printf("\r\nUart frame Rx  should be end\r\n");
   *RxStaCtrlType  = 1;
   break;
}
memset(InvalidUartFramePos, 0, sizeof(InvalidUartFramePos));
  InvalidUartFrameNum  = 0;
GetUartFrameTransferInPrama(&InvalidUartFrameNum, InvalidUartFramePos);

  if(InvalidUartFrameNum > 0)
{
if(CurSerialNum == (GetCurMaxFrameSeriNum()+1))
{
 printf("\r\nUart Rx Handle Enable\r\n");
SetCurMaxFrameSeriNum(CurSerialNum);
 SetUartFrameInvalidPosSeriNum(InvalidUartFramePos[0],CurSerialNum); 
 InvalidUartFrameNum--;
 memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
 FillUartFrameToCorrectAdd(InvalidUartFramePos[0], UartBigDataFrame);
 if(InvalidUartFrameNum != 0)
{
BigDataRxStatus  = 2;
 for(i = 0; i < InvalidUartFrameNum; i++)
 {
InvalidUartFramePos[i] = InvalidUartFramePos[i+1];
}
}
}
else
{
printf("\r\nUart frame serial number error\r\n");
}
}
else
{
   printf("\r\nNo Memory for Uart Rx, Tx On Busy\r\n");
}
break;  
 
case  2:
 
   if(GetCurMaxFrameSeriNum() >= GetUartFrameMaxRxSeri())
{
printf("\r\nUart frame Rx  should be end\r\n");
 *RxStaCtrlType  = 1;
   break;
}
 
if(CurSerialNum == (GetCurMaxFrameSeriNum()+1))
{
printf("\r\nUart Rx Handle Enable\r\n");
SetCurMaxFrameSeriNum(CurSerialNum);
 SetUartFrameInvalidPosSeriNum(InvalidUartFramePos[InvalidUartFrameNum - 1],CurSerialNum); 
 memcpy(UartBigDataFrame, &UartFrameData[3], sizeof(UartBigDataFrame));
 FillUartFrameToCorrectAdd(InvalidUartFramePos[InvalidUartFrameNum - 1], UartBigDataFrame);
 InvalidUartFrameNum--;
 if(InvalidUartFrameNum == 0)
{
BigDataRxStatus  = 1;
}
}
else
{
printf("\r\nUart frame serial number error\r\n");
}
break;
}
}








void   BigDataHandleInit(void)
{
BigDataRxStatus   = 0;
   FrameFillSerial   = START_SERIAL_NUM;
   FrameFillIndex    = 0;
   BigDataBleTxStart = false;
}








void   UartBigDataCmdProcess(uint8_t *UartFrameCmdDat)
{
   uint8_t  RxStaCtrlType = 0;
   uint8_t  DeByte = '\n';
   

   switch(BigDataCmdSta)
{
case  0:
if(UartFrameCmdDat[0] == BIG_DATA_START_CMD)
{
   if((CurUartFrameCanPutInNum() == FRAME_PUT_IN_MAX_NUM) && (GetLastUartFrameTxSta()))
{
BigDataCmdSta  = 1;
printf("\r\nBig data Uart frame can start rx\r\n");
InitUartBigDataAppParma();
BigDataHandleInit();
}
else
{
printf("\r\nBig data buffer busy on tx\r\n");
}
}
else
{
printf("\r\nBig data start rx cmd error\r\n");
}
break;
 
case  1:
DisplayWholeChrater(UartFrameCmdDat, DeByte);
if(UartFrameCmdDat[0] == BIG_DATA_RX_CMD)
{
UartBigDataRxHandle(UartFrameCmdDat, &RxStaCtrlType);
 
   if(RxStaCtrlType == 1)
{
BigDataCmdSta  = 2;
   printf("\r\nPlease let rx end\r\n");
   SetUartFrameRxFinish();
 }
else if(RxStaCtrlType == 2)
{
//启动蓝牙向手机发送大数据命令
 BigDataBleTxStart  = true;
 BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else if(UartFrameCmdDat[0] == BIG_DATA_END_CMD)
{
   if(UartFrameCmdDat[1] == 0)
{
SetLastUartFrameTxSta(1);
}
else if((UartFrameCmdDat[1] != 0) && (UartFrameCmdDat[1] <= GetUartFrameDataLenth()))
{
StoreLastUartFrameTxData(UartFrameCmdDat[1], &UartFrameCmdDat[2]);
 SetLastUartFrameTxSta(0);
}
BigDataCmdSta = 0;
SetUartFrameRxFinish();

if(BigDataBleTxStart == false)
{
 //启动蓝牙向手机发送大数据命令
BigDataBleTxStart  = true;
 BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else
{
printf("\r\nbig data frame header error  0x48 is ok\r\n");
}
break;
 
case  2:
if(UartFrameCmdDat[0] == BIG_DATA_END_CMD)
{
if(UartFrameCmdDat[1] == 0)
{
SetLastUartFrameTxSta(1);
}
else if((UartFrameCmdDat[1] != 0) && (UartFrameCmdDat[1] <= GetUartFrameDataLenth()))
{
StoreLastUartFrameTxData(UartFrameCmdDat[1], &UartFrameCmdDat[2]);
   SetLastUartFrameTxSta(0);
}
BigDataCmdSta = 0;
}
else
{
printf("\r\nbig data end command error \r\n");
}
break;
}
}








void  big_data_evt_create(void)
{
uint32_t err_code;

   err_code = app_timer_create(&BigDataClock, APP_TIMER_MODE_SINGLE_SHOT, BigDataStartHandle);
   APP_ERROR_CHECK(err_code);

   err_code = app_timer_create(&BigDataTxClock, APP_TIMER_MODE_SINGLE_SHOT, BigDataTxProgreHandle);
   APP_ERROR_CHECK(err_code);
}






void  BigDataTaskAction(uint8_t TaskId, uint16_t TaskDelay)
{
   uint32_t err_code;
switch(TaskId)
{
 case  BIG_DATA_START_EVT:
 err_code = app_timer_start(BigDataClock, APP_TIMER_TICKS(TaskDelay), NULL);
     APP_ERROR_CHECK(err_code);
 break;

case  BIG_DATA_SEND_EVT:
 err_code = app_timer_start(BigDataTxClock, APP_TIMER_TICKS(TaskDelay), NULL);
     APP_ERROR_CHECK(err_code);
 break;
}
}






void  BigDataTaskStop(uint8_t TaskId)
{
uint32_t err_code;
   switch(TaskId)
{
case  BIG_DATA_START_EVT:
err_code  = app_timer_stop(BigDataClock);
   APP_ERROR_CHECK(err_code);
   break;

case  BIG_DATA_SEND_EVT:
 err_code  = app_timer_stop(BigDataTxClock);
   APP_ERROR_CHECK(err_code);
   break;
}
}








void BigDataStartHandle(void * p_context)
{
   uint32_t err_code;

   BleBigDataTx.CentralBleBigDataRxCmdType  = CENTRAL_BIG_DATA_RX_START_CMD;
memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
BleBigDataTx.CentralBleTxStoreBuf[0] = BleBigDataTx.CentralBleBigDataRxCmdType;
   BleBigDataTx.CentralBleRxBytes  =  1;

   if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
{
err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);

 if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
{
// APP_ERROR_CHECK(err_code);
}

// if(err_code  == NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_START_EVT, 10000);
 FillBigDataReplyString("startcmdok",  sizeof("startcmdok") - 1);
}
//    else if(err_code == NRF_ERROR_BUSY)
{
// BigDataTaskAction(BIG_DATA_START_EVT, 10);
}
}
else
{
BigDataTaskAction(BIG_DATA_START_EVT, 5000);
}
}






void  BigDataTxProgreHandle(void * p_context)
{
   uint16_t  CurTxFrame;
      uint8_t   CurTxFrameOperaAddr;
      uint32_t  err_code;  

if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
{
  if(!IsUartFrameArriveEnd())
{
  CurTxFrame  =  GetCurTxFrameSerial();
if(CurTxFrame <= GetCurMaxFrameSeriNum())
{
CurTxFrameOperaAddr  =  GetUartFrameDataTabOperaAddr(CurTxFrame);
   memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetUartFrameFromDataTab(CurTxFrameOperaAddr, BleBigDataTx.CentralBleTxStoreBuf);
   BleBigDataTx.CentralBleRxBytes  = sizeof(BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);
 
   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
{
// APP_ERROR_CHECK(err_code);
}

// if(err_code  ==  NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
   FillBigDataReplyString("sendframeok",  sizeof("sendframeok") - 1);
}
// else if(err_code  == NRF_ERROR_BUSY)
{
// BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
}
}
else
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 300);
}
}
else
{
CurTxFrame  =  GetCurTxFrameSerial();
   if(CurTxFrame == (GetCurMaxFrameSeriNum()+1))
{
if(GetLastUartFrameTxSta() == 0)  //最后一帧有数据要发
{
memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetLastUartFrameTxParma(&BleBigDataTx.CentralBleRxBytes, BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);

   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
       {
//      APP_ERROR_CHECK(err_code);
       }

// if(err_code == NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
 FillBigDataReplyString("endframeok",  sizeof("endframeok") - 1);
}
// else if(err_code  == NRF_ERROR_BUSY)
{
// BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
}
}
}
else
{
CurTxFrameOperaAddr  =  GetUartFrameDataTabOperaAddr(CurTxFrame);
   memset(BleBigDataTx.CentralBleTxStoreBuf, 0, sizeof(BleBigDataTx.CentralBleTxStoreBuf));
   GetUartFrameFromDataTab(CurTxFrameOperaAddr, BleBigDataTx.CentralBleTxStoreBuf);
   BleBigDataTx.CentralBleRxBytes  = sizeof(BleBigDataTx.CentralBleTxStoreBuf);
   err_code = BleAirDataTxStartCmdSend(&BleBigDataTx);
   
   if ( (err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) )
 {
// APP_ERROR_CHECK(err_code);
 }

// if(err_code  ==  NRF_SUCCESS)
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 10000);
    FillBigDataReplyString("sendframeok",  sizeof("sendframeok") - 1);
}
// else if(err_code  == NRF_ERROR_BUSY)
 {
// BigDataTaskAction(BIG_DATA_SEND_EVT, 10);
 }
}
}
}
else
{
BigDataTaskAction(BIG_DATA_SEND_EVT, 2000);
}
}




void  FillBigDataReplyString(uint8_t *ReplyStr,  uint8_t FillSize)
{
   memset(BleBigDataTx.CentralBleReply, 0, sizeof(BleBigDataTx.CentralBleReply));
memcpy(BleBigDataTx.CentralBleReply, ReplyStr, FillSize);
   BleBigDataTx.CentralReplyLenth  = FillSize;
}






void  BleBigDataReplyProcess(void)
{
   uint16_t  CurTxFrame;

 if(memcmp(APP_ReceiveData, BleBigDataTx.CentralBleReply, BleBigDataTx.CentralReplyLenth) == 0)
{
if(memcmp(BleBigDataTx.CentralBleReply, "startcmdok", sizeof("startcmdok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_START_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 50);
}
else if(memcmp(BleBigDataTx.CentralBleReply, "sendframeok", sizeof("sendframeok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_SEND_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 2);
   CurTxFrame  =  GetCurTxFrameSerial();
   SetCurTxFrameSerial(CurTxFrame + 1);
   SetUartFrameSerialNumInvalid(GetUartFrameDataTabOperaAddr(CurTxFrame));
}
else if(memcmp(BleBigDataTx.CentralBleReply, "endframeok", sizeof("endframeok") - 1) == 0)
{
BigDataTaskStop(BIG_DATA_SEND_EVT);
   BigDataTaskAction(BIG_DATA_SEND_EVT, 50);
   SetLastUartFrameTxSta(1);
}
}
}






uint32_t  BleAirDataTxStartCmdSend(BleBigDataTx_t *BleBigDataTx)
{
   ble_gatts_hvx_params_t hvx_params;

   memset(&hvx_params, 0, sizeof(hvx_params));

   hvx_params.handle = Tx_Rx_Nux.tx_handles.value_handle;
      hvx_params.p_data = BleBigDataTx->CentralBleTxStoreBuf;
      hvx_params.p_len  = &BleBigDataTx->CentralBleRxBytes;
      hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;


      return sd_ble_gatts_hvx(Tx_Rx_Nux.conn_handle, &hvx_params);
}


#ifndef  _UART_AT_WORK_H_
#define  _UART_AT_WORK_H_










#include "socket_cfg.h"






extern void  GetProductID(uint8 id);
extern void  GetDeviceId(uint8 id);
extern void  GetMacAddr(uint8 id);
extern void  GetSoftWarmVerion(uint8 id);
extern void  GetRtcTime(uint8 id);
extern void  ResetSystem(uint8 id);
extern void   SwitchOpera(uint8 id, uint8 *cmd_rece);
extern void  ProductTest(uint8 id, uint8 *cmd_rece);
extern void   UartRxBleSend(uint8 id, uint8 *cmd_rece);














#endif




#include "sk_flash.h"
#include "string.h"
#include "fds.h"
#include "ble_gap.h"
#include "timer_correct.h"
#include "timer_modif.h"
#include "pwd_evt.h"
#include "adv_evt.h"
#include "switch_action.h"
#include "big_data_task.h"




#define   PID_STORE_SIZE   3






void  GetProductID(uint8 id)
{
uint8  ProId[PID_STORE_SIZE];

   ProId[0] = 2;
   ProId[1] = PRODUCT_ID_HIG_BYTE;
   ProId[2] = PRODUCT_ID_LOW_BYTE;
   DubegStringPut(ProId, sizeof(ProId));
}








void  GetDeviceId(uint8 id)
{
uint32  err_code;
   Socket_Id_t dev_id;
   uint8  DevId[20];

   err_code = sk_flash_access_dev_id(&dev_id, ES_FLASH_ACCESS_READ);
if(err_code == FDS_ERR_NOT_FOUND)
{

}
else
{
APP_ERROR_CHECK(err_code);
memset(DevId,0,sizeof(DevId));
 DevId[0] = dev_id.IdSize;
memcpy(&DevId[1], dev_id.IdNum, dev_id.IdSize);

 DubegStringPut(DevId, dev_id.IdSize+1);
}
}








void  GetMacAddr(uint8 id)
{
ret_code_t    err_code;
   ble_gap_addr_t device_addr;
   uint8  Mac[7];
   
   err_code = sd_ble_gap_addr_get(&device_addr);
   APP_ERROR_CHECK(err_code);

   Mac[5+1] = device_addr.addr[0];
   Mac[4+1] = device_addr.addr[1];
   Mac[3+1] = device_addr.addr[2];
   Mac[2+1] = device_addr.addr[3];
Mac[1+1] = device_addr.addr[4];
Mac[0+1] = device_addr.addr[5];
   Mac[0] = 6;

DubegStringPut(Mac, 7);
}










void  GetSoftWarmVerion(uint8 id)
{
DubegStringPut(FirmwareVersion, sizeof(FirmwareVersion));
}






uint8  GetStrSize(uint8 *Str)
{
 uint8 i = 0;

 while(Str[i] != '\n')
{
i++;
}

return  i+1;
}






void  GetRtcTime(uint8 id)
{
uint8  rtc[10];

 rtc[0] = 'w';
 rtc[1] = rtcTime.Week + 0x30;
 rtc[2] = 'h';
 rtc[3] = rtcTime.Hour/10 + 0x30;
 rtc[4] = rtcTime.Hour%10 + 0x30;
 rtc[5] = 'm';
 rtc[6] = rtcTime.Minute/10 + 0x30;
 rtc[7] = rtcTime.Minute%10 + 0x30;
 rtc[8] = '\n'; 

 DubegStringPut(rtc, GetStrSize(rtc));
}






void  ResetSystem(uint8 id)
{
     uint8 i;
ret_code_t    err_code;
   
     PASSWORDRECOVER();
   UpdateAdvData();

     for(i=0; i< NUMBER_OF_CLOCKS; i++)
   {
Sockets.Valid[i] = 0;
            Sockets.TimerActionType[i] = 0x01;
}
   
for(i=0; i< NUMBER_OF_CLOCKS; i++)
{
Sockets.IsTimerActive[i] = 0;
}

for(i=0; i< NUMBER_OF_CLOCKS; i++)
{
Sockets.IsRtcSetting[i] = 0;
}

for(i=0; i< NUMBER_OF_CLOCKS; i++)
{
Sockets.Repeat[i] = WEEK_END_REPEAT;
}

for(i= 0; i< NUMBER_OF_CLOCKS; i++)
 {
Sockets.ClockOn[i] = RTC_TIME_GROUP_ON_CFG;
}

for(i= 0; i< NUMBER_OF_CLOCKS; i++)
{
Sockets.ClockOff[i] = RTC_TIME_GROUP_OFF_CFG;
}
   
Sockets.Mode  = MODE_MANUAL;
Sockets.PowerActionType  = 0;

err_code = sk_flash_access_sockets(&Sockets, ES_FLASH_ACCESS_WRITE);
        APP_ERROR_CHECK(err_code);

DubegStringPut("ok", sizeof("ok"));
}






void   SwitchOpera(uint8 id, uint8 *cmd_rece)
{
uint8 i = 0;
   uint8 PinCtrlNum;
   uint8 ExeSta;

//    DubegStringPut(cmd_rece, sizeof(cmd_rece));
   while(cmd_rece[i] != '=')
{
i++;
}

PinCtrlNum = cmd_rece[i+1] - 0x30;
// DubegStringPut("\n", 1);
// DubegStringPut(&PinCtrlNum, 1);
// DubegStringPut("\n", 1);
ExeSta  = cmd_rece[i+3] - 0x30;
// DubegStringPut(&ExeSta, 1);
// DubegStringPut("\n", 1);

if(ExeSta)
{
 //AT+SHC=6,1
nrf_gpio_pin_write(PinCtrlNum, RELAY_ACTIVE_STATE ? 1 : 0);
 Sockets.Status = 1;
 DubegStringPut("switch on ok", sizeof("switch on ok"));
}
else
{
 //AT+SHC=6,0
nrf_gpio_pin_write(PinCtrlNum, RELAY_ACTIVE_STATE ? 0 : 1);
 Sockets.Status = 0;
 DubegStringPut("switch off ok", sizeof("switch off ok"));
}
}








void  ProductTest(uint8 id, uint8 *cmd_rece)
{
uint8_t  TestSta;

   TestSta  = cmd_rece[1] - 0x30;

   if(TestSta)
{
 //AT+PTE=1\n
nrf_gpio_pin_write( PIN_04, RELAY_ACTIVE_STATE ? 1 : 0);
nrf_gpio_pin_write( PIN_12, RELAY_ACTIVE_STATE ? 1 : 0);
 nrf_gpio_pin_write( PIN_15, RELAY_ACTIVE_STATE ? 1 : 0);
 nrf_gpio_pin_write( IO_RELAY_CTRL, RELAY_ACTIVE_STATE ? 1 : 0);
 nrf_gpio_pin_write(IO_LED_CTRL, LED_ACTIVE_STATE ? 1 : 0);
 DubegStringPut("T+ ok", sizeof("T+ ok"));
}
else
{   //AT+PTE=0
nrf_gpio_pin_write( PIN_04, RELAY_ACTIVE_STATE ? 0 : 1);
nrf_gpio_pin_write( PIN_12, RELAY_ACTIVE_STATE ? 0 : 1);
 nrf_gpio_pin_write( PIN_15, RELAY_ACTIVE_STATE ? 0 : 1);
 nrf_gpio_pin_write( IO_RELAY_CTRL, RELAY_ACTIVE_STATE ? 0 : 1);
 nrf_gpio_pin_write(IO_LED_CTRL, LED_ACTIVE_STATE ? 0 : 1);
 DubegStringPut("T- ok", sizeof("T- ok"));
}
}










void   UartRxBleSend(uint8 id, uint8 *cmd_rece)
{
DubegStringPut(cmd_rece, sizeof(cmd_rece));

   
 UartBigDataCmdProcess(&cmd_rece[1]);  
}


#ifndef  _UART_BIG_DATA_H_
#define  _UART_BIG_DATA_H_








#include <stdint.h>






extern void  InitUartBigDataAppParma(void);
extern uint8_t  SearchUartFrameValidStoreAdd(void);
extern uint16_t  GetUartFrameMaxSeriNum(void);
extern uint16_t  GetUartFrameMinSeriNum(void);
extern void   FillUartFrameToCorrectAdd(uint8_t FillAddr, const uint8_t *UartFrame);
extern void   GetUartFrameFromDataTab(uint8_t GetAddr, uint8_t *UartFrame);
extern uint8_t  GetUartFrameDataTabOperaAddr(uint16_t UartFrameSerialNum);
extern void  SetUartFrameSerialNumInvalid(uint8_t UartFrameIndex);
extern void  SetUartFrameInvalidPosSeriNum(uint8_t UartFrameIndex, uint16_t UartFrameSerial);
extern uint8_t  CurUartFrameCanPutInNum(void);
extern uint8_t  CurUartFrameCanPutOutNum(void);
extern uint16_t  GetUartFrameMaxRxSeri(void);
extern uint8_t  GetLastUartFrameTxSta(void);
extern void   StoreLastUartFrameTxData(uint8_t DataSize, uint8_t *TxVal);
extern void  SetLastUartFrameTxSta(uint8_t  FrameTxSta);
extern void  SetUartFrameRxFinish(void);
extern uint8_t  IsUartFrameArriveEnd(void);
extern void  GetLastUartFrameTxParma(uint16_t *size, uint8_t *LastDataBuf);
extern void  SetCurTxFrameSerial(uint16_t TxSeriNum);
extern uint16_t  GetCurMaxFrameSeriNum(void);
extern uint8_t  GetUartFrameDataLenth(void);
extern void  SetCurMaxFrameSeriNum(uint16_t FrameSeriNum);
extern void   GetUartFrameTransferInPrama(uint8_t *InvalidUartFrameNum, uint8_t *RecordValidUartFramePos);
extern uint16_t  GetCurTxFrameSerial(void);






#endif

#include "string.h"


#include "nrf_assert.h"
#include "uart_big_data.h"


#define  TRANSFER_FRAME_SIZE   20
#define  FRAME_NUM_FILL_SIZE   100
#define  BIG_DATA_STORE_SIZE   (TRANSFER_FRAME_SIZE*FRAME_NUM_FILL_SIZE)
#define  INVALID_SERIAL_NUM    0x0000
#define  MAX_RX_FRAME_NUM      65534
#define  RX_MAX_DATA_SIZE      (MAX_RX_FRAME_NUM*TRANSFER_FRAME_SIZE)






typedef struct
{
    uint8_t   UartFrameStoreAddr;
 uint16_t  UartFrameSerialNum;
}UartFrameInfor_t;


typedef struct
{
uint8_t   UartFrameTransferMaxSize;
 uint16_t  NextUartFrameSeriNum;     //下一个  接受帧序列号 
 uint16_t  CurAllFrameMaxSeriNum;   //所有帧最大序列号
 uint16_t  CurTxFrameSeriNum;
    uint8_t   FrameDataStoreBuf[BIG_DATA_STORE_SIZE];
 uint32_t  EnUartRxFrameTotalNum;
 UartFrameInfor_t  UartFrameInfor[FRAME_NUM_FILL_SIZE];
 uint8_t   LastFrameDataTxDone;
 uint16_t   LastFrameLenth;
 uint8_t   UartFrameEndSignal;
}UartBigDatOpera_t;




static UartBigDatOpera_t  UartBigDatOpera;
static uint8_t  LastUartFrameDataBuf[TRANSFER_FRAME_SIZE+1];




void  InitUartBigDataAppParma(void)
{
UartBigDatOpera.UartFrameTransferMaxSize = TRANSFER_FRAME_SIZE;
 UartBigDatOpera.CurAllFrameMaxSeriNum  = 0;
 UartBigDatOpera.NextUartFrameSeriNum = 1;
 memset(UartBigDatOpera.FrameDataStoreBuf, 0, sizeof(UartBigDatOpera.FrameDataStoreBuf));
 UartBigDatOpera.EnUartRxFrameTotalNum = MAX_RX_FRAME_NUM;
 memset(UartBigDatOpera.UartFrameInfor, 0, sizeof(UartBigDatOpera.UartFrameInfor));
 UartBigDatOpera.CurTxFrameSeriNum  = 0;
 memset(LastUartFrameDataBuf, 0, sizeof(LastUartFrameDataBuf));
 UartBigDatOpera.LastFrameDataTxDone  =  1;
 UartBigDatOpera.LastFrameLenth  =  0;
 UartBigDatOpera.UartFrameEndSignal  = 0;
}






void  SetUartFrameRxFinish(void)
{
UartBigDatOpera.UartFrameEndSignal  =  1;
}



uint8_t  IsUartFrameArriveEnd(void)
{
return  UartBigDatOpera.UartFrameEndSignal;
}




void   StoreLastUartFrameTxData(uint8_t DataSize, uint8_t *TxVal)
{
 uint8_t i;
 for(i = 0; i < DataSize; i++)
 {
LastUartFrameDataBuf[i] = TxVal[i];
}
UartBigDatOpera.LastFrameLenth  =  DataSize;

}






void  GetLastUartFrameTxParma(uint16_t *size, uint8_t *LastDataBuf)
{
 uint8_t  i;
*size  =  UartBigDatOpera.LastFrameLenth;
    for(i = 0; i < UartBigDatOpera.LastFrameLenth; i++)
    {
LastDataBuf[i] = LastUartFrameDataBuf[i];
}
}






void  SetLastUartFrameTxSta(uint8_t  FrameTxSta)
{
UartBigDatOpera.LastFrameDataTxDone  =  FrameTxSta;
}






uint8_t  GetLastUartFrameTxSta(void)
{
return  UartBigDatOpera.LastFrameDataTxDone;
}




uint8_t  GetUartFrameDataLenth(void)
{
return  UartBigDatOpera.UartFrameTransferMaxSize;
}




uint16_t  GetUartFrameMaxRxSeri(void)
{
return  UartBigDatOpera.EnUartRxFrameTotalNum;
}  




uint8_t  SearchUartFrameValidStoreAdd(void)
{
uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
return  i;
}
}

return  FRAME_NUM_FILL_SIZE;
}








uint8_t  GetUartFrameStoreAddr(uint8_t FrameIndex)
{
 ASSERT(FrameIndex  < FRAME_NUM_FILL_SIZE);
return  UartBigDatOpera.UartFrameInfor[FrameIndex].UartFrameStoreAddr;
}






uint16_t  GetUartFrameMaxSeriNum(void)
{
uint16_t FrameMaxSeriNum = 0;
    uint8_t i;
    
for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(FrameMaxSeriNum < UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum)
{
FrameMaxSeriNum  = UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum;
}
}

return  FrameMaxSeriNum;
}




uint16_t  GetUartFrameMinSeriNum(void)
{
uint16_t FrameMinSeriNum = MAX_RX_FRAME_NUM+1;
    uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum != 0)
{
if(FrameMinSeriNum > UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum)
{
FrameMinSeriNum  =  UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum;
}
}
}

return  FrameMinSeriNum;
}






void   FillUartFrameToCorrectAdd(uint8_t FillAddr, const uint8_t *UartFrame)
{
 ASSERT(UartFrame != NULL);
 ASSERT(sizeof(UartFrame) == TRANSFER_FRAME_SIZE);
 ASSERT(FillAddr < FRAME_NUM_FILL_SIZE);
 
memcpy(&UartBigDatOpera.FrameDataStoreBuf[TRANSFER_FRAME_SIZE*FillAddr], UartFrame, TRANSFER_FRAME_SIZE);
}






void   GetUartFrameFromDataTab(uint8_t GetAddr, uint8_t *UartFrame)
{
ASSERT(UartFrame != NULL);
 ASSERT(sizeof(UartFrame) == TRANSFER_FRAME_SIZE);
 ASSERT(GetAddr < FRAME_NUM_FILL_SIZE);

 memcpy(UartFrame, &UartBigDatOpera.FrameDataStoreBuf[TRANSFER_FRAME_SIZE*GetAddr], TRANSFER_FRAME_SIZE);
}








uint8_t  GetUartFrameDataTabOperaAddr(uint16_t UartFrameSerialNum)
{
ASSERT(UartFrameSerialNum < MAX_RX_FRAME_NUM+1);

 uint8_t i;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == UartFrameSerialNum)
{
return i;
}
}

return  FRAME_NUM_FILL_SIZE;
}










void  SetUartFrameSerialNumInvalid(uint8_t UartFrameIndex)
{
ASSERT(UartFrameIndex  < FRAME_NUM_FILL_SIZE);

 UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum  = INVALID_SERIAL_NUM;
}






void  SetUartFrameInvalidPosSeriNum(uint8_t UartFrameIndex, uint16_t UartFrameSerial)
{
ASSERT(UartFrameIndex  < FRAME_NUM_FILL_SIZE);
 ASSERT(UartFrameSerial  < MAX_RX_FRAME_NUM+1);
 ASSERT(UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum == INVALID_SERIAL_NUM);

 UartBigDatOpera.UartFrameInfor[UartFrameIndex].UartFrameSerialNum = UartFrameSerial;
}








uint8_t  CurUartFrameCanPutInNum(void)
{
uint8_t i;
 uint8_t InvalidUartFrameAccu = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
InvalidUartFrameAccu++;
}
}

return  InvalidUartFrameAccu;
}  








uint8_t  CurUartFrameCanPutOutNum(void)
{
uint8_t i;
 uint8_t ValidUartFrameAccu = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum != INVALID_SERIAL_NUM)
{
ValidUartFrameAccu++;
}
}

return ValidUartFrameAccu;
}








void   GetUartFrameTransferInPrama(uint8_t *InvalidUartFrameNum, uint8_t *RecordValidUartFramePos)
{
uint8_t  i;
 uint8_t  InvalidUartFrameCnt = 0;
 uint8_t  RecordValidIndex = 0;

 for(i = 0; i < FRAME_NUM_FILL_SIZE; i++)
 {
if(UartBigDatOpera.UartFrameInfor[i].UartFrameSerialNum == INVALID_SERIAL_NUM)
{
InvalidUartFrameCnt++;
   *InvalidUartFrameNum  = InvalidUartFrameCnt;
   RecordValidUartFramePos[RecordValidIndex] = i;
   RecordValidIndex++;
}
}
}






void  SetCurMaxFrameSeriNum(uint16_t FrameSeriNum)
{
 
UartBigDatOpera.CurAllFrameMaxSeriNum  = FrameSeriNum;
}




uint16_t  GetCurMaxFrameSeriNum(void)
{
return  UartBigDatOpera.CurAllFrameMaxSeriNum;
}




void  SetCurTxFrameSerial(uint16_t TxSeriNum)
{
ASSERT(TxSeriNum  < MAX_RX_FRAME_NUM+1);

 UartBigDatOpera.CurTxFrameSeriNum  = TxSeriNum;
}






uint16_t  GetCurTxFrameSerial(void)
{
return  UartBigDatOpera.CurTxFrameSeriNum;
}



/**
 * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */
/** @file
 *
 * @defgroup ble_sdk_uart_over_ble_main main.c
 * @{
 * @ingroup  ble_sdk_app_nus_eval
 * @brief    UART over BLE application main file.
 *
 * This file contains the source code for a sample application that uses the Nordic UART service.
 * This application uses the @ref srvlib_conn_params module.
 */






#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "nrf_sdh.h"
#include "nrf_sdh_soc.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "app_timer.h"
#include "ble_nus.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "bsp_btn_ble.h"
#include "cmd_dispatch.h"
#include "sk_evt.h"
#include "switch_action.h"
#include "timer_modif.h"
#include "BleCommand.h"
#include "sk_flash.h"
#include "name_evt.h"
#include "bond.h"
#include "adv_evt.h"
#include "socket_query.h"
#include "ble_dtm.h"
#include "pwd_evt.h"
#include "at_cmd.h"
#include "app_scheduler.h"
#include "big_data_task.h"
#include "uart_big_data.h"


#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif


#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"


//#define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */


#define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2        /**< Reply when unsupported features are requested. */


#if  defined (AXA_SMART_BOX)
#define DEVICE_NAME                     "AxaSmartBox"                               /**< Name of device. Will be included in the advertising data. */
#elif defined (AXA_SMART_SOCKET)
#define DEVICE_NAME                     "AxaSmartSocket"
#endif


//#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */


#define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */


//#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
//#define APP_ADV_TIMEOUT_IN_SECONDS      180                                         /**< The advertising timeout (in units of seconds). */




//#define APP_ADV_TIMEOUT_IN_SECONDS      BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED 


#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */


#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */




#define MAX_ITERATIONS_NEEDED_FOR_NEXT_BYTE ((5000 + 2 * UART_POLL_CYCLE) / UART_POLL_CYCLE)


#define MAX_TEST_DATA_BYTES     (15U)                /**< max number of test bytes to be used for tx and rx. */
#define UART_TX_BUF_SIZE                256*4                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */


#define BUTTON_DETECTION_DELAY          APP_TIMER_TICKS(50)


#define  NORMAL_MODE     1
#define  DTM_MODE        0




BLE_NUS_DEF(m_nus);                                                                 /**< BLE NUS service instance. */
NRF_BLE_GATT_DEF(m_gatt);                                                           /**< GATT module instance. */
BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */


static uint16_t   m_conn_handle          = BLE_CONN_HANDLE_INVALID;                 /**< Handle of the current connection. */
static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */




//static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
//{
//    {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
//};




/**@brief Function for assert macro callback.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyse
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in] line_num    Line number of the failing ASSERT call.
 * @param[in] p_file_name File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}




/**@brief Function for the GAP initialization.
 *
 * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
 *          the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
    uint32_t                err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;


    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);


    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *) DEVICE_NAME,
                                          strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);


    memset(&gap_conn_params, 0, sizeof(gap_conn_params));


    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;


    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling the data from the Nordic UART Service.
 *
 * @details This function will process the data received from the Nordic UART BLE Service and send
 *          it to the UART module.
 *
 * @param[in] p_nus    Nordic UART Service structure.
 * @param[in] p_data   Data to be send to UART module.
 * @param[in] length   Length of the data.
 */
/**@snippet [Handling the data received over BLE] */
static void nus_data_handler(ble_nus_evt_t * p_evt)
{


    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
        
        
 NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
#if  0
 uint32_t err_code;
        for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
        {
            do
            {
                err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                    APP_ERROR_CHECK(err_code);
                }
            } while (err_code == NRF_ERROR_BUSY);
        }
        if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length-1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
#endif
SocketCommandDispatch();
BleBigDataReplyProcess();
    }


}
/**@snippet [Handling the data received over BLE] */




/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_nus_init_t nus_init;


    memset(&nus_init, 0, sizeof(nus_init));


    nus_init.data_handler = nus_data_handler;


    err_code = ble_nus_init(&m_nus, &nus_init);

 Tx_Rx_Nux = m_nus;
 
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling an event from the Connection Parameters Module.
 *
 * @details This function will be called for all events in the Connection Parameters Module
 *          which are passed to the application.
 *
 * @note All this function does is to disconnect. This could have been done by simply setting
 *       the disconnect_on_fail config parameter, but instead we use the event handler
 *       mechanism to demonstrate its use.
 *
 * @param[in] p_evt  Event received from the Connection Parameters Module.
 */
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    uint32_t err_code;


    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
        err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
        APP_ERROR_CHECK(err_code);
    }
}




/**@brief Function for handling errors from the Connection Parameters module.
 *
 * @param[in] nrf_error  Error code containing information about what went wrong.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}




/**@brief Function for initializing the Connection Parameters module.
 */
static void conn_params_init(void)
{
    uint32_t               err_code;
    ble_conn_params_init_t cp_init;


    memset(&cp_init, 0, sizeof(cp_init));


    cp_init.p_conn_params                  = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail             = false;
    cp_init.evt_handler                    = on_conn_params_evt;
    cp_init.error_handler                  = conn_params_error_handler;


    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
#if  0
static void sleep_mode_enter(void)
{
    uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);


    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);


    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}
#endif




/**@brief Function for handling advertising events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
#if  0
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;


    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
//            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
//            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
//            sleep_mode_enter();
            break;
        default:
            break;
    }
}
#endif




/**@brief Function for handling BLE events.
 *
 * @param[in]   p_ble_evt   Bluetooth stack event.
 * @param[in]   p_context   Unused.
 */
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    uint32_t err_code;


    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected");
//            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
//            APP_ERROR_CHECK(err_code);
   IsDevConnect = 1;
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
   Tx_Rx_Nux.conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
   UserConnectOnEvt();
            break;


        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected");
            // LED indication will be changed when advertising starts.
   IsDevConnect = 0;
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
   Tx_Rx_Nux.conn_handle = BLE_CONN_HANDLE_INVALID;
   CurDisconPend = 1;
   UserDisconnectEvt();


            break;


#ifndef S140
        case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
        {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys =
            {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        } break;
#endif


        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break;
#if !defined (S112)
         case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
        {
            ble_gap_data_length_params_t dl_params;


            // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO
            memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
            err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL);
            APP_ERROR_CHECK(err_code);
        } break;
#endif //!defined (S112)
        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_EVT_USER_MEM_REQUEST:
            err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
            APP_ERROR_CHECK(err_code);
            break;


        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
        {
            ble_gatts_evt_rw_authorize_request_t  req;
            ble_gatts_rw_authorize_reply_params_t auth_reply;


            req = p_ble_evt->evt.gatts_evt.params.authorize_request;


            if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
            {
                if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                {
                    if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                    }
                    else
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                    }
                    auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                    err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                               &auth_reply);
                    APP_ERROR_CHECK(err_code);
                }
            }
        } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST


        default:
            // No implementation needed.
            break;
    }
}




/**@brief Function for the SoftDevice initialization.
 *
 * @details This function initializes the SoftDevice and the BLE event interrupt.
 */


static void ble_stack_init(void)
{
    ret_code_t err_code;


    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);


    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);


    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);


    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}


/*
static void ble_stack_init(void)
{
    ret_code_t err_code;


    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);


    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
    APP_ERROR_CHECK(err_code);


    // Overwrite some of the default configurations for the BLE stack.
    ble_cfg_t ble_cfg;


    // Configure the maximum number of connections.
    memset(&ble_cfg, 0, sizeof(ble_cfg));
    ble_cfg.gap_cfg.role_count_cfg.periph_role_count  = 1;
#if !defined (S112)
    ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0;
    ble_cfg.gap_cfg.role_count_cfg.central_sec_count  = 0;
#endif // !defined (S112)
    err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);
    APP_ERROR_CHECK(err_code);


    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);


    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}
*/




/**@brief Function for handling events from the GATT library. */
void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
{
    if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
    {
        m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
        NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
    }
    NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                  p_gatt->att_mtu_desired_central,
                  p_gatt->att_mtu_desired_periph);
}




/**@brief Function for initializing the GATT library. */
void gatt_init(void)
{
    ret_code_t err_code;


    err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
    APP_ERROR_CHECK(err_code);


    err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling events from the BSP module.
 *
 * @param[in]   event   Event generated by button press.
 */
#if  0
void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;


        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;


        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
            {
                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break;


        default:
            break;
    }
}
#endif




/**@brief   Function for handling app_uart events.
 *
 * @details This function will receive a single character from the app_uart module and append it to
 *          a string. The string will be be sent over BLE when the last character received was a
 *          'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length.
 */
/**@snippet [Handling the data received over UART] */
void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
//    uint32_t       err_code;


    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:

            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;


            if ((data_array[index - 1] == '\n'))
            {
                NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                NRF_LOG_HEXDUMP_DEBUG(data_array, index);
/*
                do
                {
                    uint16_t length = (uint16_t)index;
                    err_code = ble_nus_string_send(&m_nus, data_array, &length);
                    if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) )
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);
*/
//                UartBigDataCmdProcess(data_array);
                index = 0;
            }

 at_recvTask();
            break;


        case APP_UART_COMMUNICATION_ERROR:
//            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;


        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;


        default:
            break;
    }
}
/**@snippet [Handling the data received over UART] */


#if   0
uint8  GetWorkMode(void)
{
uint8 ModeAck;


#if  MODE_ACTIVE_LEVEL
 if(nrf_gpio_pin_read(IO_MODE_TEST))
{
ModeAck = NORMAL_MODE;
}
else
{
ModeAck = DTM_MODE;
}
#else
if(nrf_gpio_pin_read(IO_MODE_TEST))
{
ModeAck = DTM_MODE;
}
else
{
ModeAck = NORMAL_MODE;
}
#endif

return ModeAck;
}
#endif


// Error handler for UART
#if  0
void uart_error_handle(app_uart_evt_t * p_event)
{
    if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_communication);
    }
    else if (p_event->evt_type == APP_UART_FIFO_ERROR)
    {
        APP_ERROR_HANDLER(p_event->data.error_code);
    }
}
#endif


/**@brief  Function for initializing the UART module.
 */
/**@snippet [UART Initialization] */
#if  1
static void uart_init(void)
{
    uint32_t                     err_code;
    app_uart_comm_params_t const comm_params =
    {
        .rx_pin_no    = RX_PIN_NUMBER,
        .tx_pin_no    = TX_PIN_NUMBER,
        .rts_pin_no   = RTS_PIN_NUMBER,
        .cts_pin_no   = CTS_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity   = false,
        .baud_rate    = NRF_UART_BAUDRATE_19200
    };
#if  0
if(GetWorkMode() == NORMAL_MODE)
#endif
{
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_event_handle,
APP_IRQ_PRIORITY_LOWEST,
err_code);
}
#if  0
else
{
APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_error_handle,
                       APP_IRQ_PRIORITY_LOWEST,
                       err_code);
}
#endif
    APP_ERROR_CHECK(err_code);
}
#endif
/**@snippet [UART Initialization] */




static void advertising_init(void)
{
ret_code_t    err_code;
 ble_gap_addr_t device_addr;
 uint8 i;
//  InitAdvData();
 err_code = sd_ble_gap_addr_get(&device_addr);
 APP_ERROR_CHECK(err_code);
 
 for(i=0; i< BLE_GAP_ADDR_LEN; i++)
 {
advertData[14-i] = device_addr.addr[i];
}

// advertData[22] = (IsPassWordModify()) ? 1:0;
#if 1
if(IsPassWordModify())
{
advertData[22] = 1;
}
else
{
advertData[22] = 0;
}
#endif
 uint16 sk_scrp_length = sizeof(deviceName);
 err_code = sd_ble_gap_adv_data_set(advertData, sk_adv_length, deviceName, sk_scrp_length);
 APP_ERROR_CHECK(err_code);
/*
    ble_advdata_t advdata;
    ble_advdata_t srdata;

 ble_uuid_t adv_uuids[] = {{BLE_UUID_NUS_SERVICE, m_nus.uuid_type}};
memset(&advdata, 0, sizeof(advdata));

advdata.name_type          = BLE_ADVDATA_FULL_NAME;
advdata.include_appearance = true;
advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    advdata.uuids_complete.p_uuids  = adv_uuids;

advdata.p_service_data_array  = &SocketServiceData;


memset(&srdata, 0, sizeof(srdata));
*/
// srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
//    srdata.uuids_complete.p_uuids  = adv_uuids;

// err_code = ble_advdata_set(&advdata, &srdata);
//    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the Advertising functionality.
 */
/*
static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advertising_init_t init;


    memset(&init, 0, sizeof(init));


    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false;
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;


    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;


    init.config.ble_adv_fast_enabled  = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;


    init.evt_handler = on_adv_evt;


    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);


    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}
*/








/**@brief Function for initializing buttons and leds.
 *
 * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
 */
#if  0
static void buttons_leds_init(bool * p_erase_bonds)
{
    bsp_event_t startup_event;


    uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, bsp_event_handler);
    APP_ERROR_CHECK(err_code);


    err_code = bsp_btn_ble_init(NULL, &startup_event);
    APP_ERROR_CHECK(err_code);


    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}
#endif




/**@brief Function for initializing the nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);


    NRF_LOG_DEFAULT_BACKENDS_INIT();
}




/**@brief Function for placing the application in low power state while waiting for events.
 */
#if  1
static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}
#endif


static void leds_init(void)
{
   nrf_gpio_cfg_output(IO_LED_CTRL);
BSP_LED_CLR(IO_LED_CTRL)
}


static void  relay_init(void)
{
nrf_gpio_cfg_output(IO_RELAY_CTRL);
BSP_RELAY_CLR(IO_RELAY_CTRL)
}




static void timers_init(void)
{
uint32_t err_code;
err_code = app_timer_init();
   APP_ERROR_CHECK(err_code);
}




static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
// ret_code_t err_code;


 if(button_action != APP_BUTTON_PUSH)
{
//  SocketTaskAction(FACTORY_SET, 200);
 return;
}

SocketTaskAction(FACTORY_SET, 200);
    
switch (pin_no)
    {
        case IO_KEY_CTRL:
           
             if(Sockets.Status == 0)
            {
                if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
                {
//                    Util_stopClock(&LedFlashClock);
//    err_code = app_timer_stop(LedFlashClock);
//    APP_ERROR_CHECK(err_code);
   SocketTaskStop(LED_FLASH);
                }
                SwitchOn();
                Sockets.Status = 1;
            }
            else
            {
                if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
                {}
                else
                {
// Util_restartClock(&LedFlashClock,100);
//    err_code = app_timer_start(LedFlashClock, APP_TIMER_TICKS(100), NULL);
//    APP_ERROR_CHECK(err_code);
   SocketTaskAction(LED_FLASH, 100);
}
                
                SwitchOff();
                Sockets.Status = 0;
            }
            
            if(Tx_Rx_Nux.conn_handle != BLE_CONN_HANDLE_INVALID)
            {
 APP_SendData[0] = BLE_CMD_SWITCH;
                APP_SendData[1] = 1;
                APP_SendData[2] = Sockets.Status;
 APP_SendData[3] = SWITCH_ACTION_TRIGGER_TYPE_DEVICE_TOUCH;
 //               ProxReporter_SetParameter(PROXIMITY_SEND_DATA,sizeof(APP_SendData),APP_SendData);
 ProxReporter_SetParameter(&Tx_Rx_Nux, APP_SendData, &SocketReplyLength); 
            }
            UpdateAdvData();
            break;


        default:
            APP_ERROR_HANDLER(pin_no);
            break;
    }
}


/**@brief Function for initializing the button handler module.
 */
static void buttons_init(void)
{
    ret_code_t err_code;


    //The array must be static because a pointer to it will be saved in the button handler module.
    static app_button_cfg_t buttons[] =
    {
        {IO_KEY_CTRL, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, button_event_handler}
//    {IO_KEY_CTRL, APP_BUTTON_PUSH, BUTTON_PULL, button_event_handler}
    };


    err_code = app_button_init(buttons, sizeof(buttons) / sizeof(buttons[0]),
                               BUTTON_DETECTION_DELAY);
    APP_ERROR_CHECK(err_code);

err_code = app_button_enable();
    APP_ERROR_CHECK(err_code);
}




#define  SOCKET_INIT_EN            1
#define  DEVICE_NAME_INIT_EN       1
#define  RTC_TIME_INIT_EN          1
#define  MAC_DATA_INIT_EN          1
#define  PM_INIT_EN                1
#define  PM0_INIT_EN               1
#define  MF_INIT_EN 1
#define  MF0_INIT_EN 1
#define  POWER_CNT_INIT_EN         1


void  socket_information_init(void)
{
 
#if DEVICE_NAME_INIT_EN
 device_name_flash_init();
 for(uint8 i = 0; i < GAP_DEVICE_NAME_LEN; i++)
{
attDeviceName[i] = deviceName[i+2];
}
#endif
#if RTC_TIME_INIT_EN
rtc_time_flash_init();
#endif
#if MAC_DATA_INIT_EN
mac_data_flash_init();
if( (STORE_MAC_DATA[PHONE_FLAG] & 0x80) == 0)//密码未修改过
    {
        uint8 i=0;
for(i=0;i<6;i++)
{
STORE_MAC_DATA[PHONE_PASSWORD+i]=48+i+1;//初始密码'123456'
}
    }
#endif
#if PM_INIT_EN
phone_mac_flash_init();
#endif
#if PM0_INIT_EN
phone_mac0_flash_init();
#endif
#if MF_INIT_EN
mac_flag_flash_init();
#endif
#if MF0_INIT_EN
mac_flag0_flash_init();
#endif
#if POWER_CNT_INIT_EN
power_on_cnt_flash_init();
#endif
#if SOCKET_INIT_EN
sockets_flash_init();
 #endif




}




void  flash_init(void)
{
 ret_code_t err_code;
err_code = socket_flash_on_init();
   APP_ERROR_CHECK(err_code);
}








void  SocketEvtStart(void)
{
//  uint32_t err_code;
// err_code = app_timer_start(LedFlashClock, APP_TIMER_TICKS(100), NULL);
//  APP_ERROR_CHECK(err_code);
 
//  err_code = app_timer_start(RtcTimerClock, APP_TIMER_TICKS(100), NULL);
//  APP_ERROR_CHECK(err_code);
//    LedFlashAction(100);
   SocketTaskAction(LED_FLASH, 2000);

#if  defined(SECOND_COUNT_DOWN)
   SocketTaskAction(TIMER_DOWN_CNT, 1000);
#elif defined(MINUTE_COUNT_DOWN)
SocketTaskAction(TIMER_DOWN_CNT, 60000);
#endif
}




/**@snippet [UART Initialization] */


/**@brief Function for splitting UART command bit fields into separate command parameters for the DTM library.
 *
 * @param[in]   command   The packed UART command.
 * @return      result status from dtmlib.
 */
#if  0
static uint32_t dtm_cmd_put(uint16_t command)
{
    dtm_cmd_t      command_code = (command >> 14) & 0x03;
    dtm_freq_t     freq         = (command >> 8) & 0x3F;
    uint32_t       length       = (command >> 2) & 0x3F;
    dtm_pkt_type_t payload      = command & 0x03;


    return dtm_cmd(command_code, freq, length, payload);
}
#endif


#if  0
void  test_pin_init(void)
{
nrf_gpio_cfg_input(IO_MODE_TEST, NRF_GPIO_PIN_PULLUP);
}
#endif


#if  0
void  DtmHandler(void)
{
uint32_t    current_time;
    uint32_t    dtm_error_code;
    uint32_t    msb_time          = 0;     // Time when MSB of the DTM command was read. Used to catch stray bytes from "misbehaving" testers.
    bool        is_msb_read       = false; // True when MSB of the DTM command has been read and the application is waiting for LSB.
    uint16_t    dtm_cmd_from_uart = 0;     // Packed command containing command_code:freqency:length:payload in 2:6:6:2 bits.
    uint8_t     rx_byte;                   // Last byte read from UART.
    dtm_event_t result;                    // Result of a DTM operation.


    bsp_board_leds_init();
    
    uart_init();
 printf("DTM BOOTING");


    dtm_error_code = dtm_init();
    if (dtm_error_code != DTM_SUCCESS)
    {
        // If DTM cannot be correctly initialized, then we just return.
//        return -1;
 APP_ERROR_CHECK(dtm_error_code);
    }


    for (;;)
    {
 if(GetWorkMode() == NORMAL_MODE)
{
(void)sd_nvic_SystemReset();
}
        // Will return every timeout, 625 us.
        current_time = dtm_wait();


        if (app_uart_get(&rx_byte) != NRF_SUCCESS)
        {
            // Nothing read from the UART.
            continue;
        }


        if (!is_msb_read)
        {
            // This is first byte of two-byte command.
            is_msb_read       = true;
            dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
            msb_time          = current_time;


            // Go back and wait for 2nd byte of command word.
            continue;
        }


        // This is the second byte read; combine it with the first and process command
        if (current_time > (msb_time + MAX_ITERATIONS_NEEDED_FOR_NEXT_BYTE))
        {
            // More than ~5mS after msb: Drop old byte, take the new byte as MSB.
            // The variable is_msb_read will remains true.
            // Go back and wait for 2nd byte of the command word.
            dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
            msb_time          = current_time;
            continue;
        }


        // 2-byte UART command received.
        is_msb_read        = false;
        dtm_cmd_from_uart |= (dtm_cmd_t)rx_byte;


        if (dtm_cmd_put(dtm_cmd_from_uart) != DTM_SUCCESS)
        {
            // Extended error handling may be put here.
            // Default behavior is to return the event on the UART (see below);
            // the event report will reflect any lack of success.
        }


        // Retrieve result of the operation. This implementation will busy-loop
        // for the duration of the byte transmissions on the UART.
        if (dtm_event_get(&result))
        {
            // Report command status on the UART.
            // Transmit MSB of the result.
            while (app_uart_put((result >> 8) & 0xFF));
            // Transmit LSB of the result.
            while (app_uart_put(result & 0xFF));
        }
    }
}
#endif


void SocketOnPowerAction(void)
{
if(Sockets.PowerActionType)
{
SwitchOn();
 Sockets.Status = 1;
}
else
{
SwitchOff();
 Sockets.Status = 0;
}
}






void  relay_module_init(void)
{
nrf_gpio_cfg_output(PIN_04);
 BSP_RELAY_CLR(PIN_04)
 nrf_gpio_cfg_output(PIN_12);
 BSP_RELAY_CLR(PIN_12)
 nrf_gpio_cfg_output(PIN_15);
 BSP_RELAY_CLR(PIN_15)
}






#define APP_SCHED_MAX_EVENT_SIZE    0   /**< Maximum size of scheduler events. */
#define APP_SCHED_QUEUE_SIZE        4   /**< Maximum number of events in the scheduler queue. */


/**@brief Application main function.
 */
int main(void)
{
#if  0
 test_pin_init();
 if(GetWorkMode() == DTM_MODE)
{
DtmHandler();
}
else if(GetWorkMode() == NORMAL_MODE)
#endif
{
timers_init();
sk_event_create();
     leds_init();
relay_init();
 relay_module_init();
     buttons_init();
log_init();
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
flash_init();
socket_information_init();
advertising_init();
conn_params_init();
advertising_start();
//      AppBonding_Init();
Accumulative_PowerOn();
 SocketOnPowerAction();
SocketEvtStart();
 InitUartBigDataAppParma();
big_data_evt_create();
uart_init();
 APP_SCHED_INIT(APP_SCHED_MAX_EVENT_SIZE, APP_SCHED_QUEUE_SIZE);
printf("\r\nSmart Socket Booting!\r\n");



        // Enter main loop.
for (;;)
{
   app_sched_execute();
// power_manage();
}
}
}




/**
 * @}
 */


















































































猜你喜欢

转载自blog.csdn.net/liqiqian19871027/article/details/80495766