物模型接口示例(属性对应回调),云存储封面bug
·
改进前:
// 全量校验:所有属性都必须存在,缺一个就失败
int Zlink_SetIotPro(const PropertySet *all_props, int prop_count)
{
// 必须包含所有属性才算成功
if (prop_count != PROP_TOTAL_COUNT) {
log_error("property count mismatch: got %d, expect %d\n",
prop_count, PROP_TOTAL_COUNT);
return -1; // App只请求了2个属性 → 直接失败!
}
// 全部通过才处理
for (int i = 0; i < prop_count; i++) {
process_property(&all_props[i]);
}
return 0;
}
改进后:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// ============ 属性定义 ============
typedef enum {
PROP_COVER_URL = 0, // 封面URL
PROP_COVER_STATUS = 1, // 封面状态
PROP_PLAY_URL = 2, // 播放地址
PROP_STORAGE_TYPE = 3, // 存储类型
PROP_RECORD_MODE = 4, // 录像模式
PROP_TOTAL_COUNT = 5 // 属性总数
} PropertyID;
// 属性数据结构
typedef struct {
PropertyID id;
char value[256];
} Property;
// ============ 各属性的独立处理函数 ============
// 获取封面URL
int get_cover_url(char *buf, int buf_len)
{
snprintf(buf, buf_len, "https://cloud.zte.com/cover/2024/xxx.jpg");
printf(" [处理] 获取封面URL: %s\n", buf);
return 0;
}
// 获取封面状态
int get_cover_status(char *buf, int buf_len)
{
snprintf(buf, buf_len, "ready");
printf(" [处理] 获取封面状态: %s\n", buf);
return 0;
}
// 获取播放地址
int get_play_url(char *buf, int buf_len)
{
snprintf(buf, buf_len, "rtsp://192.168.1.100:554/live");
printf(" [处理] 获取播放地址: %s\n", buf);
return 0;
}
// 获取存储类型
int get_storage_type(char *buf, int buf_len)
{
snprintf(buf, buf_len, "cloud");
printf(" [处理] 获取存储类型: %s\n", buf);
return 0;
}
// 获取录像模式
int get_record_mode(char *buf, int buf_len)
{
snprintf(buf, buf_len, "event");
printf(" [处理] 获取录像模式: %s\n", buf);
return 0;
}
// ============ 核心:属性-函数映射表 ============
// 函数指针类型
typedef int (*PropGetFunc)(char *buf, int buf_len);
// 映射表:属性ID → 对应的处理函数
typedef struct {
PropertyID id;
const char *name;
PropGetFunc get_func; // 获取函数
// 也可以加 set_func 用于下发
} PropMapEntry;
// 映射表定义(新增属性只需加一行)
static PropMapEntry prop_map_table[PROP_TOTAL_COUNT] = {
{ PROP_COVER_URL, "cover_url", get_cover_url },
{ PROP_COVER_STATUS, "cover_status", get_cover_status },
{ PROP_PLAY_URL, "play_url", get_play_url },
{ PROP_STORAGE_TYPE, "storage_type", get_storage_type },
{ PROP_RECORD_MODE, "record_mode", get_record_mode },
};
// ============ 重构后的接口:按需调用 ============
// 改造后的接口:只处理App请求的属性
int Zlink_SetIotPro(const PropertyID *req_ids, int req_count,
Property *out_props, int *out_count)
{
*out_count = 0;
// 遍历App请求的每一个属性
for (int i = 0; i < req_count; i++) {
PropertyID id = req_ids[i];
// 越界检查
if (id < 0 || id >= PROP_TOTAL_COUNT) {
log_error("unknown property id: %d\n", id);
continue; // 跳过未知属性,不影响其他属性
}
// 查映射表,调用对应函数
PropMapEntry *entry = &prop_map_table[id];
out_props[*out_count].id = id;
int ret = entry->get_func(out_props[*out_count].value,
sizeof(out_props[*out_count].value));
if (ret == 0) {
printf(" 属性[%s] 获取成功\n", entry->name);
(*out_count)++;
} else {
printf(" 属性[%s] 获取失败\n", entry->name);
}
}
return (*out_count > 0) ? 0 : -1;
// 只要有至少一个属性成功就返回成功
// 不再要求全量通过
}
// ============ 测试 ============
int main(void)
{
// 场景1:App只请求封面相关的2个属性(之前会失败,现在成功)
printf("=== 场景1:App只请求封面URL和封面状态 ===\n");
PropertyID req1[] = { PROP_COVER_URL, PROP_COVER_STATUS };
Property out1[PROP_TOTAL_COUNT];
int out1_count = 0;
int ret1 = Zlink_SetIotPro(req1, 2, out1, &out1_count);
printf("结果: ret=%d, 获取到%d个属性\n\n", ret1, out1_count);
// 场景2:App请求全部属性
printf("=== 场景2:App请求全部属性 ===\n");
PropertyID req2[] = { PROP_COVER_URL, PROP_COVER_STATUS, PROP_PLAY_URL,
PROP_STORAGE_TYPE, PROP_RECORD_MODE };
Property out2[PROP_TOTAL_COUNT];
int out2_count = 0;
int ret2 = Zlink_SetIotPro(req2, 5, out2, &out2_count);
printf("结果: ret=%d, 获取到%d个属性\n", ret2, out2_count);
return 0;
}
更多推荐

所有评论(0)