Skip to main content

模组二次开发教程

1. AiLink文件介绍

1) AiLink核心功能文件

.
├── include
│   ├── ailink_appair.h // AP配网功能模块的API声明文件,属于内部文件
│   ├── ailink_blepair.h // ble配网功能模块的API声明文件,属于内部文件
│   ├── ailink_lan.h // 局域网功能模块的API声明文件,属于内部文件
│   ├── ailink_list.h // 链表的API声明,用于软件定时器和数据发送队列,属于内部文件
│   ├── ailink_log.h // 日志打印的API声明,属于内部文件
│   ├── ailink_ota.h // ota功能的API声明,属于外部文件
│   ├── ailink_profile.h // 可由用户调用的API声明,属于外部文件
│   ├── ailink_protocol.h // IOT协议功能的API声明,属于内部文件
│   ├── ailink_server.h // 广域网功能的API声明,属于内部文件
│   ├── ailink_softtimer.h // 软件定时器功能的API声明,属于内部文件
│   ├── ailink_transport.h // 网络数据传输功能的API声明,属于内部文件
│   └── ailink_utils.h // 工具类功能的API声明,属于外部文件
├── src
│   ├── ailink_appair.c // AP配网功能模块的API定义文件,属于内部文件
│   ├── ailink_blepair.c // ble配网功能模块的API定义文件,属于内部文件
│   ├── ailink_lan.c // 局域网功能模块的API定义文件,属于内部文件
│   ├── ailink_list.c // 链表的API定义文件,属于内部文件
│   ├── ailink_ota.c // ota功能的API定义文件,属于内部文件
│   ├── ailink_process.c // 该文件主要处理配网、局域网、广域网和OTA所有功能的启动与停止,属于内部文件
│   ├── ailink_protocol.c // 该文件主要是解析和封装IOT协议,属于内部文件
│   ├── ailink_server.c // 广域网功能模块的API定义文件,属于内部文件
│   ├── ailink_softtimer.c // 软件定时器的API定义文件,属于内部文件
│   ├── ailink_transport.c // 网络数据传输功能的API定义文件,属于内部文件
│   └── ailink_utils.c // 工具类功能的API定义文件,属于内部文件

2) AiLink平台适配文件

├── interface
│   ├── ailink_bleHal.h //适配ble功能的API声明文件
│   ├── ailink_flashHal.h //适配flash存储功能的API声明文件
│   ├── ailink_mdnsHal.h //适配mdns广播功能的API声明文件
│   ├── ailink_osHal.h //适配OS功能的API声明文件
│   ├── ailink_otaHal.h //适配OTA更新固件包功能的API声明文件
│   ├── ailink_socketHal.h //适配网络socket接口功能的API声明文件
│   ├── ailink_timerHal.h //适配硬件定时器功能的API声明文件,该定时器需精确到微秒
│   ├── ailink_uartHal.h //适配串口输出功能的API声明文件
│   ├── ailink_wdtHal.h //适配看门狗功能的API声明文件
│   └── ailink_wifiHal.h //适配WiFi功能的API声明文件

2. 结构体描述

a. 配网数据结构体

/**
* @brief 待配置的配网信息结构
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-11
*/
typedef struct
{
char pair_ap_ssid[33]; /**< AP热点的ssid */
char pair_ap_passwd[65]; /**< AP热点的passwd */
char pair_ble_adv_name[32]; /**< BLE广播名 */
}profile_pair_info;
  • AP热点名和BLE广播名的命名格式为:

    格式:企业缩写_产品标识-产品ID_p1_MAC地址(取后6位)
    例如:axy_XXJ-Y2U1bxMi_p1_47BF7C
    • 注意:
      • 只有将AP热点名和ble广播名按照格式命令后。当设备启动配网时,方可在APP搜索到设备。否则,APP将无法搜索到设备。
      • 产品标识和产品ID将由爱星物联平台创建产品时生成。
  • 在bl602的示例demo上,当设备启动AP热点后,其网关IP地址为192.168.4.1

  • 在bl602的示例demo上,当设备启动AP配网后,AiLilink将会创建UDP服务,其UDP服务的端口为9988

b. 局域网配置结构体

