博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ril分析三——客户端请求和响应处理与modem交互
阅读量:5990 次
发布时间:2019-06-20

本文共 4108 字,大约阅读时间需要 13 分钟。

    Ril与modem的交互

一 客户端的请求处理

客户端请求从EventLoop通过dispatch传递到reference-ril.c中调用onRequest接口。

  

    

处理客户端请求:

static void onRequest (int request, void *data, size_t datalen, RIL_Token t){     switch (request) {        case RIL_REQUEST_DIAL:            requestDial(data, datalen, t);            break;            ……        }}

 

二 AT Command发送

将客户端请求转化成AT命令:

 

static void requestDial(void *data, size_t datalen, RIL_Token t){    RIL_Dial *p_dial;    char *cmd; //转化成AT命令    p_dial = (RIL_Dial *)data;    asprintf(&cmd, "ATD%s%s;", p_dial->address, clir); //发送AT命令    ret = at_send_command(cmd, NULL);            //请求处理完成回调    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);}

发送AT Command:

static int at_send_command_full_nolock (const char *command,                       ATCommandType type,……){    //将数据写入到mdoem设备文件节点中  err = writeline (command);    //休眠等待写入的数据被读取    while (sp_response->finalResponse == NULL && s_readerClosed == 0) {        err = pthread_cond_wait(&s_commandcond, &s_commandmutex);    }    return err;}

将数据写入modem设备节点中:

static int writeline (const char *s){    //写入数据到设备文件描述符s_fd    while (cur < len) {        do {            written = write (s_fd, s + cur, len - cur);        } while (written < 0 && errno == EINTR);        cur += written;    } //返回行首    do {        written = write (s_fd, "\r" , 1);    } while ((written < 0 && errno == EINTR) || (written == 0));    return 0;}

 

  这样就将数据写入到设备文件描述符s_fd,将AT Command传递给Modem了;

  在数据被读取之前处于休眠状态。数据写入被读取之后,方才返回。

  那么s_fd代表的的设备是如何设置的,读数据又是怎么进行的呢。

三 Modem响应请求处理

  通过AT Command将命令发给了Modem,等待Modem处理此请求,然后将结果返回来,

读取之后进行处理,然后表示此请求Complete,并且通知 Client。

过程如下:

    

 

  这个Serial Prot是什么,Reader Loop是什么呢。回到rild进程main函数中看看。

在rild进程的main函数中:

int main(int argc, char **argv){        //处理客户端请求的模块reference-ril.c    调用RIL_Init    funcs_inst[0] = rilInit(&s_rilEnv, argc, s_argv);     ……}

reference-ril初始化函数:

RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv){    //交互的接口    s_rilenv = env;        //提取modem设备端口或者路径   //此处是d 根据前面属性系统获取参数:rild.libargs=-d /dev/ttyS0  // getopt的使用 提取选项    while ( -1 != (opt = getopt(argc, argv, "p:d:s:c:"))) {        switch (opt) {            case 'd':                s_device_path = optarg;            break;        }    }    //创建线程s_tid_mainloop  ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);    //返回请求交互的接口    return &s_callbacks;}

s_tid_mainloop线程的执行体:

static void *mainLoop(void *param){    at_set_on_reader_closed(onATReaderClosed);    at_set_on_timeout(onATTimeout);    for (;;) {        fd = open (s_device_path, O_RDWR);        s_closed = 0;        ret = at_open(fd, onUnsolicited);        RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);        // Give initializeCallback a chance to dispatched, since        // we don't presently have a cancellation mechanism        sleep(1);        waitForClose();    }}

这里打开了modem的设备文件描述符fd,传递给了at_open():

int at_open(int fd, ATUnsolHandler h){    //与modem设备通信文件描述符    s_fd = fd; //网络端传来事件请求处理onUnsolicited    s_unsolHandler = h;    s_readerClosed = 0; //创建线程s_tid_reader    ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr);    return 0;}

线程执行体readerLoop():

static void *readerLoop(void *arg){    for (;;) {        //从与modem通信设备端口读取数据        line = readline();        if (line == NULL) {            break;        }        //处理数据        processLine(line);    }    onReaderClosed();    return NULL;}

来自Modem端数据处理:

static void processLine(const char *line){    if (sp_response == NULL) {       //来自网络端事件        handleUnsolicited(line);    } else if (isFinalResponseSuccess(line)) {         //客户端请求处理返回        sp_response->success = 1;        handleFinalResponse(line);  }   ……}

来自网络端事件:

static void handleUnsolicited(const char *line){    // 回调接口onUnsolicited    if (s_unsolHandler != NULL) {        s_unsolHandler(line, NULL);    }}

客户端请求处理返回:

static void handleFinalResponse(const char *line){    //保存modem端响应请求所传递的数据    sp_response->finalResponse = strdup(line); //发送signal 唤醒等待s_commandcond的线程——Event Loop    pthread_cond_signal(&s_commandcond);}

 

整个数据流程图如下:

图片来自:http://blog.csdn.net/maxleng/article/details/5576637

你可能感兴趣的文章
Cocos Creator 鼠标事件
查看>>
类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等
查看>>
neo4j图数据库入门
查看>>
内核定时器timer_list
查看>>
VirtualBox - NAT虚拟机访问外网 + Host-Only物理主机虚拟机互访
查看>>
99. Recover Binary Search Tree
查看>>
appium+python自动化32-android_uiautomator定位进阶版
查看>>
《Java 多线程编程核心技术》- 笔记
查看>>
劣质代码评析——《写给大家看的C语言书(第2版)》附录B之21点程序(六)...
查看>>
ashx的学习
查看>>
Installing ODIConsole application using weblogic server
查看>>
hp警告Creating default object from empty value 问题的解决方法
查看>>
C#游戏开发中快速的游戏循环
查看>>
如何高效快捷检索得到核心文献?
查看>>
使用MVC写模式jsp连接到数据库操作
查看>>
模拟电路创新设计
查看>>
win10安装blueCFD
查看>>
C# 计算两个字符串的相似度
查看>>
linux 遇见错误Could not get lock /var/lib/dpkg/lock
查看>>
MySQLdump常用命令
查看>>