#include "main.h"

uint32_t current_tick = 0;  //当前运行时间   用于LED闪烁  硬件看门狗等


_Bool Networking = 0;   //联网标志位   1联网 0离线



char databuff[256];           //构建数据用的临时缓冲区
uint8_t online_counter = 1;   //查询子设备上线的计数变量
uint8_t data_counter = 1;     //查询子设备数据的计数变量

void catInit(void) {
  GPIO_InitTypeDef GPIO_Initure = {0};

//  GPIOA_RCC_ENABLE;
  GPIOC_RCC_ENABLE;

  GPIO_Initure.Pin= CAT_POW_Pin;               							//设置电源脚
  GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;                    //开漏输出
  GPIO_Initure.Pull = GPIO_NOPULL;                          //不上下拉
  GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW;                   //低速 (必需设置！)
  HAL_GPIO_Init(CAT_POW_GPIO_Port,&GPIO_Initure);            //设置

//  GPIO_Initure.Pin= CAT_RST_Pin;               							//设置复位脚(预留)
//  GPIO_Initure.Pull = GPIO_NOPULL;                          //不上下拉
//  GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD;                    //开漏输出
//  GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW;                   //低速
//  HAL_GPIO_Init(CAT_RST_GPIO_Port,&GPIO_Initure);            //设置

  GPIO_Initure.Pin = CAT_RUN_Pin ;                 //设置运行读取脚
  GPIO_Initure.Mode = GPIO_MODE_INPUT;              //输入模式
  GPIO_Initure.Pull = GPIO_PULLUP;                  //使能上拉
  GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW;                   //低速
  HAL_GPIO_Init(CAT_RUN_GPIO_Port,&GPIO_Initure);   //设置

//  GPIO_Initure.Pin = CAT_NET_Pin ;                 //设置网络读取脚
//  GPIO_Initure.Mode = GPIO_MODE_INPUT;              //输入模式
//  GPIO_Initure.Pull = GPIO_PULLUP;                  //使能上拉
//  GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW;                   //低速
//  HAL_GPIO_Init(CAT_NET_GPIO_Port,&GPIO_Initure);   //设置
}