/**
* @brief 局域网待配置的信息结构
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-11
*/
typedef struct
{
char mdns_service_type[24]; /**< 局域网功能上的MDNS服务类型 */
char mdns_host_name[65]; /**< 局域网功能上的MDNS主机名 */
uint16_t lan_port; /**< 局域网功能上的UDP服务端口号 */
}profile_lan_info;
  • mdns服务类型规定设置为 _iotaithings,在mdns_service_type这个数组上需存储_iotaithings这个字符串

  • mdns主机名的命名格式为:

    格式:企业缩写_设备ID_设备ip地址_局域网模块创建UDP服务的端口
    例如:axy_eEkR0C6w5cEUaJ_192.168.1.104_1314
    • 注意

      由于设备的ip地址需连接路由后分配给出,因此对于mdns_host_name该数组需先暂时缓存企业缩写和设备ID拼接后的字符串,之后将由AiLink处理逻辑组织拼接完整格式的主机名。

  • 局域网UDP服务的端口号默认为1314

c. AiLink数据配置结构体

/**
* @brief ailink IOT协议栈配置信息结构
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-15
*/
typedef struct
{
char user_name[65]; /**< MQTT用户名 */
char user_passwd[65]; /**< MQTT用户密码 */
char deviceid[65]; /**< 设备ID */
char productid[65]; /**< 产品ID */
char fw_version[10]; /**< 模组固件版本号 */
char mcu_version[10]; /**< MCU固件版本号 */
char device_type[10]; /**< 设备类型,如博流芯片为bl602 */
uint8_t pair_type; /**< 配置配网类型,如:AP和BLE共存配网为AILINK_PAIR_AP_BLE_TYPE */
profile_pair_info pair_info; /**< 配网配置信息 */
profile_lan_info lan_info; /**< 局域网配置信息 */
}profile_info_t;
  • user_name、user_passwd和deviceid是用于存储三元组数据(三元组数据是由爱星物联平台生成)。

    • 注意:

      • 在bl602平台上,三元组数据可写入txt文件或是bin文件,然后通过Bouffalo Lab Dev Cube工具烧录于flash的Media区域。

        三元组数据写入文件的格式如下:

        {
        "username":"oBnp4J",
        "password":"1hcgCRXI1PXNGg",
        "deviceid":"Yf6RVwjgmSrZH1"
        }
      • 在bl602平台上,三元组数据可通过串口AT指令的方式写入flash(该方式暂未支持,后续将补充该功能)

  • 产品ID将由爱星物联平台创建产品时生成

  • 模组固件版本号和MCU固件版本号都是AiLink在连接爱星物联时上报设备信息所需的。

  • 设备类型亦是AiLink在连接爱星物联时上报设备信息所需的。设备类型是指明该设备所用芯片的型号。

    示例说明:
    博流bl602的设备类型是bl602
    乐鑫esp32的设备类型是esp32
  • 配网类型是设置AiLink选择什么类型的配网方式,AiLink配网方式有以下三种方式:

    • AILINK_PAIR_AP_BLE_TYPE AP与BLE共存配网
    • AILINK_PAIR_AP_TYPE AP配网
    • AILINK_PAIR_BLE_TYPE BLE配网

d. AiLink事件回调配置结构体

