OpenHarmony之分布式软总线json_payload.c(二)

100 篇文章 3 订阅
100 篇文章 1 订阅

往期知识点记录:

前言

Harmony使用cJSON格式来组织coap设备服务发现数据。在 cJSON介绍 对cJSON主要结构体和接口函数做了介绍。下面将分析Harmony如何利用cJSON组织和解析设备数据。

json_payload.c分析

首先json_payload.c中的主要函数就是准备服务发现数据char *PrepareServiceDiscover(void);和解析服务发现数据int ParseServiceDiscover(const uint8_t *buf, struct DeviceInfo *deviceInfo, char **remoteUrlPtr);。接下来会从这两个函数入手,逐步分析服务发现数据准备过程和解析过程。

准备服务发现数据需要设备信息,ip地址和功能对应的整型数

/*
   函数功能: 准备服务发现信息
   函数返回: JSON转换后的字符串
   详细:
       1. 获取本地设备数据
       2. 创建CJSON对象
       3. 将设备信息,wifi IP和 功能位图添加到CJSON对象
       4. 将JSON对象转换位普通字符串
       5. 当上述过程都成功完成,将cJSON对象转换为字符串,否则删除cJSON对象
*/
char *PrepareServiceDiscover(void)
{
   char *formatString = NULL;
   const DeviceInfo *deviceInfo = GetLocalDeviceInfo(); //获取设备信息
   cJSON *data = NULL;
   //创建cjson对象
   data = cJSON_CreateObject();  //创建头结点,并将头指针指向头结点
   //创建失败
   if (data == NULL) {
       goto L_END_JSON;
   }
   //以JSON格式添加设备信息
   if ((AddDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) || (AddWifiApJsonData(data) != NSTACKX_EOK) ||
       (AddCapabilityBitmap(data, deviceInfo) != NSTACKX_EOK)) {
       goto L_END_JSON;
   }
   //将JSON对象转换为普通的字符串
   formatString = cJSON_PrintUnformatted(data);
   if (formatString == NULL) {
       SOFTBUS_PRINT("[DISCOVERY] PrepareServiceDiscover format fail\n");
   }
L_END_JSON:
   //删除cJSON对象
   if (data != NULL) {
       cJSON_Delete(data);
       data = NULL;
   }
   return formatString;
}

解析与组装正好相反

/*
   函数功能:解析服务发现信息
   函数参数:
           1. buf:  数据缓存区存储接收的服务发现信息
           2. deviceInfo :  用来保存解析出的远端设备信息
           3. remoteUrlPtr : 指向所有远端url
   函数返回值: 成功返回NSTACKX_EOK(0),否则返回非零表示的错误
   详细:
           1.初始化变量(cJSON对象,cJSON数据元素,远端url)
           2.检查各个参数(buf,deviceInfo,remoteUrlPtr)
           3.解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包
           4.解析出设备信息,wifi ip, 功能位图,发布模式,设备hash,服务数据
           5.解析出远端url
*/
int ParseServiceDiscover(const uint8_t *buf, DeviceInfo *deviceInfo, char **remoteUrlPtr)
{
   //远端Url
   char *remoteUrl = NULL;
   cJSON *data = NULL;
   cJSON *item = NULL;
   if (buf == NULL || deviceInfo == NULL || remoteUrlPtr == NULL) {
       return NSTACKX_EINVAL;
   }
   //解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包
   data = cJSON_Parse((char *)buf);
   if (data == NULL) {
       return NSTACKX_EINVAL;
   }
   //解析出设备信息
   if (ParseDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) {
       cJSON_Delete(data);
       return NSTACKX_EINVAL;
   }
   //
   ParseWifiApJsonData(data, deviceInfo);
   ParseCapabilityBitmap(data, deviceInfo);
   ParseModeJsonData(data, deviceInfo);
   ParseDeviceHashData(data, deviceInfo);
   ParseServiceDataJsonData(data, deviceInfo);
   //访问 data对象的JSON_COAP_URI元素
   item = cJSON_GetObjectItemCaseSensitive(data, JSON_COAP_URI);
   if (item != NULL) {
       //判断是否是字符串
       if (cJSON_IsString(item)) {
           //复制远端URL
           remoteUrl = strdup(item->valuestring);
       }
   }
   //释放json对象
   cJSON_Delete(data);
   data = NULL;
   if (remoteUrl == NULL) {
       return NSTACKX_EINVAL;
   }
   *remoteUrlPtr = remoteUrl;
   return NSTACKX_EOK;
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
你可以在图形界面中添加一个复选框(QCheckBox),让用户选择是否需要回传cid。然后在on_submit函数中,根据复选框的状态设置payload中的stream参数,如果复选框被选中,则stream为False,否则为True。具体代码实现如下: ``` def on_submit(self): prompt = self.prompt_edit.toPlainText() question = self.question_edit.toPlainText() api_url = "https://api.devbit.cn/ai/api/ai/chat" api_key = "ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SjBkQ0k2TkN3aVlYVmtJam9pTlRNeE5XTmpZekV3TlRnME5HSTNNVGcyWmpoa09XRTVOVFppTnpGbU5HWWlMQ0pzZFNJNkltZGhiMmhoYjNkbGJpSXNJbVY0Y0NJNk1UWTROVFUwT0RjNU9Td2lkWElpT2pJc0ltcDBhU0k2SWtGUVNWOVVUMHRGVGw4MU16RTFZMk5qTVRBMU9EUTBZamN4T0RabU9HUTVZVGsxTm1JM01XWTBaaTAwSW4wLjM0WWhudzVpblNRVTZROWpkZ0RxRHlCQk1GM2xmN01HYTZBcXZJMV9ydjA=" headers = { "Authorization": "Bearer "+api_key, "Accept": "application/json" } stream = not self.cid_cb.isChecked() # 如果复选框被选中,则stream为False,否则为True payload = { "prompt": prompt, "question": question, "cid": self.cid if self.cid_cb.isChecked() else "", # 如果复选框被选中,则传递cid,否则不传递 "stream": stream } response = requests.post(api_url, json=payload, headers=headers) if response.status_code == 200: print(response.json()) json_response = response.json() self.cid = str(json_response['data']['cid']) self.json_response_edit.setText(str(json_response['data']['answer'])) else: print("Request failed with error code {reaponse.status_code}") self.json_response_edit.setText(f"请求失败,错误码 {response.status_code}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值