1.7.出错处理(Error Handling)

本文详细介绍了UNIX系统中错误处理的基本原则,包括errno的作用及其在多线程环境下的实现方式,如何使用strerror和perror函数打印错误信息,以及错误恢复的技术。

1.7.出错处理(Error Handling)
当UNIX函数出错时,通常返回一个负值,并且整数errno通常设置为具有附加信息意义的一个值。(unbuffered I/O functions:open,read,write,lseek和close发生错误的时候都是返回-1并设置errno)例如,open函数如成功执行则返回一个非负文件描述符,如出错则返回-1。在open出错时,有大约1 5种不同的errno值(比如文件不存在,权限问题等)。某些函数并不返回负值而是使用另一种约定。例如,返回一个指向对象的指针的大多数函数(functions that return a pointer to an object),在出错时,将返回一个null指针来表示出错。

头文件<errno.h>中定义了符号errno以及可以赋与它的各种常量。这些常量都以E开头,另外,UNIX系统手册第2section的第1page,intro(2)列出了所有这些出错常量。例如,若errno等于常量EACCES,这表示产生了权限问题(例如,没有打开所要求文件的权限)。
在Linux里,这些出错常量(error constants)列在errno(3) manual page里。(man 3 errno)
POSIX和ISO C定义errno为一个符号expanding into a modifiable lvalue of type integer.这或者是一个包含错误号(error number)的整数,或者是一个返回一个指向错误号的指针的函数。一直以来的定义是:
  extern int errno;                   //integer
-------------------------
/usr/include/errno.h

/* Declare the `errno' variable, unless it's defined as a macro by
   bits/errno.h.  This is the case in GNU, where it is a per-thread
   variable.  This redeclaration using the macro still works, but it
   will be a function declaration without a prototype and may trigger
   a -Wstrict-prototypes warning.  */
#ifndef errno
extern int errno;
#endif
-------------------------
但是在一个支持线程的环境里,因为一个进程的地址空间(process address space)被该进程内的多线程共享,所以每个线程都需要它自己的errno的本地拷贝(its own local copy of errno),以防止线程之间的干扰。例如,linux通过把errno定义成
extern int *_ _errno_location(void);                //function
#define errno  (*_ _errno_location())
来支持多线程对errno的存取。

对于errno应当知道两条规则(rules)。第一条规则是:如果没有出错,则其值绝不会被一个例程(routine)清除。(即下一次出错之前,errno一直是上一次出错后被设的值)因此,仅当函数的返回值指明出错时,才检查其值。第二条是:任一函数都不会将errno值设置为0,在<errno.h>中定义的所有常量值都不为0。
C标准定义了两个函数,它们帮助打印出错信息。
#include <string.h>
char *strerror(int errnum);
Returns: pointer to message string
此函数将参数errnum(它通常就是errno值)映射为一个出错信息字符串,并且返回指向此字符串的指针。

#include <stdio.h>
void perror(const char *msg);
perror函数在标准出错(standard error)上产生一行出错消息(基于errno的当前值),然后返回。它首先输出由参数msg指向的字符串,然后是一个冒号,一个空格,然后是对应于errno值的出错信息,然后是一个新行符。(输出行格式:*msg: 出错信息)
---------------------------------------
perror不需要指定errno,它就是针对最近的errno值进行map并输出(如figure1.8那样直接对errno进行赋值也可接收),并且通过msg可以添加一些自己的输出。
strerror返回的是char*,还需要借助如cout,fprintf将其输出,并且需要指定errno值。
---------------------------------------
Example
程序figure1.8显示了这两个出错函数的使用方法。
If this program is compiled into the file a.out, we have

   $ ./a.out
   EACCES: Permission denied
   ./a.out: No such file or directory

Figure 1.8. Demonstrate strerror and perror
#include "apue.h"
#include <errno.h>

int
main(int argc, char *argv[])
{
    fprintf(stderr, "EACCES: %s/n", strerror(EACCES));
    errno = ENOENT;
    perror(argv[0]);
    exit(0);
}
注意:我们将程序名(argv[0],其值是a.out)作为参数传递给perror。这是一个UNIX系统中的标准惯例(standard convention in the UNIX System)。使用这种方法,如程序作为管道线的一部分执行(executed as part of a pipeline),如:
prog1 < inputfile | prog2 | prog3 > outputfile
则我们就能分清三个程序中的哪一个产生了一条特定的出错消息。(良好的编程习惯)
------------------------------------------
根据figure1.8自己写的error.cpp
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
using namespace std;

int
main(int argc, char *argv[])
{
        cout<<strerror(EACCES)<<endl;

        int fd = open("text",O_RDONLY);
        cout<<fd<<endl;
        char *msg = "NOTE";
        perror(msg);

        errno = EEXIST;
        perror(argv[0]);
        exit(0);
}


[lizl@hydra04 code]$ ./errno.out
Permission denied  *与EACCES对应的string
-1
NOTE: No such file or directory *text不存在时
./errno.out: File exists *直接赋值errno时
[lizl@hydra04 code]$
------------------------------------------

错误恢复(Error Recovery)
定义在头文件<errno.h>中的所有错误(错误常量?)可以被分为两大类:致命的和非致命的(fatal and nonfatal)。一个致命的错误没有恢复行为(has no recovery action)。在这种情况下,我们所能做的就是向用户的屏幕打印一条出错信息或者将出错信息写入log文件,然后就退出。与之对应的,非致命的错误有时被粗鲁地处理对待(can sometimes be dealt with more robustly)。大部分非致命错误本质上是暂时的,比如资源短缺(resource shortage)在系统中活动比较少的情况下可能就不会发生。
与资源相关的非致命错误包括EAGAIN, ENFILE, ENOBUFS, ENOLCK, ENOSPC, ENOSR, EWOULDBLOCK,有时候当ENOMEM. EBUSY表示一个共享资源正在使用时,它们也可以看成是非致命错误(treated as a nonfatal error)。有时,当EINTR中断了一个慢的系统调用(interrupts a slow system call)时,它也可以看成是一个非致命错误。(more on this in Section 10.5).
对一个与资源相关的非致命错误的典型的恢复行为(typical recovery action for a resource-related nonfatal error)是等一段时间再重试(delay a little and try again later)。这项技术也能够应用在其它环境(circumstances)。比如出现一个错误提示一个网络连接不再有效,那么该应用程序的解决办法可能是等一小段时间然后重新建立连接。一些应用程序使用一个指数后退算法(exponential backoff algorithm),每次反复都等待一段更长的时间(waiting a longer period of time each iteration)。
最后,由应用程序的开发者决定哪个错误是可恢复的。如果能够用一个合理的策略来从一个错误中恢复(recover from an error),那么我们就能避免异常退出而改善我们程序的健壮性。