/**
* @brief ailink IOT协议栈回调函数
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-15
*/
typedef struct
{
/**
* @brief 接收设备控制的json字符串数据回调函数
* @param[in] data json字符串事件
* @param[in] mid 消息ID数据
* @param[in] ts 时间戳
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-15
*/
void (*ailinkRecvControlInfoCb)(char *data, char *mid, uint32_t ts);
/**
* @brief 接收设备OTA的json字符串数据回调函数
* @param[in] data json字符串事件
* @param[in] mid 消息ID数据
* @param[in] ts 时间戳
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-15
*/
void (*ailinkRecvOTAInfoCb)(char *data, char *mid, uint32_t ts);
/**
* @brief 接收ailink IOT协议栈中的事件回调函数
* @param[in] event 回调事件
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-15
*/
void (*ailinkEventCb)(uint8_t event);
}profile_event_t;
  • ailinkRecvControlInfoCb该回调事件函数是由云端下发控制物模型数据。下发的协议数据格式如下:

    • 物模型数据格式

      {
      "dpid":数据内容
      }
      • 基本说明:
    字段名值类型说明
    dpidstring对应于物模型的dpid
    数据内容bool/int/string对应于物模型的属性数据
    • 示例:下发开关为开状态(物模型数据为1,属性值为true),模式为自动模式(物模型数据为2,属性值为2)

      "control":
      {
      "1": true,
      "2": 2
      }
  • ailinkRecvOTAInfoCb该回调事件函数是由云端下发OTA信息,让模组启动OTA功能,对模组或MCU进行OTA功能。协议格式如下:

    • 协议格式
    "param":
    {
    "chanel":1,
    "pointVer":"1.1.0",
    "baseVer":"1.1.0",
    //"mcuBaseVer":"1.0.0",
    "otaType":"module_ota_all",
    "appUrl":"https://xxx.com/xxx_app.bin",
    //"mcuUrl":"https://xxx.com/xxx_mcu.bin",
    "md5": "12312312312312"
    }
    • 基本说明
    字段名说明
    chanel升级渠道(1-云端、2-APP)
    pointVer指定目标版本
    baseVer固件最低兼容版本
    mcuBaseVermcu最低兼容版本
    otaTypeOTA下载OTA包的类型,如:module_ota_all, module_ota_diff、module_mcu_all、module_mcu_diff
    appUrloss永久有效的APP外链地址,
    mcuUrloss永久有效的MCU外链地址,
    md5当前待升级的固件包文件的MD5值,
    • 启动OTA功能

      当在ailinkRecvOTAInfoCb这个回调函数接收到升级信息后,可通过OTA功能模组的AilinkOtaInit进行初始化和启动OTA功能。OTA功能模块后续将会从链接获取OTA数据包,并将OTA数据包透传给OTA下载回调函数,下面将会详细地介绍OTA功能。

  • ailinkEventCb该回调事件函数是通知用户AiLink的运行状态,具体事件状态如下:

    /* ailink IOT协议栈回调事件 */
    #define AILINK_AP_BLE_EVENT 1 /**< AP与BLE共存配网启动事件 */
    #define AILINK_AP_EVENT 2 /**< AP配网启动事件 */
    #define AILINK_BLE_EVENT 3 /**< BLE配网启动事件 */
    #define AILINK_WIFI_DISCONNECT_EVENT 4 /**< wifi断开事件 */
    #define AILINK_WIFI_CONNECT_EVENT 5 /**< WiFi已连接事件 */
    #define AILINK_CLOUD_DISCONNECT_EVENT 6 /**< 网络断开事件 */
    #define AILINK_CLOUD_CONNECT_EVENT 7 /**< 网络已连接事件 */
    #define AILINK_CLOUD_QUERY_EVENT 8 /**< 网络请求上报所有物模型数据 */
    #define AILINK_DEVICE_RESTORE_EVENT 9 /**< 网络下发恢复出厂指令事件 */
    #define AILINK_DEVICE_REBOOT_EVENT 10 /**< 网络下发设备重启指令事件 */

    开发者可根据ailinkEventCb回调通知的事件,了解到设备处于什么运行状态;进而根据自己的业务需求调整设备的状态。

a. 协议信息结构体

/**
* @brief 协议信息结构
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-22
*/
typedef struct
{
uint8_t channel; /**< 升级渠道,1:云端,0:APP */
char pointVer[10]; /**< 指定目标版本号,即指定某一个版本号可升级 */
char baseVer[10]; /**< 固件最低兼容版本号,例如:最低兼容版本号是2.0.1,而2.0.5该版本可升级,而1.5.0该版本不可升级 */
char mcuBaseVer[10]; /**< 指定MCU最低兼容版本号,例如:最低兼容版本号是2.0.1,而2.0.5该版本可升级,而1.5.0该版本不可升级 */
char otaType[20]; /**< OTA包下载类型,如:module_ota_all为整包下载*/
char download_url[400]; /**< OTA包下载链接 */
}ailinkOtaProInfo;

当设备通过ailinkRecvOTAInfoCb这个回调函数接收到OTA升级的协议数据后,可将协议数据存储于ailinkOtaProInfo这个结构体上,然后再将ailinkOtaProInfo这个结构体数据传入AilinkOtaInit这个函数进行初始化和启动OTA功能。

