希望我学习Android程序时的一点经验能给大家带来帮助,导致WebDeployment出错的原因也许还有很多,不过在你遇到错误时,可以先检查一下你程序中的字符串,暂时把他们置为””,试试看。没准就是他引起的问题啊。
1. onUnsolicite(主动上报响应)
static void onUnsolicited (const char *s, const char *sms_pdu);短信的AT设计真是麻烦的主,以致这个函数的第二个参数完全就是为它准备的。
response 的主要的解析过程,由at_tok.c中的函数完成,其实就是字符串按块解析,具体的解析方式由每条命令或上报信息自行决定。这里不再详述,onUnsolicited只解析出头部(一般是+XXXX的形式),然后按类型决定下一步操作,操作为 RIL_onUnsolicitedResponse和RIL_requestTimedCallback两种。
a)RIL_onUnsolicitedResponse:将 unsolicited的信息直接返回给上层。通过Parcel传递,将 RESPONSE_UNSOLICITED,unsolResponse(request号)写入Parcel先,然后通过 s_unsolResponses数组,查找到对应的responseFunction完成进一步的的解析,存入Parcel中。最终通过 sendResponse将其传递回原进程。
流程:
sendResponse-->sendResponseRaw-->blockingWrite-->write to s_fdCommand(前面建立起来的和上层框架的socket连接)这些步骤之后有一些唤醒系统等其他操作。不再详述。通过event机制(参考文章二)实现的timer机制,回调对应的内部处理函数。
通过internalRequestTimedCallback将回调添加到event循环,最终完成callback上挂的函数的回调。比如pollSIMState,onPDPContextListChanged等回调, 不用返回上层, 内部处理就可以。
2. switch s_type(命令的具体响应)及handleFinalResponse(标准响应)命令的类型(s_type)在send command的时候设置(参考文章二)。
有NO_RESULT,NUMERIC,SINGLELINE,MULTILINE几种,供不同的AT使用。比如AT+CSQ是singleline, 返回at+csq=xx,xx,再加一行OK,比如一些设置命令,就是no_result, 只有一行OK或ERROR。
这几个类型的解析都很相仿,通过一定的判断(比较AT头标记等),如果是对应的响应,就通过 addIntermediate挂到一个临时结果sp_response->p_intermediates队列里。如果不是对应响应,那它其实应该是穿插其中的自动上报,用onUnsolicite来处理。
具体响应,只起一个获取响应信息到临时结果,等待具体分析的作用。无论有无具体响应,最终都得以标准响应handleFinalResponse来完成,也就是接受到OK,ERROR等标准response来结束,这是大多数AT命令的规范。
Android会设置s_commandcond这一object,学习Android程序也就是at_send_command_full_nolock等待的对象。到这里,响应的完整信息已经完全获得,send command可以进一步处理返回的信息了(临时结果,以及标准返回的成功或失败,都在sp_response中)。
可以看到确实是通过at_send_command_singleline来进行的操作,response在p_response中。p_response如果返回失败(也就是标准响应的ERROR等造成),则通过RIL_onRequestComplete发送返回数据给上层,结束命令。如果成功,则进一步分析p_response->p_intermediates, 同样是通过at_tok.c里的函数进行分析。并同样将结果通过RIL_onRequestComplete返回。
RIL_onRequestComplete:
RIL_onRequestComplete和RIL_onUnsolicitedResponse很相仿,功能也一致。
通过Parcel来传递回上层,同样是先写入RESPONSE_SOLICITED(区别于 RESPONSE_UNSOLICITED),pRI->token(上层传下的request号),错误码(send command的错误,不是AT响应)。
学习Android程序如果有AT响应,通过访问pRI->pCI->responseFunction来完成具体 response的解析,并写入Parcel。然后通过同样的途径:完成最终的响应传递。到这里,我们分析了自动上报与命令响应,其实response部分,也就告一段落了。三篇分析RIL的文章也到此结束。
【编辑推荐】