分布式软总线的编译和运行¶
目前聚元 PolyOS 在 硬件 Sifive Unmatched 开发板上集成了分布式软总线功能,实验所用的 OpenHarmony 设备采用的是 DAYU200 开发板。未来,聚元 PolyOS 将继续在日益丰富的 RISC-V 硬件SoC架构上适配分布式软总线功能。
下面从编译和运行分布式软总线应用说明两方面介绍其使用。
分布式软总线编译¶
具体见 build_portal环境搭建及使用 关于 unmatched 的编译使用。
分布式软总线应用说明¶
将编译出来的 demo-coreip-cli-unmatched.wic.xz,烧录到 SD 卡中。(sdX 更改为 SD 卡实际设备文件)
xzcat demo-coreip-cli-unmatched.wic.xz | sudo dd of=/dev/sdX bs=512K iflag=fullblock oflag=direct conv=fsync status=progress
将烧录完成的 SD 卡插入 Sifive Unmatched 开发板中的 MicroSD 卡槽后启动开发板。
服务端启动¶
服务端主程序名为 softbus_server_main 。
软总线通过独立进程部署的方式对外提供服务,通过执行服务端主程序可拉起软总线进程提供对外服务,实验时聚元 PolyOS 和 OpenHarmony 设备均需启动软总线服务,OpenHarmony 系统已默认启动,无需单独拉起软总线服务进程。
softbus_server_main >log.file &
1.当服务端被拉起时,会主动通过名为 ethX/wifiX 的网络设备进行 coap 广播,对对端设备进行自动探测。
2.当探测到对端设备且对端设备为可信设备时,还会自动组网操作,以便后后续客户端进行快速连接和传输(“添加可信设备”见下文)。
3.日志模块可通过重定向接管,有条件者还可通过实现和替换软总线依赖的 hilog 模块,进行更细致的日志管理。
4.服务端依赖于系统参数模块 syspara,以获取设备唯一的 UDID。聚元 PolyOS 预留了 /etc/SN
的文件接口,作为生成 UDID 的参数。
注意
SN 号可为 64 字节长度内的任意字符串。
用户需保证单设备节点上有且仅有唯一的 softbus_server_main 进程。
用户需在启动 softbus_server_main 前配置
/etc/SN
,并保证多设备下 SN 号的唯一性。
可信设备认证¶
软总线在创建连接的过程中,会调用 hichain 模块的认证接口,与对端的设备进行认证操作。hichain 模块为 OpenHarmony 提供设备认证能力,支持通过点对点认证方式创建可信群组。
聚元 PolyOS 和 OpenHarmony 设备之间要互连互通,则需要在聚元 PolyOS 上支持 hichain 的点对点认证和可信群组创建能力。
hichain 模块与软总线一样,分为服务端和客户端,实验中聚元 PolyOS 和 OpenHarmony 设备均可以作为服务端或客户端:
服务端:用户仅需拉起 hichain 服务端,无需额外操作服务端。
客户端:通过 hichain 的客户端提供的 API,可以创建群组,并请求添加群组成员,从而将多个设备添加到可信群组。
hichain 的客户端提供动态链接库 libdeviceauth_sdk.z.so
,用户可以单独链接 hichain 的客户端进行可信群组创建。
${CROSS_COMPILE}ld -ldeviceauth_sdk.z
在可信群组创建后,软总线会自动触发组网,支持后续软总线客户端的连接和传输。
hichain 的客户端 API 头文件为 device_auth.h
,可在客户端代码中引用。
直接调用接口
InitDeviceAuthService |
初始化hichain客户端 |
GetGmInstance |
获取客户端群组管理的操作函数组 |
DestroyDeviceAuthService |
注销hichain客户端 |
GetGmInstance返回的操作函数组
regCallback |
注册群组创建和请求回调函数 |
unRegCallback |
解注册群组回调函数 |
createGroup |
创建新的群组 |
getGroupInfo |
查询本地群组信息 |
destroyInfo |
释放通过getGroupInfo申请的内存 |
addMemberToGroup |
请求添加成员到群组 |
isDeviceInGroup |
查询某个设备是否在群组中 |
使用范例
按照 hichain 的点对点 pin 码认证方式,需要通过设备创建群组( host ),另一个台设备请求添加成员到该群组( target ),实例代码如下:
#include <stdio.h>
#include <string.h>
#include <cJSON.h>
#include <securec.h>
#include <discovery_service.h>
#include <session.h>
#include <device_auth.h>
#include <parameter.h>
#define APP_ID "hichain_test"
#define DEFAULT_CAPABILITY "osdCapability"
#define PUBLISH_ID 123
#define DEFAULT_GROUP_NAME "dsoftbus"
#define DEFAULT_PIN_CODE "123456"
#define MAX_UDID_LEN 65
#define MAX_GROUP_LEN 65
#define ERR_RET -1
#define FIELD_ETH_IP "ETH_IP"
#define FIELD_ETH_PORT "ETH_PORT"
#define FIELD_WLAN_IP "WIFI_IP"
#define FIELD_WLAN_PORT "WIFI_PORT"
enum {
DEVICE_DISCOVERY = 0,
DEVICE_JOINING,
DEVICE_ONLINE,
}DeviceStatus;
char *g_deviceStatus[] = {
"discovery",
"joining",
"online",
};
typedef struct DeviceList {
struct DeviceList *next;
DeviceInfo device;
int status;
int64_t requestId;
} DeviceList;
DeviceList *g_deviceListHead = NULL;
static const DeviceGroupManager *g_hichainGmInstance = NULL;
static char g_udid[MAX_UDID_LEN];
static char g_groupId[MAX_GROUP_LEN];
static int64_t g_requestId = 1;
static const char *GetStringFromJson(const cJSON *obj, const char *key)
{
cJSON *item;
if (obj == NULL || key == NULL)
return NULL;
item = cJSON_GetObjectItemCaseSensitive(obj, key);
if (item != NULL && cJSON_IsString(item)) {
return cJSON_GetStringValue(item);
} else {
int len = cJSON_GetArraySize(obj);
for (int i = 0; i < len; i++) {
item = cJSON_GetArrayItem(obj, i);
if (cJSON_IsObject(item)) {
const char *value = GetStringFromJson(item, key);
if (value != NULL)
return value;
}
}
}
return NULL;
}
static int HichainSaveGroupID(const char *param)
{
cJSON *msg = cJSON_Parse(param);
const char *value = NULL;
if (msg == NULL) {
printf("HichainSaveGroupID: cJSON_Parse fail\n");
return ERR_RET;
}
value = GetStringFromJson(msg, FIELD_GROUP_ID);
if (value == NULL) {
printf("HichainSaveGroupID:GetStringFromJson fail\n");
cJSON_Delete(msg);
return ERR_RET;
}
memcpy_s(g_groupId, MAX_GROUP_LEN, value, strlen(value));
printf("HichainSaveGroupID:groupID=%s\n", g_groupId);
cJSON_Delete(msg);
return 0;
}
static void HiChainGmOnFinish(int64_t requestId, int operationCode, const char *returnData)
{
if (operationCode == GROUP_CREATE && returnData != NULL) {
printf("create new group finish:requestId=%ld, returnData=%s\n", requestId, returnData);
HichainSaveGroupID(returnData);
} else if (operationCode == MEMBER_JOIN) {
DeviceList *node = g_deviceListHead;
printf("member join finish:requestId=%ld, returnData=%s\n", requestId, returnData);
while (node) {
if (node->requestId != requestId) {
node = node->next;
continue;
}
node->status = DEVICE_ONLINE;
break;
}
} else {
printf("<HiChainGmOnFinish>CB:requestId=%ld, operationCode=%d, returnData=%s\n", requestId, operationCode, returnData);
}
}
static void HiChainGmOnError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
{
DeviceList *node = g_deviceListHead;
printf("<HiChainGmOnError>CB:requestId=%ld, operationCode=%d, errorCode=%d, errorReturn=%s\n", requestId, operationCode, errorCode, errorReturn);
while (node) {
if (node->requestId != requestId) {
node = node->next;
continue;
}
node->status = DEVICE_DISCOVERY;
break;
}
}
static char *HiChainGmOnRuest(int64_t requestId, int operationCode, const char *reqParams)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
printf("<HiChainGmOnRuest>CB:requestId=%ld, operationCode=%d, reqParams=%s", requestId, operationCode, reqParams);
if (operationCode != MEMBER_JOIN) {
return NULL;
}
if (msg == NULL) {
printf("HiChainGmOnRuest: cJSON_CreateObject fail\n");
}
if (cJSON_AddNumberToObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) == NULL ||
cJSON_AddStringToObject(msg, FIELD_PIN_CODE, DEFAULT_PIN_CODE) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL) {
printf("HiChainGmOnRuest: cJSON_AddToObject fail\n");
cJSON_Delete(msg);
return NULL;
}
param = cJSON_PrintUnformatted(msg);
cJSON_Delete(msg);
return param;
}
static const DeviceAuthCallback g_groupManagerCallback = {
.onRequest = HiChainGmOnRuest,
.onError = HiChainGmOnError,
.onFinish = HiChainGmOnFinish,
};
static int HichainGmRegCallback(void)
{
return g_hichainGmInstance->regCallback(APP_ID, &g_groupManagerCallback);
}
static void HichainGmUnRegCallback(void)
{
g_hichainGmInstance->unRegCallback(APP_ID);
}
static int HichainGmGetGroupInfo(char **groupVec, uint32_t *num)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL) {
printf("HichainGmGetGroupInfo: cJSON_CreateObject fail\n");
return ret;
}
if (cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_VISIBILITY, GROUP_VISIBILITY_PUBLIC) == NULL) {
printf("HichainGmGetGroupInfo: cJSON_AddToObject fail\n");
goto err_cJSON_Delete;
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmGetGroupInfo: cJSON_PrintUnformatted fail\n");
goto err_cJSON_Delete;
}
ret = g_hichainGmInstance->getGroupInfo(ANY_OS_ACCOUNT, APP_ID, param, groupVec, num);
if (ret != 0) {
printf("getGroupInfo fail:%d", ret);
goto err_getGroupInfo;
}
err_getGroupInfo:
cJSON_free(param);
err_cJSON_Delete:
cJSON_Delete(msg);
return ret;
}
static void HichainGmDestroyGroupInfo(char **groupVec)
{
g_hichainGmInstance->destroyInfo(groupVec);
}
static int HichainGmCreatGroup(void)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL)
return ret;
if (cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_USER_TYPE, 0) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_VISIBILITY, GROUP_VISIBILITY_PUBLIC) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_EXPIRE_TIME, EXPIRE_TIME_MAX) == NULL) {
printf("HichainGmCreatGroup: cJSON_AddToObject fail\n");
cJSON_Delete(msg);
return ret;
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmCreatGroup: cJSON_PrintUnformatted fail\n");
cJSON_Delete(msg);
return ret;
}
ret = g_hichainGmInstance->createGroup(ANY_OS_ACCOUNT, g_requestId++, APP_ID, param);
cJSON_free(param);
cJSON_Delete(msg);
return ret;
}
static bool HichainIsDeviceInGroup(const char *groupId, const char *devId)
{
return g_hichainGmInstance->isDeviceInGroup(ANY_OS_ACCOUNT, APP_ID, groupId, devId);
}
static int HichainGmAddMemberToGroup(DeviceInfo *device, const char *groupId)
{
cJSON *msg = cJSON_CreateObject();
cJSON *addr = NULL;
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_CreateObject1 fail\n");
return ret;
}
addr = cJSON_CreateObject();
if (addr == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_CreateObject2 fail\n");
goto err_cJSON_CreateObject;
}
for (unsigned int i = 0; i < device->addrNum; i++) {
if (device->addr[i].type == CONNECTION_ADDR_ETH) {
if (cJSON_AddStringToObject(addr, FIELD_ETH_IP, device->addr[i].info.ip.ip) == NULL ||
cJSON_AddNumberToObject(addr, FIELD_ETH_PORT, device->addr[i].info.ip.port) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject1 fail\n");
goto err_cJSON_AddToObject;
}
} else if (device->addr[i].type == CONNECTION_ADDR_WLAN) {
if (cJSON_AddStringToObject(addr, FIELD_WLAN_IP, device->addr[i].info.ip.ip) == NULL ||
cJSON_AddNumberToObject(addr, FIELD_WLAN_PORT, device->addr[i].info.ip.port) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject2 fail\n");
goto err_cJSON_AddToObject;
}
} else {
printf("unsupport connection type:%d\n", device->addr[i].type);
goto err_cJSON_AddToObject;
}
}
param = cJSON_PrintUnformatted(addr);
if (param == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_PrintUnformatted1 fail\n");
goto err_cJSON_AddToObject;
}
if (cJSON_AddStringToObject(msg, FIELD_GROUP_ID, groupId) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_PIN_CODE, DEFAULT_PIN_CODE) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddBoolToObject(msg, FIELD_IS_ADMIN, false) == NULL ||
cJSON_AddStringToObject(msg, FIELD_CONNECT_PARAMS, param) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject4 fail\n");
goto err_cJSON_AddToObject1;
}
cJSON_free(param);
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_PrintUnformatted fail\n");
goto err_cJSON_CreateObject;
}
ret = g_hichainGmInstance->addMemberToGroup(ANY_OS_ACCOUNT, g_requestId++, APP_ID, param);
if (ret != 0) {
printf("addMemberToGroup fail:%d\n", ret);
}
err_cJSON_AddToObject1:
cJSON_free(param);
err_cJSON_AddToObject:
cJSON_Delete(addr);
err_cJSON_CreateObject:
cJSON_Delete(msg);
return ret;
}
static int HichainInit(void)
{
char *groupVec = NULL;
uint32_t num;
int ret;
ret = InitDeviceAuthService();
if (ret != 0) {
printf("InitDeviceAuthService fail:%d\n", ret);
return ret;
}
g_hichainGmInstance = GetGmInstance();
if (g_hichainGmInstance == NULL) {
printf("GetGmInstance fail\n");
ret = ERR_RET;
goto err_GetGmInstance;
}
ret = HichainGmRegCallback();
if (ret != 0) {
printf("HichainGmregCallback fail.:%d\n", ret);
goto err_HichainGmRegCallback;
}
ret = HichainGmGetGroupInfo(&groupVec, &num);
if (ret != 0) {
printf("HichainGmGetGroupInfo fail:%d\n", ret);
goto err_HichainGmGetGroupInfo;
}
if (num == 0) {
ret = HichainGmCreatGroup();
if (ret) {
printf("HichainGmCreatGroup fail:%d\n", ret);
goto err_HichainGmCreatGroup;
}
} else {
printf("HichainGmGetGroupInfo:num=%u\n", num);
HichainSaveGroupID(groupVec);
HichainGmDestroyGroupInfo(&groupVec);
}
return 0;
err_HichainGmCreatGroup:
err_HichainGmGetGroupInfo:
HichainGmUnRegCallback();
err_HichainGmRegCallback:
err_GetGmInstance:
DestroyDeviceAuthService();
return ret;
}
static void CheckDeviceStatus(void)
{
DeviceList *node = g_deviceListHead;
char *groupVec = NULL;
uint32_t num;
int ret;
ret = HichainGmGetGroupInfo(&groupVec, &num);
if (ret != 0 || num == 0) {
printf("HichainGmGetGroupInfo fail\n");
return;
}
ret = HichainSaveGroupID(groupVec);
if (ret != 0)
goto err_HichainSaveGroupID;
while (node) {
if (HichainIsDeviceInGroup(g_groupId, node->device.devId)) {
node->status = DEVICE_ONLINE;
}
node = node->next;
}
err_HichainSaveGroupID:
HichainGmDestroyGroupInfo(&groupVec);
}
static bool CheckDeviceExist(const DeviceInfo *device)
{
DeviceList *node = g_deviceListHead;
while (node) {
if (strcmp(device->devId, node->device.devId) == 0) {
return true;
}
node = node->next;
}
return false;
}
static void SaveDeviceInfo(const DeviceInfo *device)
{
DeviceList *node = malloc(sizeof(DeviceList));
if (node == NULL) {
printf("SaveDeviceInfo: malloc fail\n");
return;
}
node->device = *device;
node->requestId = ERR_RET;
node->status = DEVICE_DISCOVERY;
if (g_deviceListHead == NULL) {
node->next = NULL;
} else {
node->next = g_deviceListHead;
}
g_deviceListHead = node;
}
static DeviceList *GetDeviceInfo(int idx)
{
DeviceList *node = g_deviceListHead;
while (node) {
if (--idx == 0) {
return node;
}
node = node->next;
}
return NULL;
}
static void FreeDeviceInfo()
{
while (g_deviceListHead) {
DeviceList *node = g_deviceListHead->next;
free(g_deviceListHead);
g_deviceListHead = node;
}
}
static void ListDevice(void)
{
DeviceList *node = g_deviceListHead;
int input, num = 0;
if (node == NULL) {
printf("Get no device!\n");
return;
}
CheckDeviceStatus();
while (node) {
printf("\n%d: devName=%s\n", ++num, node->device.devName);
printf("\tdevId=%s\n", node->device.devId);
printf("\tstatus=%s\n", g_deviceStatus[node->status]);
node = node->next;
}
printf("Input num to auth:");
scanf_s("%d", &input);
if (input <= 0 || input >num) {
printf("error input num\n");
return;
}
node = GetDeviceInfo(input);
if (node == NULL) {
printf("GetDeviceInfo fail\n");
return;
}
if (node->status == DEVICE_DISCOVERY) {
node->requestId = g_requestId;
node->status = DEVICE_JOINING;
int ret = HichainGmAddMemberToGroup(&node->device, g_groupId);
if (ret) {
printf("HichainGmAddMemberToGroup fail:%d\n", ret);
node->requestId = ERR_RET;
node->status = DEVICE_DISCOVERY;
return;
}
}
}
static void PublishSuccess(int publishId)
{
printf("<PublishSuccess>CB: publish %d done\n", publishId);
}
static void PublishFailed(int publishId, PublishFailReason reason)
{
printf("<PublishFailed>CB: publish %d failed, reason=%d\n", publishId, (int)reason);
}
static int PublishServiceInterface(void)
{
PublishInfo info = {
.publishId = PUBLISH_ID,
.mode = DISCOVER_MODE_PASSIVE,
.medium = COAP,
.freq = LOW,
.capability = DEFAULT_CAPABILITY,
.capabilityData = NULL,
.dataLen = 0,
};
IPublishCallback cb = {
.OnPublishSuccess = PublishSuccess,
.OnPublishFail = PublishFailed,
};
return PublishService(APP_ID, &info, &cb);
}
static void DeviceFound(const DeviceInfo *device)
{
printf("<DeviceFound>CB: devName=%s", device->devName);
if (CheckDeviceExist(device)) {
printf("device:%s udid:%s is already in List\n", device->devName, device->devId);
return;
}
SaveDeviceInfo(device);
}
static void DiscoverySuccess(int subscribeId)
{
printf("<DiscoverySuccess>CB: discover subscribeId=%d\n", subscribeId);
}
static void DiscoveryFailed(int subscribeId, DiscoveryFailReason reason)
{
printf("<DiscoveryFailed>CB: discover subscribeId=%d fail, reason=%d\n", subscribeId, (int)reason);
}
static int DiscoveryInterface()
{
SubscribeInfo info = {
.subscribeId = PUBLISH_ID,
.mode = DISCOVER_MODE_ACTIVE,
.medium = COAP,
.freq = LOW,
.isSameAccount = false,
.isWakeRemote = false,
.capability = DEFAULT_CAPABILITY,
.capabilityData = NULL,
.dataLen = 0,
};
IDiscoveryCallback cb = {
.OnDeviceFound = DeviceFound,
.OnDiscoverFailed = DiscoveryFailed,
.OnDiscoverySuccess = DiscoverySuccess,
};
return StartDiscovery(APP_ID, &info, &cb);
}
int main()
{
int ret;
bool loop = true;
ret = GetDevUdid(g_udid, MAX_UDID_LEN);
if (ret) {
printf("GetDevUdid fail:%d\n", ret);
return ret;
}
ret = HichainInit();
if (ret) {
printf("HichainInit fail\n");
return ret;
}
ret = PublishServiceInterface();
if (ret) {
printf("PublishService fail, ret=%d\n", ret);
goto err_PublishServiceInterface;
}
ret = DiscoveryInterface();
if (ret != 0) {
printf("DiscoveryInterface fail\n");
goto err_DiscoveryInterface;
}
while (loop) {
printf("\nInput l to list device; Input s to stop:");
while (true) {
char c = getchar();
if (c == 'l') {
ListDevice();
continue;
} else if (c == 's') {
loop = false;
break;
} else if (c == '\n') {
break;
} else {
continue;
}
}
}
StopDiscovery(APP_ID, PUBLISH_ID);
FreeDeviceInfo();
err_DiscoveryInterface:
UnPublishService(APP_ID, PUBLISH_ID);
err_PublishServiceInterface:
HichainGmUnRegCallback();
return ret;
}
备注
在HichainInit完成后,可以在任意一端调用HichainGmAddMemberToGroup申请将本端设备添加到对端的群组中。
认证中使用的pin码,分别在两端设备中通过addMemberToGroup函数和HiChainGmOnRuest回调函数接口传入,实际应用中可由用户随机生成。
HichainGmAddMemberToGroup认证过程中需要交互的对端信息,如deviceInfo,groupID等,实际应用中可通过软总线的发现能力和认证通道进行数据交互。
客户端使用¶
聚元 PolyOS 已经为用户提供了编译好的客户端可执行程序 dsoftbus
,用户可以根据需求进行二次开发。客户端提供了动态链接库 libsoftbus_client.z.so
以及对应的头文件:
发现:discovery_service.h
组网:softbus_bus_center.h
连接/组网:session.h
discovery_service.h
发现模块头文件,支持应用主动探测和发布的API如下:
PublishService |
发布特定服务能力 |
UnPublishService |
取消发布特定服务能力 |
StartDiscovery |
订阅/探测特定服务能力 |
StopDiscovery |
取消订阅特性服务能力 |
注意
服务能力通过g_capabilityMap数组定义,用户若新增能力需要自定义修改该数组,并重新编译软总线服务端和客户端程序来生效。
softbus_bus_center.h
组网模块头文件,支持获取组网内设备信息API如下:
GetAllNodeDeviceInfo |
获取当前组网内所有节点信息 |
FreeNodeInfo |
释放GetAllNodeDeviceInfo返回的节点信息内存 |
softbus_bus_center.h
连接/传输模块头文件,支持创建session和数据传输API如下:
CreateSessionServer |
创建session服务端 |
RemoveSessionServer |
移除session服务端 |
OpenSession |
创建到对端的传输连接(依赖于本端和对端提前创建的SessionServer) |
CloseSession |
断开传输连接 |
SendBytes |
根据建好的连接ID,进行字节流数据传输 |
SendMessage |
根据建好的连接ID,进行消息数据传输 |
应用示例
该示例代码中同时实现了聚元 PolyOS 和 OpenHarmony 设备间的发现、连接、图片收发和图片 TensorFlow Lite 推理和结果反馈功能。客户端程序 dsoftbus.c
具体如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <cJSON.h>
#include <fcntl.h>
#include <securec.h>
#include "md5.h"
#include <discovery_service.h>
#include <session.h>
#include <device_auth.h>
#include <parameter.h>
#include <softbus_common.h>
#include <softbus_bus_center.h>
#define APP_ID "hichain_test"
#define DEFAULT_GROUP_NAME "dsoftbus"
#define DEFAULT_PIN_CODE "123456"
#define MAX_UDID_LEN 65
#define MAX_GROUP_LEN 65
#define ERR_RET -1
#define FIELD_ETH_IP "ETH_IP"
#define FIELD_ETH_PORT "ETH_PORT"
#define FIELD_WLAN_IP "WIFI_IP"
#define FIELD_WLAN_PORT "WIFI_PORT"
#define PACKAGE_NAME "softbus_sample"
#define LOCAL_SESSION_NAME "session_test"
#define TARGET_SESSION_NAME "session_test"
#define DEFAULT_CAPABILITY "osdCapability"
#define DEFAULT_SESSION_GROUP "group_test"
#define PUBLISH_ID 123
#define TYPE "TYPE"
#define NAME "NAME"
#define LENGTH "LENGTH"
#define CONTENT "CONTENT"
static int g_sessionId;
static void send_callback(int sessionId ,char *callback);
enum {
TYPE_MSG = 1,
TYPE_IMG,
TYPE_ELSE,
}MessageType;
enum {
DEVICE_DISCOVERY = 0,
DEVICE_JOINING,
DEVICE_ONLINE,
}DeviceStatus;
char *g_deviceStatus[] = {
"discovery",
"joining",
"online",
};
typedef struct DeviceList {
struct DeviceList *next;
DeviceInfo device;
int status;
int64_t requestId;
} DeviceList;
DeviceList *g_deviceListHead = NULL;
static const DeviceGroupManager *g_hichainGmInstance = NULL;
static char g_udid[MAX_UDID_LEN];
static char g_groupId[MAX_GROUP_LEN];
static int64_t g_requestId = 1;
static const char *GetStringFromJson(const cJSON *obj, const char *key)
{
cJSON *item;
if (obj == NULL || key == NULL)
return NULL;
item = cJSON_GetObjectItemCaseSensitive(obj, key);
if (item != NULL && cJSON_IsString(item)) {
return cJSON_GetStringValue(item);
} else {
int len = cJSON_GetArraySize(obj);
for (int i = 0; i < len; i++) {
item = cJSON_GetArrayItem(obj, i);
if (cJSON_IsObject(item)) {
const char *value = GetStringFromJson(item, key);
if (value != NULL)
return value;
}
}
}
return NULL;
}
static int HichainSaveGroupID(const char *param)
{
cJSON *msg = cJSON_Parse(param);
const char *value = NULL;
if (msg == NULL) {
printf("HichainSaveGroupID: cJSON_Parse failed\n");
return ERR_RET;
}
value = GetStringFromJson(msg, FIELD_GROUP_ID);
if (value == NULL) {
printf("HichainSaveGroupID:GetStringFromJson failed\n");
cJSON_Delete(msg);
return ERR_RET;
}
memcpy_s(g_groupId, MAX_GROUP_LEN, value, strlen(value));
printf("HichainSaveGroupID:groupID=%s\n", g_groupId);
cJSON_Delete(msg);
return 0;
}
static void HiChainGmOnFinish(int64_t requestId, int operationCode, const char *returnData)
{
if (operationCode == GROUP_CREATE && returnData != NULL) {
printf("create new group finish:requestId=%ld, returnData=%s\n", requestId, returnData);
HichainSaveGroupID(returnData);
} else if (operationCode == MEMBER_JOIN) {
DeviceList *node = g_deviceListHead;
printf("member join finish:requestId=%ld, returnData=%s\n", requestId, returnData);
while (node) {
if (node->requestId != requestId) {
node = node->next;
continue;
}
node->status = DEVICE_ONLINE;
break;
}
} else {
printf("<HiChainGmOnFinish>CB:requestId=%ld, operationCode=%d, returnData=%s\n", requestId, operationCode, returnData);
}
}
static void HiChainGmOnError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
{
DeviceList *node = g_deviceListHead;
printf("<HiChainGmOnError>CB:requestId=%ld, operationCode=%d, errorCode=%d, errorReturn=%s\n", requestId, operationCode, errorCode, errorReturn);
while (node) {
if (node->requestId != requestId) {
node = node->next;
continue;
}
node->status = DEVICE_DISCOVERY;
break;
}
}
static char *HiChainGmOnRuest(int64_t requestId, int operationCode, const char *reqParams)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
printf("<HiChainGmOnRuest>CB:requestId=%ld, operationCode=%d, reqParams=%s", requestId, operationCode, reqParams);
if (operationCode != MEMBER_JOIN) {
return NULL;
}
if (msg == NULL) {
printf("HiChainGmOnRuest: cJSON_CreateObject failed\n");
}
if (cJSON_AddNumberToObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) == NULL ||
cJSON_AddStringToObject(msg, FIELD_PIN_CODE, DEFAULT_PIN_CODE) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL) {
printf("HiChainGmOnRuest: cJSON_AddToObject failed\n");
cJSON_Delete(msg);
return NULL;
}
param = cJSON_PrintUnformatted(msg);
cJSON_Delete(msg);
return param;
}
static const DeviceAuthCallback g_groupManagerCallback = {
.onRequest = HiChainGmOnRuest,
.onError = HiChainGmOnError,
.onFinish = HiChainGmOnFinish,
};
static int HichainGmRegCallback(void)
{
return g_hichainGmInstance->regCallback(APP_ID, &g_groupManagerCallback);
}
static void HichainGmUnRegCallback(void)
{
g_hichainGmInstance->unRegCallback(APP_ID);
}
static int HichainGmGetGroupInfo(char **groupVec, uint32_t *num)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL) {
printf("HichainGmGetGroupInfo: cJSON_CreateObject failed\n");
return ret;
}
if (cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_VISIBILITY, GROUP_VISIBILITY_PUBLIC) == NULL) {
printf("HichainGmGetGroupInfo: cJSON_AddToObject failed\n");
goto err_cJSON_Delete;
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmGetGroupInfo: cJSON_PrintUnformatted failed\n");
goto err_cJSON_Delete;
}
ret = g_hichainGmInstance->getGroupInfo(ANY_OS_ACCOUNT, APP_ID, param, groupVec, num);
if (ret != 0) {
printf("getGroupInfo failed:%d", ret);
goto err_getGroupInfo;
}
err_getGroupInfo:
cJSON_free(param);
err_cJSON_Delete:
cJSON_Delete(msg);
return ret;
}
static void HichainGmDestroyGroupInfo(char **groupVec)
{
g_hichainGmInstance->destroyInfo(groupVec);
}
static int HichainGmCreatGroup(void)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL)
return ret;
if (cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_USER_TYPE, 0) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_VISIBILITY, GROUP_VISIBILITY_PUBLIC) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_EXPIRE_TIME, EXPIRE_TIME_MAX) == NULL) {
printf("HichainGmCreatGroup: cJSON_AddToObject failed\n");
cJSON_Delete(msg);
return ret;
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmCreatGroup: cJSON_PrintUnformatted failed\n");
cJSON_Delete(msg);
return ret;
}
ret = g_hichainGmInstance->createGroup(ANY_OS_ACCOUNT, g_requestId++, APP_ID, param);
cJSON_free(param);
cJSON_Delete(msg);
return ret;
}
static bool HichainIsDeviceInGroup(const char *groupId, const char *devId)
{
return g_hichainGmInstance->isDeviceInGroup(ANY_OS_ACCOUNT, APP_ID, groupId, devId);
}
static int HichainGmAddMemberToGroup(DeviceInfo *device, const char *groupId)
{
cJSON *msg = cJSON_CreateObject();
cJSON *addr = NULL;
char *param = NULL;
int ret = ERR_RET;
if (msg == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_CreateObject1 failed\n");
return ret;
}
addr = cJSON_CreateObject();
if (addr == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_CreateObject2 failed\n");
goto err_cJSON_CreateObject;
}
for (unsigned int i = 0; i < device->addrNum; i++) {
if (device->addr[i].type == CONNECTION_ADDR_ETH) {
if (cJSON_AddStringToObject(addr, FIELD_ETH_IP, device->addr[i].info.ip.ip) == NULL ||
cJSON_AddNumberToObject(addr, FIELD_ETH_PORT, device->addr[i].info.ip.port) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject1 failed\n");
goto err_cJSON_AddToObject;
}
} else if (device->addr[i].type == CONNECTION_ADDR_WLAN) {
if (cJSON_AddStringToObject(addr, FIELD_WLAN_IP, device->addr[i].info.ip.ip) == NULL ||
cJSON_AddNumberToObject(addr, FIELD_WLAN_PORT, device->addr[i].info.ip.port) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject2 failed\n");
goto err_cJSON_AddToObject;
}
} else {
printf("unsupport connection type:%d\n", device->addr[i].type);
goto err_cJSON_AddToObject;
}
}
param = cJSON_PrintUnformatted(addr);
if (param == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_PrintUnformatted1 failed\n");
goto err_cJSON_AddToObject;
}
if (cJSON_AddStringToObject(msg, FIELD_GROUP_ID, groupId) == NULL ||
cJSON_AddNumberToObject(msg, FIELD_GROUP_TYPE, PEER_TO_PEER_GROUP) == NULL ||
cJSON_AddStringToObject(msg, FIELD_PIN_CODE, DEFAULT_PIN_CODE) == NULL ||
cJSON_AddStringToObject(msg, FIELD_DEVICE_ID, g_udid) == NULL ||
cJSON_AddStringToObject(msg, FIELD_GROUP_NAME, DEFAULT_GROUP_NAME) == NULL ||
cJSON_AddBoolToObject(msg, FIELD_IS_ADMIN, false) == NULL ||
cJSON_AddStringToObject(msg, FIELD_CONNECT_PARAMS, param) == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_AddToObject4 failed\n");
goto err_cJSON_AddToObject1;
}
cJSON_free(param);
param = cJSON_PrintUnformatted(msg);
if (param == NULL) {
printf("HichainGmAddMemberToGroup: cJSON_PrintUnformatted failed\n");
goto err_cJSON_CreateObject;
}
ret = g_hichainGmInstance->addMemberToGroup(ANY_OS_ACCOUNT, g_requestId++, APP_ID, param);
if (ret != 0) {
printf("addMemberToGroup failed:%d\n", ret);
}
err_cJSON_AddToObject1:
cJSON_free(param);
err_cJSON_AddToObject:
cJSON_Delete(addr);
err_cJSON_CreateObject:
cJSON_Delete(msg);
return ret;
}
static int HichainInit(void)
{
char *groupVec = NULL;
uint32_t num;
int ret;
ret = GetDevUdid(g_udid, MAX_UDID_LEN);
if (ret) {
printf("GetDevUdid failed:%d\n", ret);
return ret;
}
ret = InitDeviceAuthService();
if (ret != 0) {
printf("InitDeviceAuthService failed:%d\n", ret);
return ret;
}
g_hichainGmInstance = GetGmInstance();
if (g_hichainGmInstance == NULL) {
printf("GetGmInstance failed\n");
ret = ERR_RET;
goto err_GetGmInstance;
}
ret = HichainGmRegCallback();
if (ret != 0) {
printf("HichainGmregCallback failed.:%d\n", ret);
goto err_HichainGmRegCallback;
}
ret = HichainGmGetGroupInfo(&groupVec, &num);
if (ret != 0) {
printf("HichainGmGetGroupInfo failed:%d\n", ret);
goto err_HichainGmGetGroupInfo;
}
if (num == 0) {
ret = HichainGmCreatGroup();
if (ret) {
printf("HichainGmCreatGroup failed:%d\n", ret);
goto err_HichainGmCreatGroup;
}
}
else {
printf("HichainGmGetGroupInfo:num=%u\n", num);
HichainSaveGroupID(groupVec);
HichainGmDestroyGroupInfo(&groupVec);
}
return 0;
err_HichainGmCreatGroup:
err_HichainGmGetGroupInfo:
HichainGmUnRegCallback();
err_HichainGmRegCallback:
err_GetGmInstance:
DestroyDeviceAuthService();
return ret;
}
static bool CheckDeviceExist(const DeviceInfo *device)
{
DeviceList *node = g_deviceListHead;
while (node) {
if (strcmp(device->devId, node->device.devId) == 0) {
return true;
}
node = node->next;
}
return false;
}
static void SaveDeviceInfo(const DeviceInfo *device)
{
DeviceList *node = malloc(sizeof(DeviceList));
if (node == NULL) {
printf("SaveDeviceInfo: malloc failed\n");
return;
}
node->device = *device;
node->requestId = ERR_RET;
node->status = DEVICE_DISCOVERY;
if (g_deviceListHead == NULL) {
node->next = NULL;
} else {
node->next = g_deviceListHead;
}
g_deviceListHead = node;
}
static DeviceList *GetDeviceInfo(int idx)
{
DeviceList *node = g_deviceListHead;
while (node) {
if (--idx == 0) {
return node;
}
node = node->next;
}
return NULL;
}
static void FreeDeviceInfo()
{
while (g_deviceListHead) {
DeviceList *node = g_deviceListHead->next;
free(g_deviceListHead);
g_deviceListHead = node;
}
}
static void PublishSuccess(int publishId)
{
printf("<PublishSuccess>CB: publish %d done\n", publishId);
}
static void PublishFailed(int publishId, PublishFailReason reason)
{
printf("<PublishFailed>CB: publish %d failed, reason=%d\n", publishId, (int)reason);
}
static int PublishServiceInterface(void)
{
PublishInfo info = {
.publishId = PUBLISH_ID,
.mode = DISCOVER_MODE_PASSIVE,
.medium = COAP,
.freq = LOW,
.capability = DEFAULT_CAPABILITY,
.capabilityData = NULL,
.dataLen = 0,
};
IPublishCallback cb = {
.OnPublishSuccess = PublishSuccess,
.OnPublishFail = PublishFailed,
};
return PublishService(PACKAGE_NAME, &info, &cb);
}
static void UnPublishServiceInterface(void)
{
int ret = UnPublishService(PACKAGE_NAME, PUBLISH_ID);
if (ret != 0) {
printf("UnPublishService failed:%d\n", ret);
}
}
static void DeviceFound(const DeviceInfo *device)
{
unsigned int i;
printf("<DeviceFound>CB: Device has found\n");
printf("\tdevId=%s\n", device->devId);
printf("\tdevName=%s\n", device->devName);
printf("\tdevType=%d\n", device->devType);
printf("\taddrNum=%d\n", device->addrNum);
for (i = 0; i < device->addrNum; i++) {
printf("\t\taddr%d:type=%d,", i + 1, device->addr[i].type);
switch (device->addr[i].type) {
case CONNECTION_ADDR_WLAN:
case CONNECTION_ADDR_ETH:
printf("ip=%s,port=%d,", device->addr[i].info.ip.ip, device->addr[i].info.ip.port);
break;
default:
break;
}
printf("peerUid=%s\n", device->addr[i].peerUid);
}
printf("\tcapabilityBitmapNum=%d\n", device->capabilityBitmapNum);
for (i = 0; i < device->addrNum; i++) {
printf("\t\tcapabilityBitmap[%d]=0x%x\n", i + 1, device->capabilityBitmap[i]);
}
printf("\tcustData=%s\n", device->custData);
if (CheckDeviceExist(device)) {
printf("device:%s udid:%s is already in List\n", device->devName, device->devId);
return;
}
SaveDeviceInfo(device);
}
static void DiscoverySuccess(int subscribeId)
{
printf("<DiscoverySuccess>CB: discover subscribeId=%d\n", subscribeId);
}
static void DiscoveryFailed(int subscribeId, DiscoveryFailReason reason)
{
printf("<DiscoveryFailed>CB: discover subscribeId=%d failed, reason=%d\n", subscribeId, (int)reason);
}
static int DiscoveryInterface()
{
SubscribeInfo info = {
.subscribeId = PUBLISH_ID,
.mode = DISCOVER_MODE_ACTIVE,
.medium = COAP,
.freq = LOW,
.isSameAccount = false,
.isWakeRemote = false,
.capability = DEFAULT_CAPABILITY,
.capabilityData = NULL,
.dataLen = 0,
};
IDiscoveryCallback cb = {
.OnDeviceFound = DeviceFound,
.OnDiscoverFailed = DiscoveryFailed,
.OnDiscoverySuccess = DiscoverySuccess,
};
return StartDiscovery(PACKAGE_NAME, &info, &cb);
}
static void StopDiscoveryInterface(void)
{
int ret = StopDiscovery(PACKAGE_NAME, PUBLISH_ID);
if (ret) {
printf("StopDiscovery failed:%d\n", ret);
}
}
static int SessionOpened(int sessionId, int result)
{
printf("<SessionOpened>CB: session %d open result:%d\n", sessionId, result);
if (result == 0) {
g_sessionId = sessionId;
}
return result;
}
static void SessionClosed(int sessionId)
{
printf("<SessionClosed>CB: session %d closed\n", sessionId);
}
static int md5_file_calc(char *filename, char *dest)
{
int i = 0;
int filelen = 0;
int read_len = 0;
char temp[8] = {0};
char hexbuf[128] = {0};
unsigned char decrypt[16] = {0};
unsigned char decrypt32[64] = {0};
MD5_CTX md5;
char fw_path[128];
int fd;
fd = open(filename, O_RDWR);
if (fd < 0)
{
printf("%s not exist\n", filename);
return -1;
}
MD5Init(&md5);
while (1)
{
read_len = read(fd, hexbuf, sizeof(hexbuf));
if (read_len < 0)
{
close(fd);
return -1;
}
if (read_len == 0)
{
break;
}
filelen += read_len;
MD5Update(&md5, (unsigned char *)hexbuf, read_len);
}
MD5Final(&md5, decrypt);
strcpy((char *)decrypt32, "");
for (i = 0; i < 16; i++)
{
sprintf(temp, "%02x", decrypt[i]);
strcat((char *)decrypt32, temp);
}
strcpy(dest, decrypt32);
printf("md5:%s len=%d\n", dest, filelen);
close(fd);
return filelen;
}
static void ByteRecived(int sessionId, const void *data, unsigned int dataLen)
{
//创建文件
FILE *fp = NULL;
FILE *cp = NULL;
int msg_type,ret;
char *content,*file_name;
char *param = NULL;
static int file_length = 0;
char callback[1024] = {0};
static char name[64] = {0};
static bool isFile = false;
if(isFile)//接收文件内容
{
fp = fopen(name,"w");
if (fwrite((const char *)data,file_length,1,fp) == 1)
{
printf("文件 %s 写入成功!\n",name);
fflush(fp);
//执行文件操作指令
cp = popen("/usr/share/tensorflow/lite/examples/label_image/label_image --tflite_model /usr/share/tensorflow/lite/examples/label_image/mobilenet_v1_1.0_224.tflite --labels /usr/share/tensorflow/lite/examples/label_image/labels.txt --image ./hcg.png 2>&1", "r");
fread(callback,1,sizeof(callback)-1,cp);
send_callback(g_sessionId,callback);
}
else
{
printf("文件 %s 写入失败!\n",name);
}
pclose(cp);
fclose(fp);
isFile = false;
}
else//接收json数据
{
cJSON *root = cJSON_Parse((const char *)data);
/*获取消息类型*/
cJSON * msg = cJSON_GetObjectItem(root, TYPE);
msg_type = cJSON_GetNumberValue(msg);
/*获取消息/文件内容*/
msg = cJSON_GetObjectItem(root, CONTENT);
content = cJSON_GetStringValue(msg);
if(msg_type == 1)//处理消息的接收
{
printf("<ByteRecived>CB: msg_type is %d,content is %s\n",msg_type,content);
}
else if(msg_type == 2)//处理文件的接收
{
isFile = true;
/*获取文件名称*/
msg = cJSON_GetObjectItem(root, NAME);
file_name = cJSON_GetStringValue(msg);
strcpy(name, file_name);
/*获取文件长度*/
msg = cJSON_GetObjectItem(root, LENGTH);
file_length = cJSON_GetNumberValue(msg);
printf("<ByteRecived>CB: msg_type is %d,name is %s,file_length is %d,content is %s\n",msg_type,name,file_length,content);
}
else//其他
{
printf("<ByteRecived>CB: msg_type error\n");
}
cJSON_Delete(root);
}
}
static void MessageReceived(int sessionId, const void *data, unsigned int dataLen)
{
printf("<MessageReceived>CB: session %d received %u bytes message=%s\n", sessionId, dataLen, (const char *)data);
}
static int CreateSessionServerInterface(void)
{
const ISessionListener sessionCB = {
.OnSessionOpened = SessionOpened,
.OnSessionClosed = SessionClosed,
.OnBytesReceived = ByteRecived,
.OnMessageReceived = MessageReceived,
};
return CreateSessionServer(PACKAGE_NAME, LOCAL_SESSION_NAME, &sessionCB);
}
static void RemoveSessionServerInterface(void)
{
int ret = RemoveSessionServer(PACKAGE_NAME, LOCAL_SESSION_NAME);
if (ret) {
printf("RemoveSessionServer failed:%d\n", ret);
}
}
static int OpenSessionInterface(const char *peerNetworkId)
{
SessionAttribute attr = {
.dataType = TYPE_BYTES,
.linkTypeNum = 1,
.linkType[0] = LINK_TYPE_WIFI_WLAN_2G,
.attr = {RAW_STREAM},
};
return OpenSession(LOCAL_SESSION_NAME, TARGET_SESSION_NAME, peerNetworkId, DEFAULT_SESSION_GROUP, &attr);
}
static void CloseSessionInterface(int sessionId)
{
CloseSession(sessionId);
}
static int GetAllNodeDeviceInfoInterface(NodeBasicInfo **dev)
{
int ret, num;
ret = GetAllNodeDeviceInfo(PACKAGE_NAME, dev, &num);
if (ret) {
printf("GetAllNodeDeviceInfo failed:%d\n", ret);
return -1;
}
printf("<GetAllNodeDeviceInfo>return %d Node\n", num);
for (int i = 0; i < num; i++) {
printf("<num %d>deviceName=%s\n", i + 1, dev[i]->deviceName);
printf("\tnetworkId=%s\n", dev[i]->networkId);
printf("\tType=%d\n", dev[i]->deviceTypeId);
}
return num;
}
static void FreeNodeInfoInterface(NodeBasicInfo *dev)
{
FreeNodeInfo(dev);
}
static void send_callback(int sessionId ,char *callback)
{
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
if (msg == NULL) {
printf("send_callback: cJSON_CreateObject failed\n");
}
if (cJSON_AddNumberToObject(msg, TYPE, TYPE_MSG) == NULL ||
cJSON_AddStringToObject(msg, NAME, "") == NULL ||
cJSON_AddNumberToObject(msg, LENGTH, 0) == NULL ||
cJSON_AddStringToObject(msg, CONTENT, callback) == NULL)
{
printf("send_callback: cJSON_AddToObject failed\n");
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL)
{
printf("send_callback: cJSON_PrintUnformatted failed\n");
}
SendBytes(sessionId, param, strlen(param) + 1);
printf("send_callback: param is %s\n",param);
cJSON_free(param);
cJSON_Delete(msg);
}
static void md5_file(void)
{
int filelen;
char md5_file[64] = {0};
char md5_str[64] = {0};
printf("请输入需要MD5校验的文件名:");
if(scanf("%s",md5_file))
{
printf("输入完毕!\n");
}
getchar();//过滤回车
filelen = md5_file_calc(md5_file, md5_str);
if (filelen < 0)
{
printf("md5_file: calc_md5 fail\n");
return;
}
}
static void softbus_file(int sessionId)
{
char file_name[64] = {0};
char file_md5[64] = {0};
char *file_data;
FILE *fp = NULL;
int ret, file_size;
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
if (msg == NULL) {
printf("softbus_file: cJSON_CreateObject failed\n");
}
printf("请输入需要传输的文件名:");
if(scanf("%s",file_name)){
printf("输入完毕!\n");
}
getchar();//过滤回车
fp = fopen(file_name, "rb");
file_size = md5_file_calc(file_name, file_md5);
file_data = (char*)malloc((file_size+1)*sizeof(char));
fread(file_data,1,file_size, fp);
file_data[file_size]= '\0';
if (cJSON_AddNumberToObject(msg, TYPE, TYPE_IMG) == NULL ||
cJSON_AddStringToObject(msg, NAME, file_name) == NULL ||
cJSON_AddNumberToObject(msg, LENGTH, file_size) == NULL ||
cJSON_AddStringToObject(msg, CONTENT, "") == NULL)
{
printf("softbus_file: cJSON_AddToObject failed\n");
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL)
{
printf("softbus_file: cJSON_PrintUnformatted failed\n");
}
SendBytes(sessionId, param, strlen(param) + 1);
SendBytes(sessionId, file_data, file_size);
printf("softbus_file: param is %s\n",param);
cJSON_free(param);
cJSON_Delete(msg);
free(file_data);
fflush(fp);
fclose(fp);
}
static void softbus_msg(int sessionId)
{
char message[1024] = {0};
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
if (msg == NULL) {
printf("softbus_msg: cJSON_CreateObject failed\n");
}
printf("请输入需要传输的内容:");
if(scanf("%s",message)){
printf("输入完毕!\n");
}
getchar();//过滤回车
if (cJSON_AddNumberToObject(msg, TYPE, TYPE_MSG) == NULL ||
cJSON_AddStringToObject(msg, NAME, "") == NULL ||
cJSON_AddNumberToObject(msg, LENGTH, 0) == NULL ||
cJSON_AddStringToObject(msg, CONTENT, message) == NULL)
{
printf("softbus_msg: cJSON_AddToObject failed\n");
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL)
{
printf("softbus_msg: cJSON_PrintUnformatted failed\n");
}
SendBytes(sessionId, param, strlen(param) + 1);
printf("softbus_msg: param is %s\n",param);
cJSON_free(param);
cJSON_Delete(msg);
}
static void softbus_test(int sessionId)
{
char cData[] = "PolyOS-Dsoftbus-Test";
cJSON *msg = cJSON_CreateObject();
char *param = NULL;
if (msg == NULL) {
printf("softbus_test: cJSON_CreateObject failed\n");
}
if (cJSON_AddNumberToObject(msg, TYPE, TYPE_MSG) == NULL ||
cJSON_AddStringToObject(msg, NAME, "") == NULL ||
cJSON_AddNumberToObject(msg, LENGTH, 0) == NULL ||
cJSON_AddStringToObject(msg, CONTENT, cData) == NULL)
{
printf("softbus_test: cJSON_AddToObject failed\n");
}
param = cJSON_PrintUnformatted(msg);
if (param == NULL)
{
printf("softbus_test: cJSON_PrintUnformatted failed\n");
}
SendBytes(sessionId, param, strlen(param) + 1);
printf("softbus_test: param is %s\n",param);
cJSON_free(param);
cJSON_Delete(msg);
}
int main(int argc, char **argv)
{
NodeBasicInfo *dev = NULL;
bool loop = true;
int ret,sessionId;
ret = CreateSessionServerInterface();
if (ret) {
printf("CreateSessionServer failed, ret=%d\n", ret);
return ret;
}
ret = PublishServiceInterface();
if (ret) {
printf("PublishService failed, ret=%d\n", ret);
goto err_PublishServiceInterface;
}
ret = DiscoveryInterface();
if (ret) {
printf("DiscoveryInterface failed, ret=%d\n", ret);
goto err_DiscoveryInterface;
}
ret = GetAllNodeDeviceInfoInterface(&dev);
if (ret <= 0) {
printf("GetAllNodeDeviceInfoInterface failed, ret=%d\n", ret);
return ret;
}
g_sessionId = -1;
sessionId = OpenSessionInterface(dev[0].networkId);
if (sessionId < 0) {
printf("OpenSessionInterface fail, ret=%d\n", sessionId);
goto err_OpenSessionInterface;
}
while (loop) {
printf("\n Input t to dsoftbus test, Input k to send file, Input m to send message,Input c to get md5, Input s to stop:");
char op = getchar();
getchar();//过滤回车
switch(op) {
case 'k':
softbus_file(g_sessionId);
continue;
case 'm':
softbus_msg(g_sessionId);
continue;
case 't':
softbus_test(g_sessionId);
continue;
case 'c':
md5_file();
continue;
case 's':
loop = false;
break;
case '\n':
break;
default:
continue;
}
}
StopDiscoveryInterface();
FreeDeviceInfo();
CloseSessionInterface(sessionId);
err_OpenSessionInterface:
FreeNodeInfoInterface(dev);
err_DiscoveryInterface:
UnPublishServiceInterface();
err_PublishServiceInterface:
RemoveSessionServerInterface();
return 0;
}