b. OTA包头结构体

/**
* @brief OTA包头信息结构
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-22
*/
typedef struct
{
char device_fw_version[17]; /**< OTA包固件版本号 */
char device_productid[64]; /**< 设备的产品ID */
char ota_type; /**< OTA类型,1:模组OTA固件包,2:MCU OTA固件包 */
char ota_flag[8]; /**< OTA包头标志,即0xaa 0x55 0xff 0x44 0x88 0xaa */
uint16_t head_offset; /**< OTA包头偏移长度 */
uint32_t ota_length; /**< OTA包数据长度 */
}ailink_ota_head_info;

当设备通过ailinkRecvOTAInfoCb这个回调函数接收到OTA升级的协议数据后,在对AilinkOtaInit该函数进行初始化前,还需对ailink_ota_head_info该结构体中device_fw_versiondevice_productid这两个变量进行赋值;否则当OTA功能启动时,在校验固件版本号和产品ID时不通过而导致OTA失败。

注意

1)device_fw_version该变量需存储当前设备固件的软件版本号。当OTA功能模块启动后,在获取到OTA数据包后,将会对OTA包内的软件版本号与device_fw_version这个变量存储的版本号进行比较。若是OTA包内的软件版本号小于device_fw_version该变量上的版本号,OTA失败;而当OTA包内版本大于或等于,OTA则继续执行。

2)device_productid该变量是用于校验OTA包内的产品ID。若是不同产品的OTA包,OTA将会返回失败;而OTA包内与该变量的产品ID一样时,OTA将继续。

c. OTA配置结构体

/**
* @brief OTA 配置信息结构体
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-22
*/
typedef struct
{
uint32_t ota_timeout; /**< OTA超时时间 */
ailink_ota_head_info head_info; /**< OTA包头信息结构 */
ailinkOtaProInfo ProInfo; /**< OTA协议信息结构 */
ailinkOtaStatusCallback OtaStatusCallback; /**< OTA升级状态回调函数 */
ailinkOtaDownloadCallback OtaDownloadCallback; /**< OTA包数据透传回调函数 */
ailinkOtaDownloadCallback McuOtaDownloadCallback; /**< MCU OTA包数据透传回调函数 */
}ailink_ota_config;

当设备通过ailinkRecvOTAInfoCb这个回调函数接收到OTA升级的协议数据后,将对应结构数据存储于ailink_ota_config这个结构体上,并将响应的回调函数亦存储于该结构体上;接着便可将ailink_ota_config这个结构体数据传入AilinkOtaInit这个函数进行初始化OTA功能。

注意

1)当OTA功能初始化启动后,OTA功能进行过程中会将运行的状态通过OtaStatusCallback这个回调通知应用层OTA的运行状态,具体的状态事件如下:

#define AILINK_OTA_STATUS_SUCCESS   (0)  /**< OTA成功 */
#define AILINK_OTA_STATUS_FAIL (1) /**< OTA失败 */
#define AILINK_OTA_STATUS_TIMEOUT (2) /**< OTA超时 */
#define AILINK_OTA_STATUS_STRART (3) /**< OTA开始 */

​ 应用层可根据不同的状态进行反初始化OTA功能,释放OTA功能占用的资源;或是重新启动OTA功能等。

2)当OTA功能模块获取到OTA数据包后,将会通过OtaDownloadCallbackMcuOtaDownloadCallback这两个回调函数透传OTA数据包。

OtaDownloadCallback:该回调函数主要是透传模组的OTA数据包,应用层接收到OTA数据包后,再根据不同平台将OTA数据包放于运行程序的flash便可。

​ 对于该回调函数透传的OTA数据包,已经是经过处理了Http协议头以及OTA包头相关杂质数据了。该OTA数据根据不同平台放于

​ flash运行。

McuOtaDownloadCallback:该回调函数主要是透传MCU的OTA数据包,应用层接收到该数据包后将直接通过串口的方式透传给MCU。对于该回调函数透传

​ 的OTA数据包,并未经过处理,即该数据包是原始的http协议数据。

3. API描述

