6, reference-ril-->Modem
reference-ril.c中调用流程图如下,
onRequest方法中会处理所有消息,但是处理流程完全一样, 以RIL_REQUEST_DIAL消息为例来论述消息的处理, onRequest中相关代码如下,
case RIL_REQUEST_DIAL:
requestDial(data, datalen, t);
break;
另一方面,有些消息需要回调给ril,然后到RILJ。
default:
RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
break;
首先看回调的消息, RIL_onRequestComplete定义如下,
static const struct RIL_Env *s_rilenv;
#define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
#define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
#define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
该回调消息后面会论述。
requestDial方法如下,
static void requestDial(void *data, size_t datalen __unused, RIL_Token t)
{
RIL_Dial *p_dial;
char *cmd;
const char *clir;
int ret;
p_dial = (RIL_Dial *)data;
switch (p_dial->clir) {
case 1: clir = "I"; break; /*invocation*/
case 2: clir = "i"; break; /*suppression*/
default:
case 0: clir = ""; break; /*subscription default*/
}
asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);//封装AT指令
ret = at_send_command(cmd, NULL);//继续发送
free(cmd);
/* success or failure is ignored by the upper layer here.
it will call GET_CURRENT_CALLS and determine success that way */
RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);//回调
}
at_send_command方法如下,
int at_send_command (const char *command, ATResponse **pp_outResponse)
{
int err;
err = at_send_command_full (command, NO_RESULT, NULL, NULL, 0, pp_outResponse);
return err;
}
at_send_command_full_nolock方法逻辑如下,
1,调用writeline方法通过串口将数据发送到Modem
2, 阻塞当前线程,等待Modem回应.
3,将回应发送给请求的AT线程。
首先论述第一步,在下个章节中论述第二步和第三步。
at_send_command_full_nolock方法有关代码如下,
err = writeline (command);
writeline方法如下,
static int writeline (const char *s)
{
size_t cur = 0;
size_t len = strlen(s);
ssize_t written;
if (s_fd < 0 || s_readerClosed > 0) {
return AT_ERROR_CHANNEL_CLOSED;
}
RLOGD("AT> %s\n", s);
AT_DUMP( ">> ", s, strlen(s) );
/* the main string */
while (cur < len) {
do {
//s_fd就是Modem与RILC之间的串口
written = write (s_fd, s + cur, len - cur);
} while (written < 0 && errno == EINTR);
if (written < 0) {
return AT_ERROR_GENERIC;
}
cur += written;
}
/* the \r */
do {
written = write (s_fd, "\r" , 1);//以换行结尾
} while ((written < 0 && errno == EINTR) || (written == 0));
if (written < 0) {
return AT_ERROR_GENERIC;
}
return 0;
}
这样,通过串口的方式,将数据从reference-ril发送到Modem了。
s_fd串口是在reference-ril的读取子线程(读Modem)中打开的,然后通过at_open方法赋值给atchannel.c的s_fd,将会在下一章中论述。
小结:这一章比较简单,以RIL_REQUEST_DIAL消息为例论述了reference-ril将消息通过串口发送给modem的流程。
通过这三个章节,数据终于从RILJ发送到Modem了。Modem往上发送消息都要分为2大类,稍微麻烦一些。