1.背景
国家码自适应适配:在设置国家码的时候,我们会先读取协议那边的sim卡内容,根据sim卡字符串,然后去匹配出对应的国家,最后设置到/etc/config/wireless文件中去,那么问题是:协议通知sim卡状态的消息在我们ubus订阅成功之前,也就是说当我们订阅成功对应的ubus事件后,人家协议早就通知过了sim卡状态(开机后只通知一次),所以我们必须去invoke查询sim卡状态消息
注意:
在UBUS中,像这种需要带回返回数据并完成响应操作的状况,我们一般都用同步查询函数,但我开始就选择了异步查询,因为不管查询OK不OK,我国家码肯定是要设置的,查询OK的话,设置对应的国家,不OK的话,我就设置默认,所以现在需要根据原有逻辑完成异步查询且带回返回数据的操作,也算是一个扩展,因为异步查询函数的特点是不需要等待返回数据进行相应操作,所以这个大家注意了。
ubus_subscribe(ctx, obj, id)订阅被订阅者id的消息
ubus_lookup_id(ctx, path, id) 查找被订阅者id
ubus_register_subscriber(ctx, s)添加订阅者s
typedef struct ubus_subscriber ZLINK_UbusSubscriber;定义ubus_subscriber实例并调用ubus_register_subscriber()将其注册到ubusd订阅感兴趣的对象(Object)
typedef struct uloop_timeout ZLINK_UloopTimeout;定时器timeout结构
ubus_strerror(error) ubus错误信息输出接口
blobmsg_get_string(attr) 获取字符串
/*
* 函数功能: Ubus发送异步消息等待结果通过ID
*/
int ZLINK_MSG_UbusInvokeAsyncCompleteById(ZLINK_UbusContext *ctx, unsigned int id,
ZLINK_BlobAttr *msg, const char *method);
/*
* 函数功能: Ubus发送异步消息等待结果通过ID,并携带返回data功能
*/
int ZLINK_MSG_UbusInvokeAsyncCompleteByIdDataCb(ZLINK_UbusContext *ctx, unsigned int id,
ZLINK_BlobAttr *msg, const char *method, ZLINK_UbusReqDataCbInfo *reqDataCb);
/*
* 函数功能: Ubus发送同步消息
*/
int ZLINK_MSG_UbusInvoke(ZLINK_UbusContext *ctx, const char *obj,
ZLINK_BlobAttr *msg, const char *method, ZLINK_UbusInvokeInfo *info);
2.方案及前提
采用异步查询机制进行查询,并带回查询的数据,进行下一步操作
3.实现
这个解析函数是非常有意思的,我们看看实现,数据格式如下:
来,我们定义这个数据格式:
1.先在头文件中定义号对应的枚举变量
2.在.c文件中定义对应的数据格式
/*
*msg结构
*ubus call solution.telesrv tele_srv_get_sim_status
*{
* "response": {
* "setting_response": "OK"
* },
* "tele_srv_ntf_info": {
* "tele_srv_ntf_status": 1,
* "sim_status": 255,
* "sim_bind_available": 0,
* "plmn_change_flg": 0,
* "imsi_change_flg": 0,
* "sim_plmn": ""
* }
*}
*/
/*1.构造json数据格式 :表*/
static const struct blobmsg_policy CooTable[] = {
[RESPONSE] = {
.name = "response",
.type = BLOBMSG_TYPE_TABLE,
},
[TELE_SRV_NTE_INFO] = {
.name = "tele_srv_ntf_info",
.type = BLOBMSG_TYPE_TABLE,
},
};
/*2.构造json数据格式 :表成员*/
static const struct blobmsg_policy Cooinvoke_Response[] = {
[SET_RESPONSE] = {
.name = "setting_response",
.type = BLOBMSG_TYPE_STRING,
},
};
static const struct blobmsg_policy Cooinvoke_Tele[] = {
[TELE_SRV_NTF_STATUS] = {
.name = "tele_srv_ntf_status",
.type = BLOBMSG_TYPE_INT32,
},
[SIM_STATUS] = {
.name = "sim_status",
.type = BLOBMSG_TYPE_INT32,
},
[SIM_BIND_AVAILABLE] = {
.name = "sim_bind_available",
.type = BLOBMSG_TYPE_INT32,
},
[PLMN_CHANGE_FLG] = {
.name = "plmn_change_flg",
.type = BLOBMSG_TYPE_INT32,
},
[IMSI_CHANGE_FLG] = {
.name = "imsi_change_flg",
.type = BLOBMSG_TYPE_INT32,
},
[SIM_PLMN] = {
.name = "sim_plmn",
.type = BLOBMSG_TYPE_STRING,
},
};
/* 解析 wlan_service ubus信息 */
static int WLAN_ParseCountryCodeInvokeSimMsg(Telesrv_Sim *sim_info, ZLINK_BlobAttr *recvBBuf) {
int rc = ZLINK_FAILED;
char *tmp = NULL;
struct blob_attr *tb[ARRAY_SIZE(CooTable)];//1.创建大表
struct blob_attr *subtba[ARRAY_SIZE(Cooinvoke_Response)];//2.创建表内成员
struct blob_attr *subtb[ARRAY_SIZE(Cooinvoke_Tele)];//2.创建表内成员
LOGZ();
if (sim_info == NULL) {
ZLINK_LOG_DEBUG("sim_info is NULL\n");
goto EXIT;;
}
//3.解析入参数据wlanBuf放入大表tb
rc = blobmsg_parse(CooTable, ARRAY_SIZE(CooTable), tb, ZLINK_BlobMsgData(recvBBuf), ZLINK_BlobMsgDataLen(recvBBuf));
ZLINK_LOG_DEBUG("blobmsg_parse tb msg end, rc = %d\n", rc);
if (rc < 0) {
ZLINK_LOG_DEBUG("parse table msg failed, rc = %d\n", rc);
LOGSZ("parse table msg failed");
goto EXIT;
}
if (!tb[RESPONSE]) {
ZLINK_LOG_DEBUG("tb[RESPONSE] is null \n");
LOGSZ("tb[RESPONSE] is null");
goto EXIT;
} else {/*解析值并放入结构sim_info中*/
rc = ZLINK_BlobMsgParse(Cooinvoke_Response, ARRAY_SIZE(Cooinvoke_Response), subtba,
ZLINK_BlobMsgData(tb[RESPONSE]), ZLINK_BlobMsgDataLen(tb[RESPONSE]));
if (rc < 0) {
ZLINK_LOG_DEBUG("parse msg failed, rc = %d\n", rc);
LOGSZ("parse msg failed");
goto EXIT;;
}
if (!subtba[SET_RESPONSE]) {
ZLINK_LOG_DEBUG("tb[WEBSOCKET_MOD_RESPONSE] is NULL\n");
rc = ZLINK_FAILED;
LOGSZ("tb[WEBSOCKET_MOD_RESPONSE] is NULL");
goto EXIT;;
}
if (subtba[SET_RESPONSE]) {
ZLINK_LOG_DEBUG("tb[WEBSOCKET_MOD_RESPONSE] is success\n");
LOGSZ("tb[WEBSOCKET_MOD_RESPONSE] is success");
tmp = blobmsg_get_string(subtba[SET_RESPONSE]);
strncpy_s(sim_info->Setting_Response, CHANN_LENGTH, tmp, strlen(tmp));
LOGSZ(sim_info->Setting_Response);
}
rc = ZLINK_BlobMsgParse(Cooinvoke_Tele, ARRAY_SIZE(Cooinvoke_Tele), subtb,
ZLINK_BlobMsgData(tb[TELE_SRV_NTE_INFO]), ZLINK_BlobMsgDataLen(tb[TELE_SRV_NTE_INFO]));
if (rc < 0) {
ZLINK_LOG_DEBUG("parse msg failed, rc = %d\n", rc);
LOGSZ("parse msg failed=====1============");
goto EXIT;;
} else {
sim_info->Tele_Srv_Ntf_Status = blobmsg_get_u32(subtb[TELE_SRV_NTF_STATUS]);
sim_info->Sim_Status = blobmsg_get_u32(subtb[SIM_STATUS]);
sim_info->Sim_Bind_Available = blobmsg_get_u32(subtb[SIM_BIND_AVAILABLE]);
sim_info->Plmn_Change_Flg = blobmsg_get_u32(subtb[PLMN_CHANGE_FLG]);
sim_info->Imsi_Change_Flg = blobmsg_get_u32(subtb[IMSI_CHANGE_FLG]);
tmp = blobmsg_get_string(subtb[SIM_PLMN]);
strncpy_s(sim_info->Sim_Plmn, CHANN_LENGTH, tmp, strlen(tmp));
LOGDZ(sim_info->Tele_Srv_Ntf_Status);
LOGDZ(sim_info->Sim_Status);
LOGDZ(sim_info->Sim_Bind_Available);
LOGDZ(sim_info->Plmn_Change_Flg);
LOGDZ(sim_info->Imsi_Change_Flg);
LOGSZ(sim_info->Sim_Plmn);
}
}
EXIT:
ZLINK_MemRelease((void**)(&recvBBuf));
return rc;
}
4.验证