/**
* @brief 初始化Ailink IOT协议栈
* @param[in] info 待配置的信息
* @param[in] eventCb 事件回调函数
* @return int32_t
* 0:初始化成功
* -1:初始化失败
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-11
*/
int32_t AilinkInit(profile_info_t *info, profile_event_t *eventCb);
/**
* @brief 进入配网函数
* @note 当调用该函数时,设备便进入配网模式(配网模式由初始化AilinkInit设置决定)
* 1. 当设备已配过网时,通过该函数先行关闭STA模式以及反初始化广域网和局域网模块,然后进入配网模式
* 2. 当设备未配网过时,通过该函数将直接进入配网模式
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-12
*/
void AilinkEnterPair(void);
/**
* @brief 退出配网模式
* @note 当调用该函数时有以下两种情况
* 1. 设备已配过网,当设备重新进入配网模式时,可通过该函数退出配网,然后重新连接之前配网过路由。
* 若是重新连接路由超时时(3分钟超时),设备将会重新进入配网模式。
* 2. 设备未配过网,当设备已进入配网模式时,通过该函数退出配网后,设备仍会进入配网模式。
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-12
*/
void AilinkExitPair(void);
/**
* @brief 获取profile信息
* @return profile_info_t* 返回获取profile存储的信息
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-05-28
*/
profile_info_t *AilinkGetProfileInfo(void);
/**
* @brief 获取WiFi信息
* @return profile_wifi_info* 返回已连接的路由信息
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-07-05
*/
profile_wifi_info *AilinkGetWifiInfo(void);
/**
* @brief 向云端回应控制ack
* @param[in] code 错误码
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-05-31
*/
void AilinkPublicControlAck(uint8_t code);
/**
* @brief 设备主动上报设备所有的属性
* @param[in] topic 主题
* @param[in] qos 消息质量
* @param[in] json_device 待上报的json数据
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-05-31
*/
void AilinkPublicReportAttributes(cJSON *json_device);
/**
* @brief OTA升级进度上报
* @param[in] code 错误码状态
* 0:表示OTA成功
* 1:表示下载失败
* 2:表示安装失败
* 3:表示协议数据错误
* 4:表示OTA数据包错误
* @param[in] otaStatus ota上报状态
* Downloading:表示下载中
* Installing:表示固件正在安装中
* @param[in] progress ota上报进度
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-06-18
*/
void AilinkPublicReportProgress(uint8_t code, char *otaStatus, uint32_t progress);

注意:该文件是AiLink主要的头文件,该文件已包含了应用层可调用的相关API。因此,需要基于AiLink进行二次开发,让设备接入爱星物联,只需在包含该头文件

​ 并调用相关API便可自动完成初始化,启动配网功能、局域网功能和广域网功能。

/**
* @brief ota功能初始化,配置OTA各个参数
* @param[in] config 待配置OTA的参数
* @return int32_t
* 0:ota初始化成功
* -1:ota初始化失败
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-06-16
*/
int32_t AilinkOtaInit(ailink_ota_config *config);
/**
* @brief ota功能反初始化,但ota升级结束后,可调用该函数,释放ota过程中占用的资源
* @return int32_t
* 0:反初始化成功
* -1:反初始化失败
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-06-16
*/
int32_t AilinkOtaDeInit(void);

注意:该头文件主要是包含OTA功能的相关API。当应用层接收到OTA相关信息时,便可调用该头文件的API进行初始化和启动OTA功能了。