//模块开机后会收到 +NITZ: 24/04/13,12:11:59+32,0  实际时间  2024/4/13 20:11:59秒
void catConnectServer(void) {
  uint8_t Multiple = 100; //短暂延时  默认100ms
  uint8_t netstep = 0;
  char serverbuff[100] = {0}; //例子：AT+MCONFIG="8c91c2a533b3c573","965669176415378622","ad592e4c3e7117c6",0,0,0,0
  char portbuff[50] = {0};  	//例子：AT+MIPSTART="58.17.14.95",1880
  char topicbuff[50]= {0};  	//订阅主题  才能收到云平台下发的控制指令
  sprintf(serverbuff,"AT+MCONFIG=\"%s\",\"%s\",\"%s\",0,0,0,0",MqttInfoStr.ClientID,MqttInfoStr.Username,MqttInfoStr.Passward);
  sprintf(portbuff,	 "AT+MIPSTART=\"%s\",%d",MqttInfoStr.ServerIP,MqttInfoStr.ServerPort);
  sprintf(topicbuff, "AT+MSUB=\"%s%s\",0",MqttInfoStr.Topic,MqttInfoStr.ClientID);

#if 0
  if(POWER_STA==1) {  							           //如果PB1是高电平，表示目前处于关机状态
    log_info("目前4G模块处于关机状态，准备开机");       //串口输出信息
    POWER_KEY(1);                                          //先拉高
    HAL_Delay(1500);									   //延时
    POWER_KEY(0);										   //再拉低，开机
  } else {                                                   //反之PA0是低电平，表示目前处于开机状态
    log_info("目前4G模块处于开机状态，准备重启");       //串口输出信息
    POWER_KEY(1);                                          //先拉高
    HAL_Delay(1500);								       //延时
    POWER_KEY(0);										   //再拉低，关机
    HAL_Delay(3000);                                       //间隔
    POWER_KEY(1);                                          //先拉高
    HAL_Delay(1500);									   //延时
    POWER_KEY(0);										   //再拉低，开机，完成重启
  }
#endif
  log_info("准备复位");
  POWER_KEY(1);                        //先拉高 复位
  HAL_Delay(1000);								       //延时
  POWER_KEY(0);										   //再拉低
  HAL_Delay(4000);                                       //间隔


  HAL_Delay(Multiple);
  if(catSendCmd("AT","OK", 8,30)) {
    log_info("开机失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("开机成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("关闭回显"); // 串口提示数据
  if(catSendCmd("ATE0","OK", 5, 30)) {
    log_info("关闭回显失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("关闭回显成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备查询卡状态"); // 串口提示数据
  if(catSendCmd("AT+CPIN?","READY", 5, 30)) {
    log_info("查询卡状态失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("查询卡状态成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备设置单连接\r\n"); // 串口提示数据
  if(catSendCmd("AT+CIPMUX=0","OK", 5, 30)) {
    log_info("设置单连接失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("设置单连接成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备配置网络"); // 串口提示数据
  if(catSendCmd("AT+CSTT","OK", 5, 30)) {
    log_info("配置网络失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("配置网络成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备激活网络"); // 串口提示数据
  if(catSendCmd("AT+CIICR","OK", 5, 30)) {
    log_info("激活网络失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("激活网络成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备连接服务器"); // 串口提示数据
  if(catSendCmd(serverbuff,"OK", 5, 30)) {
    log_info("连接服务器失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else  {
    netstep += 1; //步进增加
    log_info("连接服务器成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备连接TCP端口");
  if(catSendCmd(portbuff,"OK", 5, 30)) {
    log_info("连接TCP端口失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("连接TCP端口成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备配置保活时间");
  if(catSendCmd("AT+MCONNECT=1,60","OK", 5, 30)) {
    log_info("配置保活时间失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("配置保活时间成功");	//串口输出信息
  }
  HAL_Delay(Multiple);
  log_info("准备订阅主题");
  if(catSendCmd(topicbuff,"SUBACK", 5, 30)) {
    log_info("订阅主题失败，准备重启");	//串口输出信息
    NVIC_SystemReset();   //重启！
  } else {
    netstep += 1; //步进增加
    log_info("订阅主题成功");	//串口输出信息
  }
  HAL_Delay(Multiple);

  log_info("当前来到步：%d",netstep);
  if(netstep	>=	10) {
    Networking = 1;
    log_info("联网过程一切OK!");
  } else {
    Networking = 0;
    log_info("联网失败，重启");
    HAL_Delay(Multiple);
    NVIC_SystemReset();   //重启！
  }

}


/*-------------------------------------------------*/
/*函数名：卡模块发送指令                           */
/*参  数：cmd：指令                                */
/*参  数：ret：对比数据                            */
/*参  数：cnt：发送次数                            */
/*参  数：timeout：超时时间（50ms的倍数）         */
/*返回值：0：正确   其他：错误                     */
/*-------------------------------------------------*/
uint8_t catSendCmd(char *cmd, char *ret, uint8_t cnt, uint8_t timeout) {
  uint8_t result = 1; // 默认结果设为错误（非0值）
  while(cnt > 0 && result != 0) {
    CAT1_printf("%s\r\n", cmd);  // 发送指令  结尾加上换行回车
    uint8_t current_timeout = timeout;
    while(--current_timeout) {
      HAL_Delay(50);
			usart2RxHandle();//串口2数据处理
      if (strstr((char *)U2_CopyBuff, ret)) {//查找匹配字符串
        result = 0; // 找到期望的回复，结果设为正确（0值）
        break;
      }
    }
    if (current_timeout == 0) // 如果timeout<=0，说明超时，但此时未收到期望回复
      log_info("第%d次超时",cnt);
    cnt--; // 发送次数减1
  }
  return result;
}



//主动事件     LED闪烁
void activeEvents(void) {
	Networking = 1;
  
  if (HAL_GetTick() - current_tick >= 1000) {
    if(Networking){		//连接成功
      LED1_TOGGLE;  	//LED闪烁：联网    熄灭：离线
		}
    else{
      LED1_OFF;//熄灭网络指示灯
		}
    current_tick =  HAL_GetTick();  //更新时间
  }
}

