声明:文章只做技术交流,没有其他任何用途,侵权泄密立删!!
此文章适配后,可实现APP扫描添加网关,删除网关,OTA升级网关(OTA需华为技术配合调试).
如果是wifi类单品,适配完就完了...
商务审核ok以后,会发送sdk包,内有参考文档.
接口1:获取本地ip,让sdk联网
位置:hilink-sdk-src/adapter/network_adapter/hilink_network_adapter.c
/*
* 获取本地ip
* localIp表示存放Ip的缓冲
* len表示存放Ip的缓冲长度
* 返回0表示成功,返回-1表示失败
* 注意: localIp为点分十进制格式
*/
int HILINK_GetLocalIp(char *localIp, unsigned char len)
/*
eth_name:网卡名称,例如eth0
local_ip_addr:存放获取到的IP
*/
int USER_GetLocalIp(const char * eth_name, char *local_ip_addr)
{
int ret = -1;
register int fd;
struct ifreq ifr;
user_link_status = 0;
if (local_ip_addr == NULL || eth_name == NULL)
{
return ret;
}
if ((fd=socket(AF_INET, SOCK_DGRAM, 0)) > 0)
{
strcpy(ifr.ifr_name, eth_name);
if (!(ioctl(fd, SIOCGIFADDR, &ifr)))
{
ret = 0;
user_link_status = 1;
strcpy(local_ip_addr, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
hilink_printf("local_ip_addr:%s\n",local_ip_addr);
}
}
if (fd > 0)
{
close(fd);
}
return ret;
}
接口2:获取网络mac地址,此处只需要填充唯一值,不需要获取网络mac,如果要获取网络mac,就要先写网络mac,因为我的硬件没有网mac.所以可以先写到网络mac,然后再获取出来,我是直接读取变量,没有获取网络的mac(因为是我写的).
位置:hilink-sdk-src/adapter/network_adapter/hilink_network_adapter.c
/*
* 获取网络mac地址
* mac表示存放MAC地址的缓冲
* len表示缓冲长度
* 返回0表示成功,返回-1表示失败
* 注意: mac格式为a1b2c3d4e5f6
*/
int HILINK_GetMacAddr(unsigned char *mac, unsigned char len)
{
//填充mac
}
接口3:重启Hilink SDK,此接口非常重要:需要处理删除数据库,删除子设备,清空SDK的缓存数据等操作.
位置:hilink-sdk-src/adapter/network_adapter/hilink_network_adapter.c
注:有以下情况会调用此接口
/*
* 重启HiLink SDK
* 若系统不可重启,建议重启HiLink进程
* 返回0表示成功,返回-1表示失败
*/
int HILINK_Restart(void)
{
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
return 0;
}
接口4:其他wifi相关的接口我不用适配,因为我插网线的,后期适配了在更新.
位置:hilink-sdk-src/adapter/network_adapter/hilink_network_adapter.c
接口1:其他wifi softap相关的接口我不用适配,因为我插网线的,后期适配了在更新.
位置:hilink-sdk-src/adapter/network_adapter/hilink_softap_adapter.c
接口1:网关设备的网络状态指示,可以适配指示哪个灯亮.
位置:hilink-sdk-src/adapter/sdk_adapter/hilink_sdk_adapter.c
注:SDK连上服务器之后,如果网关下面有子设备,需要在这里面调用子设备上线的函数,如下
以上两个参数都可以,因为存在一种情况,网关没有网络,子设备已经加入成功了需要调用DEV_ADD,普通上线DEV_ONLINE,所以使用DEV_ADD比较好!!!
/*
* 通知设备的状态
* status表示设备当前的状态
* 注意,此函数由设备厂商根据产品业务选择性实现
*/
void hilink_notify_devstatus(int status)
{
switch(status){
case HILINK_M2M_CLOUD_OFFLINE:/* 设备与云端连接断开(版本向前兼容) */
hilink_printf("device disconnected!\n");
break;
case HILINK_M2M_CLOUD_ONLINE:/* 设备连接云端成功,处于正常工作态(版本向前兼容) */
hilink_printf("device connected!\n");
break;
case HILINK_LINK_CONNECTED_WIFI:/* 设备已经连上路由器 */
hilink_printf("device connected to internet!\n");
break;
case HILINK_M2M_CONNECTTING_CLOUD:/* 设备正在连接云端 */
hilink_printf("device connecting to cloud!\n");
break;
default:
hilink_printf("ok:%d\n",status);
break;
}
return;
}
接口2:网关重启前需要处理哪些事情,我这边不处理,直接返回0,即可同意重启.
位置:hilink-sdk-src/adapter/sdk_adapter/hilink_sdk_adapter.c
/*
* 实现模组重启前的设备操作
* flag为0表示HiLink SDK 线程看门狗触发模组重启; 为1表示APP删除设备触发模组重启
* 返回0表示处理成功, 系统可以重启,使用硬重启; 返回1表示处理成功, 系统可以重启,使用软重启;
* 返回负值表示处理失败, 系统不能重启
* 注意,此函数由设备厂商实现;若APP删除设备触发模组重启时,设备操作完务必返回0,否则会导致删除设备异常
*/
int hilink_process_before_restart(int flag)
{
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
hilink_printf("flag:%d\n",flag);
/* HiLink SDK线程看门狗超时触发模组重启 */
if (flag == HILINK_REBOOT_WATCHDOG) {
/* 实现模组重启前的操作(如:保存系统状态等) */
return 0;
}
/* APP删除设备触发模组重启 */
if (flag == HILINK_REBOOT_DEVDELETE) {
/* 实现模组重启前的操作(如:保存系统状态等) */
return 0;
}
return -1;
}
接口3:其他接口不用适配,故障码我不获取.
位置:hilink-sdk-src/adapter/network_adapter/hilink_network_adapter.c
接口1:获取网关当前版本,我的是10.
位置:hilink-sdk-src/adapter/network_adapter/hilink_ota.c
#define OTA_VERION "10"
/*
* 获取MCU当前版本
* version表示版本字符串
* inLen表示输入字符串长度
* outLen表示输出字符串长度
* 返回值是RETURN_OK时,表示获取成功
* 返回值是RETURN_ERROR_NO_MCU时,表示没有MCU
* 返回值是RETURN_ERROR时,表示获取失败
* 注意:
* 如果获取不到MCU的版本,则不对MCU进行升级。
* 建议厂商在MCU正常启动后,或升级启动后,就将MCU的版本号传递给模组,确保模组可以获取到MCU的版本。
*/
int HilinkGetMcuVersion(char *version, unsigned int inLen, unsigned int *outLen)
{
/* 厂商实现此接口 */
char ver[20];
memset(ver,0,sizeof(ver));
memcpy(ver,OTA_VERION,strlen(OTA_VERION));
memcpy(version,ver,strlen(ver));
*outLen = strlen(ver);
hilink_printf("ver:%s,outLen:%d\n", ver, *outLen);
return RETURN_OK;
return RETURN_ERROR_NO_MCU;
}
接口2:获取设备升级文件保存路径,linux系统,设置个路径和保存的文件名,sdk会把升级文件下载下来.然后结束,很简单
位置:hilink-sdk-src/adapter/network_adapter/hilink_ota.c
#define OTA_PATH "/root/APP-OTA"
/*
* 获取设备升级文件保存路径
* filePath表示设备升级文件保存路径
* len表示设备升级文件保存路径的长度
* 返回值是RETURN_OK时,表示获取成功
* 返回值是RETURN_ERROR时,表示获取失败
* 注意:
* Linux系统和安卓系统需要适配此接口,其他操作系统不用适配此接口。
* HiLink SDK下载的设备升级文件需保存在设备上的某个文件路径下;
* 此文件路径,需由厂商适配提供,例如“/var/update.bin”。
*/
int HILINK_GetUpdateFilePath(char *filePath, unsigned int len)
{
hilink_printf("---------------------HILINK_GetUpdateFilePath-------------------\n");
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
hilink_printf("filePath:%s,len:%d\n", filePath,len);
/* 厂商实现此接口 */
char path[128];
memset(path,0,sizeof(path));
memcpy(path,OTA_PATH,strlen(OTA_PATH));
//保存路径
memcpy(filePath,path,strlen(path));
len = strlen(path);
hilink_printf("filePath:%s,len:%d\n", filePath,len);
return RETURN_OK;
}
接口3:网关升级结束,我是调用Sethilink_otaPtr,修改数据库标记,重启程序后,处理OTA的文件,然后运行这个文件,不运行之前的默认文件了.
位置:hilink-sdk-src/adapter/network_adapter/hilink_ota.c
/*
* 模组升级结束
* status表示升级结果
* 当status是100时,表示升级成功
* 当status不是100时,表示升级失败
* 返回值是RETURN_OK时,表示处理成功,HiLink SDK将置升级标志或切换运行区标志
* 返回值不是RETURN_OK时,表示处理不成功,HiLink SDK将终止本次升级流程
* 注意:
* HiLink SDK在将固件写入到OTA升级区后,且完整性校验通过后,将调用厂商适配的此接口;
* 厂商可在此接口中完成和升级流程相关的处理。
* 自动升级流程在凌晨进行,因此厂商在实现升级流程相关功能时,确保在升级的下载安装固件和重启设备时避免对用户产生影响,
* 比如发出声音,光亮等;升级类型是否为自SL-D0Z0-W02-Hilink-V动升级可参考接口HilinkOtaStartProcess的参数type的描述。
*/
int HilinkOtaEndProcess(int status)
{
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
Sethilink_otaPtr(This,status);
if(status == 100)
{
hilink_printf("Hilink OTA OK \n");
}else{
hilink_printf("Hilink OTA error \n");
}
/* 厂商实现此接口 */
return RETURN_OK;
}
接口4:其他接口用不着,不是linux系统的话需要适配.
位置:hilink-sdk-src/adapter/network_adapter/hilink_ota.c
接口1:获取AC和BI两个变量的值,用于公司账号的加密啥的.
位置:hilink-sdk-src/adapter/profile_adapter/hilink_profile_adapter.c
注:这两个变量从哪里来呢?当我在华为开发者联盟注册中控主机后,即可下载到这两个文件,打开后转成16进制复制过来就行了.
提醒:linux下有命令使用十六进制方式打开文件.
/* 获取加密 AC 参数 */
unsigned char *hilink_get_auto_ac(void)
{
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
return A_C;
}
/* 获取加密 BI 参数 */
char *hilink_get_auto_bi_rsa_cipher(void)
{
hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
return bi_rsacipher;
}
接口2:修改服务当前字段值,当APP控制网关,数据就从这个接口过来的,非常重要的接口.
位置:hilink-sdk-src/adapter/profile_adapter/hilink_profile_adapter.c
/*
* 修改服务当前字段值
* svcId为服务的ID,payload为接收到需要修改的Json格式的字段与其值,len为payload的长度
* 返回0表示服务状态值修改成功,不需要底层设备主动上报,由Hilink Device SDK上报;
* 返回-101表示获得报文不符合要求;
* 返回-111表示服务状态值正在修改中,修改成功后底层设备必须主动上报;
*/
int hilink_put_char_state(const char *svcId, const char *payload, unsigned int len)
{
}
接口3:获取服务字段值,当APP控制网关后,会调用一次这个接口,意思是,我控制网关的数据,网关收到了吗?
位置:hilink-sdk-src/adapter/profile_adapter/hilink_profile_adapter.c
/*
* 获取服务字段值
* svcId表示服务ID。厂商实现该函数时,需要对svcId进行判断;
* in表示接收到的Json格式的字段与其值;
* inLen表示接收到的in的长度;
* out表示保存服务字段值内容的指针,内存由厂商开辟,使用完成后,由Hilink Device SDK释放;
* outLen表示读取到的payload的长度;
* 返回0表示服务状态字段值获取成功,返回非0表示获取服务状态字段值不成功。
*/
int hilink_get_char_state(const char *svcId, const char *in, unsigned int inLen, char **out, unsigned int *outLen)
{
}
接口3:获取网关的SN,版本:唯一值,给一个就行
位置:hilink-sdk-src/adapter/profile_adapter/hilink_profile_adapter.c
/*
* 获取设备sn号
* 注意: sn指向的字符串长度为0时将使用设备mac地址作为sn
*/
void HilinkGetDeviceSn(unsigned int len, char *sn)
{
}
/*
* 获取设备相关版本号
* 返回0表示版本号获取成功,返回其他表示版本号获取失败
* 注意,此接口为HiLink内部调用函数
*/
int getDeviceVersion(char **firmwareVer, char **softwareVer, char **hardwareVer)
{
// hilink_printf("file:%s,line:%d\n", __FILE__, __LINE__);
*firmwareVer = FIRMWARE_VER;
*softwareVer = SOFTWARE_VER;
*hardwareVer = HARDWARE_VER;
return 0;
}
接口4:其他接口用不着
位置:hilink-sdk-src/adapter/profile_adapter/hilink_profile_adapter.c