/**
* @brief 获取星期几
* @note 使用蔡勒公式计算星期几
* @param[in] iYear 指定月份
* @param[in] ucMonth 指定月份
* @param[in] ucDay 指定天数
* @return uint8_t 返回星期几
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-19
*/
uint8_t cTimeToWeek(int32_t iYear, uint8_t ucMonth, uint8_t ucDay);
/**
* @brief 获取日期和时间
* @note 返回TimeType类型的日期和时间
* @param[in] lStamp UNIX时间戳
* @param[in] ptypeTime 时间结构体指针
* @param[in] cUTC 时区(东时区为正、西时区为负)
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-19
*/
void vStampToTime(uint32_t lStamp, TimeType *ptypeTime, int8_t cUTC);
/**
* @brief 获取以秒为单位的时间戳
* @param[in] typeTime 日期和时间
* @return uint32_t 返回时间戳
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-19
*/
uint32_t lTimeToStamp(TimeType typeTime);
/**
* @brief 时间戳转换字符串时间
* @param[in] lStamp 时间戳
* @param[in] cUTC 时间戳时区
* @return char*
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-10
*/
char *pcStampToTimeStrings(uint32_t lStamp, int8_t cUTC);
/**
* @brief 时间戳转换日期
* @param[in] lStamp 时间戳
* @param[in] cUTC 时间戳时区
* @return char*
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-10
*/
char *pcStampToDateStrings(uint32_t lStamp , int8_t cUTC);
/**
* @brief 获取月份天数
* @param[in] month 指导月份
* @return uint8_t 返回指定月份的天数
* @author Ai-Thinker (zhuolm@tech-now.com)
* @date 2022-08-19
*/
uint8_t GetMonthDays(uint8_t month);

注意:该头文件主要是包含了AiLink所需组件工具的API。例如在应用层或是适配层的实时时钟功能需要时间戳转换功能和星期获取功能。