Microsoft Windows [版本 10.0.19045.6216] (c) Microsoft Corporation。保留所有权利。 C:\Users\Administrator>CD C:\Users\Administrator\Desktop\VideoSteganography C:\Users\Administrator\Desktop\VideoSteganography>python build_app.py 2025-08-23 00:43:00,801 - INFO - ============================================================ 2025-08-23 00:43:00,801 - INFO - 视频隐写术应用程序打包脚本 2025-08-23 00:43:00,802 - INFO - ============================================================ 2025-08-23 00:43:00,809 - INFO - 尝试 1/3: 删除现有虚拟环境... 2025-08-23 00:43:02,895 - INFO - 尝试 1/3: 创建虚拟环境... 2025-08-23 00:43:05,429 - INFO - 虚拟环境创建成功: venv\Scripts\python.exe 2025-08-23 00:43:05,430 - INFO - 升级pip... 2025-08-23 00:43:06,982 - INFO - pip升级成功 2025-08-23 00:43:06,982 - INFO - 安装项目依赖... 2025-08-23 00:43:08,610 - ERROR - 安装依赖失败: 1 2025-08-23 00:43:08,611 - ERROR - 错误输出: Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/ Collecting pyinstaller==6.2.0 (from -r requirements.txt (line 1)) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/a8/44/ddbc0b6c75599793ec5853adbd418e5401ceb0933d4a0e523b93e4b79a0a/pyinstaller-6.2.0-py3-none-win_amd64.whl (1.3 MB) ---------------------------------------- 1.3/1.3 MB 16.2 MB/s 0:00:00 Collecting opencv-python-headless<4.9.0,>=4.8.0 (from -r requirements.txt (line 2)) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e3/10/31b27a7473043eb5317f698ede00e7e129b2de378903bfe0bb4d785a7baf/opencv_python_headless-4.8.1.78-cp37-abi3-win_amd64.whl (38.0 MB) ---------------------------------------- 38.0/38.0 MB 80.6 MB/s 0:00:00 Collecting numpy==1.24.3 (from -r requirements.txt (line 3)) Using cached https://pypi.tuna.tsinghua.edu.cn/packages/65/5d/46da284b0bf6cfbf04082c3c5e84399664d69e41c11a33587ad49b0c64e5/numpy-1.24.3-cp310-cp310-win_amd64.whl (14.8 MB) Collecting imageio==2.31.1 (from -r requirements.txt (line 4)) Downloading https://pypi.tuna.tsinghua.edu.cn/packages/c7/b0/7b6c35b8636ed773325cdb6f5ac3cd36afba63d99e20ed59c521cf5018b4/imageio-2.31.1-py3-none-any.whl (313 kB) Collecting imageio-ffmpeg==0.4.9 (from -r requirements.txt (line 5)) Using cached https://pypi.tuna.tsinghua.edu.cn/packages/c6/01/716106099e48c4f419876d5814679a94dd7d6f441217c97c1b608123c6bb/imageio_ffmpeg-0.4.9-py3-none-win_amd64.whl (22.6 MB) Collecting pydub==0.25.1 (from -r requirements.txt (line 6)) Using cached https://pypi.tuna.tsinghua.edu.cn/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl (32 kB) ERROR: Ignored the following yanked versions: 3.23.3, 3.23.4, 3.24.1, 3.24.2, 3.24.3, 3.24.4, 3.24.5 ERROR: Ignored the following versions that require a different python version: 2.3.0 Requires-Python >=3.11; 2.3.1 Requires-Python >=3.11; 2.3.2 Requires-Python >=3.11 ERROR: Could not find a version that satisfies the requirement tkinterweb==3.14.0 (from versions: 2.1.8, 2.2.1, 3.0.0, 3.2.0, 3.3.1, 3.3.2, 3.3.4, 3.4.1, 3.4.2, 3.5.0, 3.8.0, 3.8.1, 3.9.0, 3.9.1, 3.9.4, 3.9.5, 3.9.6, 3.9.7, 3.9.10, 3.9.11, 3.9.14, 3.10.2, 3.10.3, 3.10.4, 3.10.5, 3.10.6, 3.10.7, 3.11.4, 3.12.1, 3.12.2, 3.13.1, 3.13.2, 3.14.1, 3.14.2, 3.14.3, 3.14.5, 3.14.6, 3.15.1, 3.15.2, 3.15.4, 3.15.5, 3.15.6, 3.16.1, 3.17.1, 3.17.2, 3.17.3, 3.17.4, 3.17.5, 3.17.7, 3.18.2, 3.18.5, 3.18.6, 3.18.7, 3.18.8, 3.18.9, 3.18.10, 3.18.12, 3.18.14, 3.19.2, 3.20.1, 3.20.2, 3.21.0, 3.21.1, 3.22.1, 3.23.2, 3.23.5, 3.23.7, 3.23.8, 3.23.9, 3.23.10, 3.24.6, 3.24.7, 3.24.8, 3.24.9, 3.24.10, 3.24.12, 3.24.13, 3.24.14, 3.24.15, 3.25.1, 3.25.2, 3.25.3, 3.25.4, 3.25.5, 3.25.6, 3.25.7, 3.25.8, 3.25.10, 3.25.11, 3.25.12, 3.25.13, 3.25.14, 3.25.15, 3.25.16, 3.25.17, 3.25.18, 3.25.19, 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.1.0, 4.1.1, 4.1.2, 4.1.3, 4.2.0, 4.3.0, 4.3.1, 4.4.0, 4.4.1, 4.4.2, 4.4.3, 4.4.4) ERROR: No matching distribution found for tkinterweb==3.14.0 2025-08-23 00:43:08,612 - INFO - 尝试使用官方PyPI源安装依赖... 2025-08-23 00:43:28,041 - ERROR - 官方源安装也失败: 1 2025-08-23 00:43:28,041 - ERROR - 错误输出: Collecting pyinstaller==6.2.0 (from -r requirements.txt (line 1)) Downloading pyinstaller-6.2.0-py3-none-win_amd64.whl.metadata (8.3 kB) Collecting opencv-python-headless<4.9.0,>=4.8.0 (from -r requirements.txt (line 2)) Downloading opencv_python_headless-4.8.1.78-cp37-abi3-win_amd64.whl.metadata (20 kB) Collecting numpy==1.24.3 (from -r requirements.txt (line 3)) Using cached numpy-1.24.3-cp310-cp310-win_amd64.whl.metadata (5.6 kB) Collecting imageio==2.31.1 (from -r requirements.txt (line 4)) Downloading imageio-2.31.1-py3-none-any.whl.metadata (4.7 kB) Collecting imageio-ffmpeg==0.4.9 (from -r requirements.txt (line 5)) Downloading imageio_ffmpeg-0.4.9-py3-none-win_amd64.whl.metadata (1.7 kB) Collecting pydub==0.25.1 (from -r requirements.txt (line 6)) Using cached pydub-0.25.1-py2.py3-none-any.whl.metadata (1.4 kB) ERROR: Ignored the following yanked versions: 3.23.3, 3.23.4, 3.24.1, 3.24.2, 3.24.3, 3.24.4, 3.24.5 ERROR: Ignored the following versions that require a different python version: 2.3.0 Requires-Python >=3.11; 2.3.1 Requires-Python >=3.11; 2.3.2 Requires-Python >=3.11 ERROR: Could not find a version that satisfies the requirement tkinterweb==3.14.0 (from versions: 2.1.8, 2.2.1, 3.0.0, 3.2.0, 3.3.1, 3.3.2, 3.3.4, 3.4.1, 3.4.2, 3.5.0, 3.8.0, 3.8.1, 3.9.0, 3.9.1, 3.9.4, 3.9.5, 3.9.6, 3.9.7, 3.9.10, 3.9.11, 3.9.14, 3.10.2, 3.10.3, 3.10.4, 3.10.5, 3.10.6, 3.10.7, 3.11.4, 3.12.1, 3.12.2, 3.13.1, 3.13.2, 3.14.1, 3.14.2, 3.14.3, 3.14.5, 3.14.6, 3.15.1, 3.15.2, 3.15.4, 3.15.5, 3.15.6, 3.16.1, 3.17.1, 3.17.2, 3.17.3, 3.17.4, 3.17.5, 3.17.7, 3.18.2, 3.18.5, 3.18.6, 3.18.7, 3.18.8, 3.18.9, 3.18.10, 3.18.12, 3.18.14, 3.19.2, 3.20.1, 3.20.2, 3.21.0, 3.21.1, 3.22.1, 3.23.2, 3.23.5, 3.23.7, 3.23.8, 3.23.9, 3.23.10, 3.24.6, 3.24.7, 3.24.8, 3.24.9, 3.24.10, 3.24.12, 3.24.13, 3.24.14, 3.24.15, 3.25.1, 3.25.2, 3.25.3, 3.25.4, 3.25.5, 3.25.6, 3.25.7, 3.25.8, 3.25.10, 3.25.11, 3.25.12, 3.25.13, 3.25.14, 3.25.15, 3.25.16, 3.25.17, 3.25.18, 3.25.19, 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.1.0, 4.1.1, 4.1.2, 4.1.3, 4.2.0, 4.3.0, 4.3.1, 4.4.0, 4.4.1, 4.4.2, 4.4.3, 4.4.4) ERROR: No matching distribution found for tkinterweb==3.14.0 2025-08-23 00:43:28,043 - INFO - 尝试使用opencv-python替代headless版本... Traceback (most recent call last): File "C:\Users\Administrator\Desktop\VideoSteganography\build_app.py", line 117, in install_dependencies subprocess.run( File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 526, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['venv\\Scripts\\python.exe', '-m', 'pip', 'install', '-r', 'requirements.txt']' returned non-zero exit status 1. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Administrator\Desktop\VideoSteganography\build_app.py", line 154, in install_dependencies subprocess.run( File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 526, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['venv\\Scripts\\python.exe', '-m', 'pip', 'install', '-r', 'requirements.txt', '--index-url', 'https://pypi.org/simple']' returned non-zero exit status 1. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\Administrator\Desktop\VideoSteganography\build_app.py", line 369, in <module> sys.exit(main()) File "C:\Users\Administrator\Desktop\VideoSteganography\build_app.py", line 347, in main if not install_dependencies(venv_dir): File "C:\Users\Administrator\Desktop\VideoSteganography\build_app.py", line 178, in install_dependencies if "opencv-python-headless" in default_deps: UnboundLocalError: local variable 'default_deps' referenced before assignment C:\Users\Administrator\Desktop\VideoSteganography>
最新发布
08-24
UART1 and UART2 initialized. ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite ERR: Failed to rbWrite rbCreate Success DHT11 OK: T=30, H=53Warning:gizProtocolResendData 589 2 0Warning: timeout, resend data valueFan_OnOff ChangedvalueLED_OnOff Changedchanged, report dataDHT11 OK: T=30, H=53Warning:gizProtocolResendData 857 604 0Warning: timeout, resend data DHT11 OK: T=30, H=53Warning:gizProtocolResendData 1118 865 1Warning: timeout, resend data DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53valuelight Changedchanged, report dataDHT11 OK: T=30, H=53Warning:gizProtocolResendData 6950 6697 0Warning: timeout, resend data DHT11 OK: T=30, H=53Warning:gizProtocolResendData 7211 6958 1Warning: timeout, resend data DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53DHT11 OK: T=30, H=53连不上网 #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "DHT11.h" #include "LED.h" #include "Light_Sensor.h" // 光敏电阻驱动(PA7) #include "Fan.h" #include "Buzzer.h" #include "TIM3.h" // TIM3定时器(1ms中断) #include "usart.h" // 串口通信(含机智云数据传输) #include "gizwits_product.h" // 机智云SDK #include "gizwits_protocol.h" // 阈值定义 #define TEMP_THRESHOLD 29 // 温度阈值(℃) #define LIGHT_THRESHOLD 128 // 光照阈值(0-255) extern uint8_t temp; extern uint8_t humi; extern dataPoint_t currentDataPoint; // 全局变量 uint8_t light_intensity; // 光照强度 void controlPeripherals(void) { // 温度控制风扇 if (temp > TEMP_THRESHOLD) { Control_Fan(1); // 风扇开启 currentDataPoint.valueFan_OnOff = 1; // 更新机智云风扇状态 OLED_ShowString(4, 1, "Fan: ON "); } else { Control_Fan(0); // 风扇关闭 currentDataPoint.valueFan_OnOff = 0; // 更新机智云风扇状态 OLED_ShowString(4, 1, "Fan: OFF"); } // 光照控制LED if (light_intensity < LIGHT_THRESHOLD) { Control_Light(1); // 光照不足,开灯 currentDataPoint.valueLED_OnOff = 1; } else { Control_Light(0); // 光照充足,关灯 currentDataPoint.valueLED_OnOff = 0; } // 超阈值报警(温度+湿度) if (temp > TEMP_THRESHOLD) { Buzzer_ON(); // 蜂鸣器报警 } else { Buzzer_OFF(); // 停止报警 } } // OLED显示更新 void updateOLED(void) { // 光照显示 OLED_ShowString(1, 1, "Light:"); OLED_ShowNum(1, 7, light_intensity, 3); OLED_ShowString(1, 10, "/255"); // 温度显示 OLED_ShowString(2, 1, "Temp:"); if(temp == 0xFF) { // 0xFF表示读取错误 OLED_ShowString(2, 6, "ERR"); } else { OLED_ShowNum(2, 6, temp, 2); OLED_ShowCC_F16x16(2, 8, 0); // 显示℃ } // 湿度显示 OLED_ShowString(3, 1, "Humi:"); OLED_ShowNum(3, 6, humi, 2); OLED_ShowCC_F16x16(3, 8, 1); // %显示 } int main(void) { // 初始化外设(按依赖顺序) NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_Init(); uart1_init(115200); // 初始化USART1,用于printf输出 uart2_init(115200); printf("UART1 and UART2 initialized.\r\n"); // 现在应该可以输出 OLED_Init(); // OLED显示屏 OLED_ShowString(1, 1, "System Start"); Delay_ms(1000); OLED_Clear(); LED_Init(); // LED初始化 LightSensor_Init(); // 光敏电阻初始化(PA7) ADC1_Init(); // ADC初始化(读取光敏电阻) DHT11_UserConfig(); // DHT11温湿度传感器初始化 Fan_Init(); // 风扇初始化 Buzzer_Init(); // 蜂鸣器初始化 GENERAL_TIM_Init(); // TIM3初始化(1ms中断,机智云定时) userInit(); // 机智云用户初始化 gizwitsInit(); gizwitsSetMode(WIFI_AIRLINK_MODE); // 机智云设备初始化 Delay_ms(500); OLED_Clear(); // 清屏准备正式显示 while (1) { light_intensity = Get_Light_Intensity(); // 1. 采集传感器数据 collectSensorData(); // 2. 更新机智云数据点(供云端读取) currentDataPoint.valuetemp = temp; // 温度数据 currentDataPoint.valuehumi = humi; // 湿度数据 currentDataPoint.valuelight = light_intensity;// 光照数据 // 3. 控制外设(风扇、LED、蜂鸣器) controlPeripherals(); // 4. 更新OLED显示 updateOLED(); // 5. 机智云任务处理(数据上报/指令接收) userHandle(); // 用户自定义处理 gizwitsHandle(&currentDataPoint); // 机智云核心处理 // 6. 延时,降低CPU占用 Delay_ms(200); } } #include "sys.h" #include "usart.h" #include "gizwits_product.h" #if 1 #pragma import(__use_no_semihosting) //Ҫ׼ࠢѨҪք֧Ԗگ˽ struct __FILE { int handle; }; FILE __stdout; //֨ӥ_sys_exit()ӔҜĢʹԃѫ׷ܺģʽ void _sys_exit(int x) { x = x; } int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0); USART1->DR = (u8) ch; return ch; } #endif #if EN_USART1_RX //ɧڻʹŜ‹ޓ˕ //Ԯࠚ1א׏ؾϱԌѲ //עӢ,ׁȡUSARTx->SRŜҜĢĪĻǤĮքխϳ u8 USART_RX_BUF[USART_REC_LEN]; //ޓ˕ۺԥ,خճUSART_REC_LENٶؖޚ. //ޓ˕״̬ //bit15ì ޓ˕ΪԉҪ־ //bit14ì ޓ˕ս0x0d //bit13~0ì ޓ˕սքԐЧؖޚ˽Ŀ u16 USART_RX_STA=0; //ޓ˕״̬Ҫ݇ void uart1_init(u32 bound){ //GPIO׋ࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹŜUSART1ìGPIOAʱד //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART1, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א׏ USART_Cmd(USART1, ENABLE); //ʹŜԮࠚ1 } void uart2_init(u32 bound){ //GPIO׋ࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //ʹŜUSART2ìGPIOAʱד RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART2, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א׏ USART_Cmd(USART2, ENABLE); //ʹŜԮࠚ1 // 添加串口错误中断使能 USART_ITConfig(USART2, USART_IT_ORE, ENABLE); // 过载错误 USART_ITConfig(USART2, USART_IT_NE, ENABLE); // 噪声错误 USART_ITConfig(USART2, USART_IT_FE, ENABLE); // 帧错误 } void USART1_IRQHandler(void) //Ԯࠚ1א׏ؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //ޓ˕א׏(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); Res =USART_ReceiveData(USART1); //ׁȡޓ˕սք˽ߝ } } void USART2_IRQHandler(void) //Ԯࠚ2א׏ؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART2, USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_ORE); USART_ReceiveData(USART2); // 清除溢出 } if(USART_GetITStatus(USART2, USART_IT_NE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_NE); } if(USART_GetITStatus(USART2, USART_IT_FE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_FE); } if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //ޓ˕א׏(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART2,USART_IT_RXNE); Res =USART_ReceiveData(USART2); //ׁȡޓ˕սք˽ߝ gizPutData(&Res,1); } } #endif /** ************************************************************ * @file gizwits_protocol.c * @brief Corresponding gizwits_product.c header file (including product hardware and software version definition) * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note 机智云.只为智能硬件而生 * Gizwits Smart Cloud for Smart Products * 链接|增值ֵ|开放|中立|安全|自有|自由|生态 * www.gizwits.com * ***********************************************************/ #include "ringBuffer.h" #include "gizwits_product.h" #include "dataPointTools.h" /** Protocol global variables **/ gizwitsProtocol_t gizwitsProtocol; /**@name The serial port receives the ring buffer implementation * @{ */ rb_t pRb; ///< Ring buffer structure variable static uint8_t rbBuf[RB_MAX_LEN]; ///< Ring buffer data cache buffer /**@} */ /** * @brief Write data to the ring buffer * @param [in] buf : buf adress * @param [in] len : byte length * @return correct : Returns the length of the written data failure : -1 */ int32_t gizPutData(uint8_t *buf, uint32_t len) { int32_t count = 0; if(NULL == buf) { GIZWITS_LOG("ERR: gizPutData buf is empty \n"); return -1; } count = rbWrite(&pRb, buf, len); if(count != len) { GIZWITS_LOG("ERR: Failed to rbWrite \n"); return -1; } return count; } /** * @brief Protocol header initialization * * @param [out] head : Protocol header pointer * * @return 0, success; other, failure */ static int8_t gizProtocolHeadInit(protocolHead_t *head) { if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolHeadInit head is empty \n"); return -1; } memset((uint8_t *)head, 0, sizeof(protocolHead_t)); head->head[0] = 0xFF; head->head[1] = 0xFF; return 0; } /** * @brief Protocol ACK check processing function * * @param [in] data : data adress * @param [in] len : data length * * @return 0, suceess; other, failure */ static int8_t gizProtocolWaitAck(uint8_t *gizdata, uint32_t len) { if(NULL == gizdata) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); memcpy((uint8_t *)gizwitsProtocol.waitAck.buf, gizdata, len); gizwitsProtocol.waitAck.dataLen = (uint16_t)len; gizwitsProtocol.waitAck.flag = 1; gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); return 0; } /** * @brief generates "controlled events" according to protocol * @param [in] issuedData: Controlled data * @param [out] info: event queue * @param [out] dataPoints: data point data * @return 0, the implementation of success, non-0, failed */ static int8_t ICACHE_FLASH_ATTR gizDataPoint2Event(gizwitsIssued_t *issuedData, eventInfo_t *info, dataPoint_t *dataPoints) { if((NULL == issuedData) || (NULL == info) ||(NULL == dataPoints)) { GIZWITS_LOG("gizDataPoint2Event Error , Illegal Param\n"); return -1; } /** Greater than 1 byte to do bit conversion **/ if(sizeof(issuedData->attrFlags) > 1) { if(-1 == gizByteOrderExchange((uint8_t *)&issuedData->attrFlags,sizeof(attrFlags_t))) { GIZWITS_LOG("gizByteOrderExchange Error\n"); return -1; } } if(0x01 == issuedData->attrFlags.flagFan_OnOff) { info->event[info->num] = EVENT_Fan_OnOff; info->num++; dataPoints->valueFan_OnOff = gizStandardDecompressionValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } if(0x01 == issuedData->attrFlags.flagLED_OnOff) { info->event[info->num] = EVENT_LED_OnOff; info->num++; dataPoints->valueLED_OnOff = gizStandardDecompressionValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } return 0; } /** * @brief contrasts the current data with the last data * * @param [in] cur: current data point data * @param [in] last: last data point data * * @return: 0, no change in data; 1, data changes */ static int8_t ICACHE_FLASH_ATTR gizCheckReport(dataPoint_t *cur, dataPoint_t *last) { int8_t ret = 0; static uint32_t lastReportTime = 0; uint32_t currentTime = 0; if((NULL == cur) || (NULL == last)) { GIZWITS_LOG("gizCheckReport Error , Illegal Param\n"); return -1; } currentTime = gizGetTimerCount(); if(last->valueFan_OnOff != cur->valueFan_OnOff) { GIZWITS_LOG("valueFan_OnOff Changed\n"); ret = 1; } if(last->valueLED_OnOff != cur->valueLED_OnOff) { GIZWITS_LOG("valueLED_OnOff Changed\n"); ret = 1; } if(last->valuetemp != cur->valuetemp) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuetemp Changed\n"); ret = 1; } } if(last->valuehumi != cur->valuehumi) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuehumi Changed\n"); ret = 1; } } if(last->valuelight != cur->valuelight) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuelight Changed\n"); ret = 1; } } if(1 == ret) { lastReportTime = gizGetTimerCount(); } return ret; } /** * @brief User data point data is converted to wit the cloud to report data point data * * @param [in] dataPoints: user data point data address * @param [out] devStatusPtr: wit the cloud data point data address * * @return 0, the correct return; -1, the error returned */ static int8_t ICACHE_FLASH_ATTR gizDataPoints2ReportData(dataPoint_t *dataPoints , devStatus_t *devStatusPtr) { if((NULL == dataPoints) || (NULL == devStatusPtr)) { GIZWITS_LOG("gizDataPoints2ReportData Error , Illegal Param\n"); return -1; } gizMemset((uint8_t *)devStatusPtr->wBitBuf,0,sizeof(devStatusPtr->wBitBuf)); gizStandardCompressValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueFan_OnOff); gizStandardCompressValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueLED_OnOff); gizByteOrderExchange((uint8_t *)devStatusPtr->wBitBuf,sizeof(devStatusPtr->wBitBuf)); devStatusPtr->valuetemp = gizY2X(temp_RATIO, temp_ADDITION, dataPoints->valuetemp); devStatusPtr->valuehumi = gizY2X(humi_RATIO, humi_ADDITION, dataPoints->valuehumi); devStatusPtr->valuelight = exchangeBytes(gizY2X(light_RATIO, light_ADDITION, dataPoints->valuelight)); return 0; } /** * @brief This function is called by the Gagent module to receive the relevant protocol data from the cloud or APP * @param [in] inData The protocol data entered * @param [in] inLen Enter the length of the data * @param [out] outData The output of the protocol data * @param [out] outLen The length of the output data * @return 0, the implementation of success, non-0, failed */ static int8_t gizProtocolIssuedProcess(char *did, uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t *outLen) { uint8_t issuedAction = inData[0]; if((NULL == inData)||(NULL == outData)||(NULL == outLen)) { GIZWITS_LOG("gizProtocolIssuedProcess Error , Illegal Param\n"); return -1; } if(NULL == did) { memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t)); switch(issuedAction) { case ACTION_CONTROL_DEVICE: gizDataPoint2Event((gizwitsIssued_t *)&inData[1], &gizwitsProtocol.issuedProcessEvent,&gizwitsProtocol.gizCurrentDataPoint); gizwitsProtocol.issuedFlag = ACTION_CONTROL_TYPE; outData = NULL; *outLen = 0; break; case ACTION_READ_DEV_STATUS: if(0 == gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,&gizwitsProtocol.reportData.devStatus)) { memcpy(outData+1, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(gizwitsReport_t)); outData[0] = ACTION_READ_DEV_STATUS_ACK; *outLen = sizeof(gizwitsReport_t)+1; } else { return -1; } break; case ACTION_W2D_TRANSPARENT_DATA: memcpy(gizwitsProtocol.transparentBuff, &inData[1], inLen-1); gizwitsProtocol.transparentLen = inLen - 1; gizwitsProtocol.issuedProcessEvent.event[gizwitsProtocol.issuedProcessEvent.num] = TRANSPARENT_DATA; gizwitsProtocol.issuedProcessEvent.num++; gizwitsProtocol.issuedFlag = ACTION_W2D_TRANSPARENT_TYPE; outData = NULL; *outLen = 0; break; default: break; } } return 0; } /** * @brief The protocol sends data back , P0 ACK * * @param [in] head : Protocol head pointer * @param [in] data : Payload data * @param [in] len : Payload data length * @param [in] proFlag : DID flag ,1 for Virtual sub device did ,0 for single product or gateway * * @return : 0,Ack success; * -1Input Param Illegal * -2,Serial send faild */ static int32_t gizProtocolIssuedDataAck(protocolHead_t *head, uint8_t *gizdata, uint32_t len, uint8_t proFlag) { int32_t ret = 0; uint8_t tx_buf[RB_MAX_LEN]; uint32_t offset = 0; uint8_t sDidLen = 0; uint16_t data_len = 0; uint8_t *pTxBuf = tx_buf; if(NULL == gizdata) { GIZWITS_LOG("[ERR] data Is Null \n"); return -1; } if(0x1 == proFlag) { sDidLen = *((uint8_t *)head + sizeof(protocolHead_t)); data_len = 5 + 1 + sDidLen + len; } else { data_len = 5 + len; } GIZWITS_LOG("len = %d , sDidLen = %d ,data_len = %d\n", len,sDidLen,data_len); *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8); *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= head->cmd + 1; *pTxBuf ++= head->sn; *pTxBuf ++= 0x00; *pTxBuf ++= proFlag; offset = 8; if(0x1 == proFlag) { *pTxBuf ++= sDidLen; offset += 1; memcpy(&tx_buf[offset],(uint8_t *)head+sizeof(protocolHead_t)+1,sDidLen); offset += sDidLen; pTxBuf += sDidLen; } if(0 != len) { memcpy(&tx_buf[offset],gizdata,len); } tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("uart write error %d \n", ret); return -2; } return 0; } /** * @brief Report data interface * * @param [in] action : PO action * @param [in] data : Payload data * @param [in] len : Payload data length * * @return : 0,Ack success; * -1Input Param Illegal * -2,Serial send faild */ static int32_t gizReportData(uint8_t action, uint8_t *gizdata, uint32_t len) { int32_t ret = 0; protocolReport_t protocolReport; if(NULL == gizdata) { GIZWITS_LOG("gizReportData Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&protocolReport); protocolReport.head.cmd = CMD_REPORT_P0; protocolReport.head.sn = gizwitsProtocol.sn++; protocolReport.action = action; protocolReport.head.len = exchangeBytes(sizeof(protocolReport_t)-4); memcpy((gizwitsReport_t *)&protocolReport.reportData, (gizwitsReport_t *)gizdata,len); protocolReport.sum = gizProtocolSum((uint8_t *)&protocolReport, sizeof(protocolReport_t)); ret = uartWrite((uint8_t *)&protocolReport, sizeof(protocolReport_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); return -2; } gizProtocolWaitAck((uint8_t *)&protocolReport, sizeof(protocolReport_t)); return ret; }/** * @brief Datapoints reporting mechanism * * 1. Changes are reported immediately * 2. Data timing report , 600000 Millisecond * *@param [in] currentData : Current datapoints value * @return : NULL */ static void gizDevReportPolicy(dataPoint_t *currentData) { static uint32_t lastRepTime = 0; uint32_t timeNow = gizGetTimerCount(); if((1 == gizCheckReport(currentData, (dataPoint_t *)&gizwitsProtocol.gizLastDataPoint))) { GIZWITS_LOG("changed, report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); } if((0 == (timeNow % (600000))) && (lastRepTime != timeNow)) { GIZWITS_LOG("Info: 600S report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); lastRepTime = timeNow; } } /** * @brief Get a packet of data from the ring buffer * * @param [in] rb : Input data address * @param [out] data : Output data address * @param [out] len : Output data length * * @return : 0,Return correct ;-1,Return failure;-2,Data check failure */ static int8_t gizProtocolGetOnePacket(rb_t *rb, uint8_t *gizdata, uint16_t *len) { int32_t ret = 0; uint8_t sum = 0; int32_t i = 0; uint8_t tmpData; uint16_t tmpLen = 0; uint16_t tmpCount = 0; static uint8_t protocolFlag = 0; static uint16_t protocolCount = 0; static uint8_t lastData = 0; static uint8_t debugCount = 0; uint8_t *protocolBuff = gizdata; protocolHead_t *head = NULL; if((NULL == rb) || (NULL == gizdata) ||(NULL == len)) { GIZWITS_LOG("gizProtocolGetOnePacket Error , Illegal Param\n"); return -1; } tmpLen = rbCanRead(rb); if(0 == tmpLen) { return -1; } for(i=0; i<tmpLen; i++) { ret = rbRead(rb, &tmpData, 1); if(0 != ret) { if((0xFF == lastData) && (0xFF == tmpData)) { if(0 == protocolFlag) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; protocolFlag = 1; } else { if((protocolCount > 4) && (protocolCount != tmpCount)) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; } } } else if((0xFF == lastData) && (0x55 == tmpData)) { } else { if(1 == protocolFlag) { protocolBuff[protocolCount] = tmpData; protocolCount++; if(protocolCount > 4) { head = (protocolHead_t *)protocolBuff; tmpCount = exchangeBytes(head->len)+4; if (tmpCount >= MAX_PACKAGE_LEN || tmpCount <= 4) { protocolFlag = 0; protocolCount = 0; GIZWITS_LOG("ERR:the data length is too long or too small, will abandon \n"); } if(protocolCount == tmpCount) { break; } } } } lastData = tmpData; debugCount++; } } if((protocolCount > 4) && (protocolCount == tmpCount)) { sum = gizProtocolSum(protocolBuff, protocolCount); if(protocolBuff[protocolCount-1] == sum) { *len = tmpCount; protocolFlag = 0; protocolCount = 0; debugCount = 0; lastData = 0; return 0; } else { protocolFlag = 0; protocolCount = 0; return -2; } } return 1; } /** * @brief Protocol data resend * The protocol data resend when check timeout and meet the resend limiting * @param none * * @return none */ static void gizProtocolResendData(void) { int32_t ret = 0; if(0 == gizwitsProtocol.waitAck.flag) { return; } GIZWITS_LOG("Warning: timeout, resend data \n"); ret = uartWrite(gizwitsProtocol.waitAck.buf, gizwitsProtocol.waitAck.dataLen); if(ret != gizwitsProtocol.waitAck.dataLen) { GIZWITS_LOG("ERR: resend data error\n"); } gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); } /** * @brief Clear the ACK protocol message * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolWaitAckCheck(protocolHead_t *head) { protocolHead_t *waitAckHead = (protocolHead_t *)gizwitsProtocol.waitAck.buf; if(NULL == head) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } if(waitAckHead->cmd+1 == head->cmd) { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } return 0; } /** * @brief Send general protocol message data * * @param [in] head : Protocol header address * * @return : Return effective data length;-1,return failure */ static int32_t gizProtocolCommonAck(protocolHead_t *head) { int32_t ret = 0; protocolCommon_t ack; if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolCommonAck data is empty \n"); return -1; } memcpy((uint8_t *)&ack, (uint8_t *)head, sizeof(protocolHead_t)); ack.head.cmd = ack.head.cmd+1; ack.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); ack.sum = gizProtocolSum((uint8_t *)&ack, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&ack, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief ACK processing function * Time-out 200ms no ACK resend,resend two times at most * @param none * * @return none */ static void gizProtocolAckHandle(void) { if(1 == gizwitsProtocol.waitAck.flag) { if(SEND_MAX_NUM > gizwitsProtocol.waitAck.num) { // Time-out no ACK resend if(SEND_MAX_TIME < (gizGetTimerCount() - gizwitsProtocol.waitAck.sendTime)) { GIZWITS_LOG("Warning:gizProtocolResendData %d %d %d\n", gizGetTimerCount(), gizwitsProtocol.waitAck.sendTime, gizwitsProtocol.waitAck.num); gizProtocolResendData(); gizwitsProtocol.waitAck.num++; } } else { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } } } /** * @brief Protocol 4.1 WiFi module requests device information * * @param[in] head : Protocol header address * * @return Return effective data length;-1,return failure */ static int32_t gizProtocolGetDeviceInfo(protocolHead_t * head) { int32_t ret = 0; protocolDeviceInfo_t deviceInfo; if(NULL == head) { GIZWITS_LOG("gizProtocolGetDeviceInfo Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&deviceInfo); deviceInfo.head.cmd = ACK_GET_DEVICE_INFO; deviceInfo.head.sn = head->sn; memcpy((uint8_t *)deviceInfo.protocolVer, protocol_VERSION, 8); memcpy((uint8_t *)deviceInfo.p0Ver, P0_VERSION, 8); memcpy((uint8_t *)deviceInfo.softVer, SOFTWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.hardVer, HARDWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.productKey, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy((uint8_t *)deviceInfo.productSecret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memset((uint8_t *)deviceInfo.devAttr, 0, 8); deviceInfo.devAttr[7] |= DEV_IS_GATEWAY<<0; deviceInfo.devAttr[7] |= (0x01<<1); deviceInfo.ninableTime = exchangeBytes(NINABLETIME); #ifdef DATA_CONFIG_ENABLE deviceInfo.DataLen = exchangeBytes(GIZ_DATA_LEN); sprintf(deviceInfo.Data,"apName=%s&apPwd=%s&cfgMode=%s",AP_NAME,AP_PWD,CFG_MODE); #endif deviceInfo.head.len = exchangeBytes(sizeof(protocolDeviceInfo_t)-4); deviceInfo.sum = gizProtocolSum((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); ret = uartWrite((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.7 Handling of illegal message notification * @param[in] head : Protocol header address * @param[in] errno : Illegal message notification type * @return 0, success; other, failure */ static int32_t gizProtocolErrorCmd(protocolHead_t *head,errorPacketsType_t errno) { int32_t ret = 0; protocolErrorType_t errorType; if(NULL == head) { GIZWITS_LOG("gizProtocolErrorCmd Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&errorType); errorType.head.cmd = ACK_ERROR_PACKAGE; errorType.head.sn = head->sn; errorType.head.len = exchangeBytes(sizeof(protocolErrorType_t)-4); errorType.error = errno; errorType.sum = gizProtocolSum((uint8_t *)&errorType, sizeof(protocolErrorType_t)); ret = uartWrite((uint8_t *)&errorType, sizeof(protocolErrorType_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.13 Get and process network time * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolNTP(protocolHead_t *head) { protocolUTT_t *UTTInfo = (protocolUTT_t *)head; if(NULL == head) { GIZWITS_LOG("ERR: NTP is empty \n"); return -1; } memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.year,(uint8_t *)UTTInfo->time, 7); memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.ntp,(uint8_t *)UTTInfo->ntp_time, 4); gizwitsProtocol.TimeNTP.year = exchangeBytes(gizwitsProtocol.TimeNTP.year); gizwitsProtocol.TimeNTP.ntp =exchangeWord(gizwitsProtocol.TimeNTP.ntp); gizwitsProtocol.NTPEvent.event[gizwitsProtocol.NTPEvent.num] = WIFI_NTP; gizwitsProtocol.NTPEvent.num++; gizwitsProtocol.issuedFlag = GET_NTP_TYPE; return 0; } /** * @brief Protocol 4.4 Device MCU restarts function * @param none * @return none */ static void gizProtocolReboot(void) { uint32_t timeDelay = gizGetTimerCount(); /*Wait 600ms*/ while((gizGetTimerCount() - timeDelay) <= 600); mcuRestart(); } /** * @brief Protocol 4.5 :The WiFi module informs the device MCU of working status about the WiFi module * @param[in] status WiFi module working status * @return none */ static int8_t gizProtocolModuleStatus(protocolWifiStatus_t *status) { static wifiStatus_t lastStatus; if(NULL == status) { GIZWITS_LOG("gizProtocolModuleStatus Error , Illegal Param\n"); return -1; } status->ststus.value = exchangeBytes(status->ststus.value); //OnBoarding mode status if(lastStatus.types.onboarding != status->ststus.types.onboarding) { if(1 == status->ststus.types.onboarding) { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_AIRLINK; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: AirLink mode\n"); } } else { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_STATION; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: Station mode\n"); } } } //binding mode status if(lastStatus.types.binding != status->ststus.types.binding) { lastStatus.types.binding = status->ststus.types.binding; if(1 == status->ststus.types.binding) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in binding mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out binding mode\n"); } } //router status if(lastStatus.types.con_route != status->ststus.types.con_route) { lastStatus.types.con_route = status->ststus.types.con_route; if(1 == status->ststus.types.con_route) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected router\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected router\n"); } } //M2M server status if(lastStatus.types.con_m2m != status->ststus.types.con_m2m) { lastStatus.types.con_m2m = status->ststus.types.con_m2m; if(1 == status->ststus.types.con_m2m) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected m2m\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected m2m\n"); } } //APP status if(lastStatus.types.app != status->ststus.types.app) { lastStatus.types.app = status->ststus.types.app; if(1 == status->ststus.types.app) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: app connect\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: no app connect\n"); } } //test mode status if(lastStatus.types.test != status->ststus.types.test) { lastStatus.types.test = status->ststus.types.test; if(1 == status->ststus.types.test) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in test mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out test mode\n"); } } gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_RSSI; gizwitsProtocol.wifiStatusEvent.num++; gizwitsProtocol.wifiStatusData.rssi = status->ststus.types.rssi; GIZWITS_LOG("RSSI is %d \n", gizwitsProtocol.wifiStatusData.rssi); gizwitsProtocol.issuedFlag = WIFI_STATUS_TYPE; return 0; } /**@name Gizwits User API interface * @{ */ /** * @brief gizwits Protocol initialization interface * Protocol-related timer, serial port initialization * Datapoint initialization * @param none * @return none */ void gizwitsInit(void) { pRb.rbCapacity = RB_MAX_LEN; pRb.rbBuff = rbBuf; if(0 == rbCreate(&pRb)) { GIZWITS_LOG("rbCreate Success \n"); } else { GIZWITS_LOG("rbCreate Faild \n"); } memset((uint8_t *)&gizwitsProtocol, 0, sizeof(gizwitsProtocol_t)); } /** * @brief WiFi configure interface * Set the WiFi module into the corresponding configuration mode or reset the module * @param[in] mode :0x0, reset the module ;0x01, SoftAp mode ;0x02, AirLink mode ;0x03, Production test mode; 0x04:allow users to bind devices * @return Error command code */ int32_t gizwitsSetMode(uint8_t mode) { int32_t ret = 0; protocolCfgMode_t cfgMode; protocolCommon_t setDefault; switch(mode) { case WIFI_RESET_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_SET_DEFAULT; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_SOFTAP_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_AIRLINK_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_PRODUCTION_TEST: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_PRODUCTION_TEST; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_NINABLE_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_NINABLE_MODE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_REBOOT_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_REBOOT_MODULE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; default: GIZWITS_LOG("ERR: CfgMode error!\n"); break; } return ret; } /** * @brief Get the the network time * Protocol 4.13:"Device MCU send" of "the MCU requests access to the network time" * @param[in] none * @return none */ void gizwitsGetNTP(void) { int32_t ret = 0; protocolCommon_t getNTP; gizProtocolHeadInit((protocolHead_t *)&getNTP); getNTP.head.cmd = CMD_GET_NTP; getNTP.head.sn = gizwitsProtocol.sn++; getNTP.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); getNTP.sum = gizProtocolSum((uint8_t *)&getNTP, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&getNTP, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getNTP, sizeof(protocolCommon_t)); } /** * @brief Get Module Info * * @param[in] none * @return none */ void gizwitsGetModuleInfo(void) { int32_t ret = 0; protocolGetModuleInfo_t getModuleInfo; gizProtocolHeadInit((protocolHead_t *)&getModuleInfo); getModuleInfo.head.cmd = CMD_ASK_MODULE_INFO; getModuleInfo.head.sn = gizwitsProtocol.sn++; getModuleInfo.type = 0x0; getModuleInfo.head.len = exchangeBytes(sizeof(protocolGetModuleInfo_t)-4); getModuleInfo.sum = gizProtocolSum((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); ret = uartWrite((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); } /** * @brief Module Info Analyse * * @param [in] head : * * @return 0, Success, , other,Faild */ static int8_t gizProtocolModuleInfoHandle(protocolHead_t *head) { protocolModuleInfo_t *moduleInfo = (protocolModuleInfo_t *)head; if(NULL == head) { GIZWITS_LOG("NTP is empty \n"); return -1; } #if MODULE_TYPE memcpy((uint8_t *)&gizwitsProtocol.gprsInfoNews,(uint8_t *)&moduleInfo->gprsModuleInfo, sizeof(gprsInfo_t)); #else memcpy((uint8_t *)&gizwitsProtocol.wifiModuleNews,(uint8_t *)&moduleInfo->wifiModuleInfo, sizeof(moduleInfo_t)); #endif gizwitsProtocol.moduleInfoEvent.event[gizwitsProtocol.moduleInfoEvent.num] = MODULE_INFO; gizwitsProtocol.moduleInfoEvent.num++; gizwitsProtocol.issuedFlag = GET_MODULEINFO_TYPE; return 0; } /** * @brief Protocol handling function * * @param [in] currentData :The protocol data pointer * @return none */ int32_t gizwitsHandle(dataPoint_t *currentData) { int8_t ret = 0; #ifdef PROTOCOL_DEBUG uint16_t i = 0; #endif uint8_t ackData[RB_MAX_LEN]; uint16_t protocolLen = 0; uint32_t ackLen = 0; protocolHead_t *recvHead = NULL; char *didPtr = NULL; uint16_t offset = 0; if(NULL == currentData) { GIZWITS_LOG("GizwitsHandle Error , Illegal Param\n"); return -1; } /*resend strategy*/ gizProtocolAckHandle(); ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen); if(0 == ret) { GIZWITS_LOG("Get One Packet!\n"); #ifdef PROTOCOL_DEBUG GIZWITS_LOG("WiFi2MCU[%4d:%4d]: ", gizGetTimerCount(), protocolLen); for(i=0; i<protocolLen;i++) { GIZWITS_LOG("%02x ", gizwitsProtocol.protocolBuf[i]); } GIZWITS_LOG("\n"); #endif recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; switch (recvHead->cmd) { case CMD_GET_DEVICE_INTO: gizProtocolGetDeviceInfo(recvHead); break; case CMD_ISSUED_P0: GIZWITS_LOG("flag %x %x \n", recvHead->flags[0], recvHead->flags[1]); //offset = 1; if(0 == gizProtocolIssuedProcess(didPtr, gizwitsProtocol.protocolBuf+sizeof(protocolHead_t)+offset, protocolLen-(sizeof(protocolHead_t)+offset+1), ackData, &ackLen)) { gizProtocolIssuedDataAck(recvHead, ackData, ackLen,recvHead->flags[1]); GIZWITS_LOG("AckData : \n"); } break; case CMD_HEARTBEAT: gizProtocolCommonAck(recvHead); break; case CMD_WIFISTATUS: gizProtocolCommonAck(recvHead); gizProtocolModuleStatus((protocolWifiStatus_t *)recvHead); break; case ACK_REPORT_P0: case ACK_WIFI_CONFIG: case ACK_SET_DEFAULT: case ACK_NINABLE_MODE: case ACK_REBOOT_MODULE: gizProtocolWaitAckCheck(recvHead); break; case CMD_MCU_REBOOT: gizProtocolCommonAck(recvHead); GIZWITS_LOG("report:MCU reboot!\n"); gizProtocolReboot(); break; case CMD_ERROR_PACKAGE: break; case ACK_PRODUCTION_TEST: gizProtocolWaitAckCheck(recvHead); GIZWITS_LOG("Ack PRODUCTION_MODE success \n"); break; case ACK_GET_NTP: gizProtocolWaitAckCheck(recvHead); gizProtocolNTP(recvHead); GIZWITS_LOG("Ack GET_UTT success \n"); break; case ACK_ASK_MODULE_INFO: gizProtocolWaitAckCheck(recvHead); gizProtocolModuleInfoHandle(recvHead); GIZWITS_LOG("Ack GET_Module success \n"); break; default: gizProtocolErrorCmd(recvHead,ERROR_CMD); GIZWITS_LOG("ERR: cmd code error!\n"); break; } } else if(-2 == ret) { //Check failed, report exception recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; gizProtocolErrorCmd(recvHead,ERROR_ACK_SUM); GIZWITS_LOG("ERR: check sum error!\n"); return -2; } switch(gizwitsProtocol.issuedFlag) { case ACTION_CONTROL_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t)); memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent,0x0,sizeof(gizwitsProtocol.issuedProcessEvent)); break; case WIFI_STATUS_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.wifiStatusEvent, (uint8_t *)&gizwitsProtocol.wifiStatusData, sizeof(moduleStatusInfo_t)); memset((uint8_t *)&gizwitsProtocol.wifiStatusEvent,0x0,sizeof(gizwitsProtocol.wifiStatusEvent)); break; case ACTION_W2D_TRANSPARENT_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen); break; case GET_NTP_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.NTPEvent, (uint8_t *)&gizwitsProtocol.TimeNTP, sizeof(protocolTime_t)); memset((uint8_t *)&gizwitsProtocol.NTPEvent,0x0,sizeof(gizwitsProtocol.NTPEvent)); break; case GET_MODULEINFO_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.moduleInfoEvent, (uint8_t *)&gizwitsProtocol.wifiModuleNews, sizeof(moduleInfo_t)); memset((uint8_t *)&gizwitsProtocol.moduleInfoEvent,0x0,sizeof(moduleInfo_t)); break; default: break; } gizDevReportPolicy(currentData); return 0; } /** * @brief gizwits report transparent data interface * The user can call the interface to complete the reporting of private protocol data * @param [in] data :Private protocol data * @param [in] len :Private protocol data length * @return 0,success ;other,failure */ int32_t gizwitsPassthroughData(uint8_t * gizdata, uint32_t len) { int32_t ret = 0; uint8_t tx_buf[MAX_PACKAGE_LEN]; uint8_t *pTxBuf = tx_buf; uint16_t data_len = 6+len; if(NULL == gizdata) { GIZWITS_LOG("[ERR] gizwitsPassthroughData Error \n"); return (-1); } *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8);//len *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= CMD_REPORT_P0;//0x1b cmd *pTxBuf ++= gizwitsProtocol.sn++;//sn *pTxBuf ++= 0x00;//flag *pTxBuf ++= 0x00;//flag *pTxBuf ++= ACTION_D2W_TRANSPARENT_DATA;//P0_Cmd memcpy(&tx_buf[9],gizdata,len); tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck(tx_buf, data_len+4); return 0; } /**@} */
07-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值