4. 示例

  • 回调函数定义

    /**
    * @brief 接收设备控制的json字符串数据回调函数
    *
    * @param[in] data json字符串事件
    * @param[in] mid 消息ID数据
    * @param[in] ts 时间戳
    *
    * @author Ai-Thinker (zhuolm@tech-now.com)
    * @date 2022-08-16
    */
    void AilinkRecvControlInfo(char *data, char *mid, uint32_t ts)
    {
    }
    /**
    * @brief 接收设备OTA的json字符串数据回调函数
    *
    * @param[in] data json字符串事件
    * @param[in] mid 消息ID数据
    * @param[in] ts 时间戳
    *
    * @author Ai-Thinker (zhuolm@tech-now.com)
    * @date 2022-08-16
    */
    void AilinkRecvOtaInfo(char *data, char *mid, uint32_t ts)
    {
    }
    /**
    * @brief 接收ailink IOT协议栈中的事件回调函数
    *
    * @param[in] event 回调事件
    *
    * @author Ai-Thinker (zhuolm@tech-now.com)
    * @date 2022-08-16
    */
    void AilinkEvent(uint8_t event)
    {
    switch (event)
    {
    case AILINK_AP_BLE_EVENT:{}
    break;

    case AILINK_AP_EVENT:{}
    break;

    case AILINK_BLE_EVENT:{}
    break;

    case AILINK_WIFI_DISCONNECT_EVENT:{}
    break;

    case AILINK_WIFI_CONNECT_EVENT:{}
    break;

    case AILINK_CLOUD_DISCONNECT_EVENT:{}
    break;

    case AILINK_CLOUD_CONNECT_EVENT:{}
    break;

    case AILINK_CLOUD_QUERY_EVENT:{}
    break;

    case AILINK_DEVICE_RESTORE_EVENT:{}
    break;

    case AILINK_DEVICE_REBOOT_EVENT:{}
    break;

    default:
    break;
    }
    }
  • 数据定义

    #define DEVICE_FLAG                 "XXJ"                       // 产品标识
    #define DEVICE_PRODUCT_ID ("Y2U1bxMi") // 产品ID
    #define DEVICE_USER_NAME "8Jyq2u" // 三元组数据用户名
    #define DEVICE_USER_PASSWD "hJ15BAUGoqWMpx" // 三元组数据密码
    #define DEVICE_DEVICEID "tjvHR5WLMKBqtO" // 三元组数据设备ID
    #define DEVICE_MDNS_SERVER_TYPE ("_iotaithings") // mdns服务类型
    #define DEVICE_FW_VERSION ("1.0.0") // 模组软件版本号
    #define DEVICE_MCU_VERSION ("1.0.0") // MCU软件版本号
    #define DEVICE_TYPE ("bl602") // 设备类型
  • 变量定义

    char macstr[13] = "B4E8420F757C";               // 默认提供芯片的mac地址
    static char mdns_host_name[65] = {0}; // mdns主机名的组成格式可参考第2节的ailink_profile.h结构体描述
    profile_info_t profile_info = {0}; // AiLink配置数据结构体
    profile_event_t profile_event = {0}; // AiLink事件结构体
    char DataBuff[100] = {0}; // 缓存空间
  • AiLink初始化

        /* ailink IOT协议栈配置 */
    memcpy(profile_info.user_name, DEVICE_USER_NAME, strlen(DEVICE_USER_NAME)); // 拷贝三元组数据用户名
    memcpy(profile_info.user_passwd, DEVICE_USER_PASSWD, strlen(DEVICE_USER_PASSWD)); // 拷贝三元组数据密码
    memcpy(profile_info.deviceid, DEVICE_DEVICEID, strlen(DEVICE_DEVICEID)); // 拷贝三元组数据设备id
    memcpy(profile_info.productid, DEVICE_PRODUCT_ID, strlen(DEVICE_PRODUCT_ID)); // 拷贝设备产品ID
    memcpy(profile_info.fw_version, DEVICE_FW_VERSION, strlen(DEVICE_FW_VERSION)); // 拷贝模组固件版本号
    memcpy(profile_info.mcu_version, DEVICE_MCU_VERSION, strlen(DEVICE_MCU_VERSION)); // 拷贝MCU固件版本号
    memcpy(profile_info.device_type, DEVICE_TYPE, strlen(DEVICE_TYPE)); // 拷贝设备类型
    memcpy(profile_info.lan_info.mdns_service_type, DEVICE_MDNS_SERVER_TYPE, strlen(DEVICE_MDNS_SERVER_TYPE));//拷贝服务类型
    snprintf(mdns_host_name, sizeof(mdns_host_name), "axy_%s", device_info.deviceId); // 拼接主机名
    memcpy(profile_info.lan_info.mdns_host_name, mdns_host_name, strlen(mdns_host_name)); // 拷贝主机名

    // 拷贝回调函数
    profile_event.ailinkRecvControlInfoCb = AilinkRecvControlInfo;
    profile_event.ailinkRecvOTAInfoCb = AilinkRecvOtaInfo;
    profile_event.ailinkEventCb = AilinkEvent;

    /* 将AP热点和蓝牙广播名按照协议格式拼接成需要的名称 */
    snprintf(DataBuff, sizeof(DataBuff), "axy_%s-%s_p1_", DEVICE_FLAG, DEVICE_PRODUCT_ID);
    memcpy(profile_info.pair_info.pair_ap_ssid, DataBuff, strlen(DataBuff));
    memcpy(profile_info.pair_info.pair_ble_adv_name, DataBuff, strlen(DataBuff));
    strncat(profile_info.pair_info.pair_ap_ssid, &macstr[6], 6);
    strncat(profile_info.pair_info.pair_ble_adv_name, &macstr[6], 6);
    IOT_InfoLog("profile_info.pair_info.pair_ap_ssid = %s \r\n", profile_info.pair_info.pair_ap_ssid);
    IOT_InfoLog("profile_info.pair_info.pair_ble_adv_name = %s \r\n", profile_info.pair_info.pair_ble_adv_name);

    AilinkInit(&profile_info, &profile_event); /* 初始化ailink IOT协议栈 */

5. 编译

  • 执行build.sh脚本编译

    • 该文件在AiLink根目录上

    • 执行该文件时需传入两个参数(平台和示例demo文件夹名)。

      ./build.sh bl602 OpenSource
    • 注意:在执行build.sh脚本时,该脚本执行的步骤如下:

      • 把AiLink上的c文件编译生成libAilink静态库,存放于lib文件上。
      • 当执行build.sh脚本编译源码demo时,将会将AiLink上的c文件拷贝到示例demo进行更新最新c文件。
      • 当执行build.sh脚本编译静态库demo时,将会将AiLink的libAilink静态库拷贝到示例demo上。
      • 最后编译指定demo工程的程序,并打包生成固件包
  • 在示例demo上,执行genromap脚本编译

    • 进入bl602示例demo工程后,可执行以下指令后,便可生成二进制固件,固件存放于build_out文件夹中(固件名Project.bin)。

      ./genromap
  • 在示例demo上,执行buildscript.sh脚本编译

    • 该编译脚本是在shellscript文件夹中

    • 该脚本主要是bl602程序工程的编译与固件打包功能。

    • 执行以下指令编译工程程序和打包固件

      ./buildscript.sh