Android——4.2 - 3G移植之路之 AT 通訊 (四)

來源:互聯網
上載者:User

標籤:3g   at   ril   fd   reference-ril   

   在前文Android——4.2 - 3G移植之路之 reference-ril .pppd 撥接 (三) 中分析了3G串連網路的流程,其中有說道通過AT指令建立串連,

在這裡記錄一下3G中的AT通訊.


                                                                              撰寫不易,轉載請註明出處:http://blog.csdn.net/jscese/article/details/41083363

概念:

 來自AT命令手冊中的概念如下:

 TE

Terminal Equipment
終端裝置 與DTE 等價 比如一個電腦
它是和資訊網路的一端相接的可提供必要功能的裝置 這些功能使得使用者通過接入協議
能接入網路 如發送資訊和接收資訊 也可指由線路 電路 通道 資料鏈路的終端或起點組成的裝置


 TA

Terminal Adapter
終端機介面卡 與DCE 等價
提供終端適配功能的物理實體 是一種介面裝置


 DCE

Data Circuit terminating Equipment
資料電路終接裝置
一種介面裝置 線上路之間進行代碼或訊號轉換 同資料終端設備實現介面 能夠建立
保持和釋放資料終端設備與資料轉送線之間的串連


DTE

Data Terminal Equipment
資料終端設備
它具有向電腦輸入和接收電腦輸出的能力 與資料通訊線路串連的通訊控制能力以
及一定的資料處理能力


 ME

Mobile Equipment
行動裝置 比如GSM 話機就屬於ME
移動台中的一種發射機或接收機或發射機與接收機二者的組合


MS

Mobile Station
移動台
在移動通訊業務中 可以在移動中使用的通訊站 包括車 船 載台便攜台和手持機


AT

即Attention
AT 命令集是從TEDTETADCE  發送的 通過TA ,TE 發送AT 命令來控制MS  的功能 與GSM 網路業務進行互動
使用者可以通過AT 命令進行呼叫 簡訊 電話本 資料業務 補充業務 傳真等方面的控制

這裡只是應用到android裝置(TE)與3G模組(TA)之間的通訊

不同晶片的3G模組所支援的AT 指令集會有差異,具體需要查看對應規格書.



角色:

 在前文 Android——RIL 機制源碼分析 中知道:

android電話系統的ril驅動檔案目錄是在源碼/hardware/ril下,其中包含:

rild— ril主體控制機制,

libril— ril與上層socket通訊,

reference-ril— ril與serial裝置AT指令通訊

這三個檔案夾,其中reference-ril是第三方驅動,根據不同的裝置選擇不同.

也就是說 AT 指令就是我們android 裝置與 需要移植的第三方的3G裝置之間的 最終通訊的橋樑

具體實現存在與reference-ril檔案中的atchannel.c 中,最終編譯成第三方的動態庫。



實現:

 前文中知道當3G裝置通過usb-modeswitch之後出現的/dev/ttyUSB*時,reference-ril.c中的mainLoop 就會檢測到,然後跳出loop:

static void *mainLoop(void *param){    int fd;    int ret;... else if (s_device_path != NULL) {                fd = open (s_device_path, O_RDWR);                if ( fd >= 0 && !memcmp( s_device_path, "/dev/tty", 8 ) ) {   //可以看到這裡的篩選                    /* disable echo on serial ports */                    struct termios  ios;                    tcgetattr( fd, &ios );                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */                   if( cfsetispeed( &ios, B115200) != 0 )                       ALOGE("Failed to set in speed");                   if ( cfsetospeed( &ios, B115200) != 0 )                       ALOGE("Failed to set out speed");                    tcsetattr( fd, TCSANOW, &ios );   ALOGI("[%s] jscese _display in reference listener device insert  path== %s \n",__func__,s_device_path);                }            }            if (fd < 0) {                perror ("opening AT interface. retrying...");                sleep(10);                /* never returns */            }        }        s_closed = 0;        ret = at_open(fd, onUnsolicited); // 這裡初始化,傳了上面的裝置的檔案描述符fd,開啟 AT 傳回值的讀取        if (ret < 0) {            ALOGE ("AT error %d on at_open\n", ret);            return 0;        }           RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0); //這裡會調用到initializeCallback 函數進行初始化AT指令的發送        // Give initializeCallback a chance to dispatched, since        // we don't presently have a cancellation mechanism        sleep(1);        waitForClose();        ALOGI("Re-opening after close");    }}


前文at_open 幹了啥都有分析,這裡就不提了,解析下initializeCallback函數:


/** * Initialize everything that can be configured while we're still in * AT+CFUN=0 */static void initializeCallback(void *param){    ATResponse *p_response = NULL;    int err;    setRadioState (RADIO_STATE_OFF);    at_handshake();    /* note: we don't check errors here. Everything important will       be handled in onATTimeout and onATReaderClosed */    /*  atchannel is tolerant of echo but it must */    /*  have verbose result codes */    at_send_command("ATE0Q0V1", NULL); //決定是否回顯字元 ATE0就是不回顯,ATE1反之    /*  No auto-answer */    at_send_command("ATS0=0", NULL);   //自動應答,很明顯這裡不自動    /*  Extended errors */    at_send_command("AT+CMEE=1", NULL); //報告行動裝置的錯誤。這個命令決定允許或不允許用結果碼 “+CME ERROR:<xxx>”或者 “+CMS  ERROR:<xxx>”代替簡單的“ERROR”。    /*  Network registration events */    err = at_send_command("AT+CREG=2", &p_response);  //網路註冊。獲得手機的註冊狀態    ALOGI("[%s] jscese AT  Network registration events err== %d \n",__func__,err);    /* some handsets -- in tethered mode -- don't support CREG=2 */    if (err < 0 || p_response->success == 0) {        at_send_command("AT+CREG=1", NULL);    }    at_response_free(p_response);    /*  GPRS registration events */    at_send_command("AT+CGREG=1", NULL); //初始化GPRS模組    /*  Call Waiting notifications */    at_send_command("AT+CCWA=1", NULL); //插撥    /*  Alternating voice/data off */    at_send_command("AT+CMOD=0", NULL); // 配置交替模式呼叫 single mode...#endif /* USE_TI_COMMANDS */    /* assume radio is off on error */    if (isRadioOn() > 0) {        setRadioState (RADIO_STATE_SIM_NOT_READY);    }    ALOGI("[%s] jscese ============= AT  INIT OVER =============\n",__func__);}

可以看到AT指令的組成 大部分使用 AT+*** 組成,具體支援那些AT指令,需要看對應晶片的AT手冊,那樣才是最權威可靠的因為不同廠家的會有出入,而且還有一些自訂AT指令!


atchannel.c中實現at_send_command ,最終調用到的地方:

** * Internal send_command implementation * Doesn't lock or call the timeout callback * * timeoutMsec == 0 means infinite timeout */static int at_send_command_full_nolock (const char *command, ATCommandType type,                    const char *responsePrefix, const char *smspdu,                    long long timeoutMsec, ATResponse **pp_outResponse){    int err = 0;...    err = writeline (command); //寫命令,上面有提到,往初始化AT時傳進來的fd,我這裡也就是dev/ttyUSB2...    sp_response = at_response_new();  //置空 全域的response,這個指標由processLine(line)函數引導去維護,processLine用來處理at_open 時開啟的readerLoop 中讀取到的response...    while (sp_response->finalResponse == NULL && s_readerClosed == 0) { //等待一下 response        if (timeoutMsec != 0) {#ifdef USE_NP            err = pthread_cond_timeout_np(&s_commandcond, &s_commandmutex, timeoutMsec);#else            err = pthread_cond_timedwait(&s_commandcond, &s_commandmutex, &ts);#endif /*USE_NP*/        } else {            err = pthread_cond_wait(&s_commandcond, &s_commandmutex);        }        if (err == ETIMEDOUT) {            err = AT_ERROR_TIMEOUT;            goto error;        }    }    if (pp_outResponse == NULL) {        at_response_free(sp_response);    } else {        /* line reader stores intermediate responses in reverse order */        reverseIntermediates(sp_response);        *pp_outResponse = sp_response;    }    sp_response = NULL;  // 重設... }}

再往下最終就可以看到 write 以及 read 代表裝置檔案/dev/ttyUSB* 的fd了.



shell調試:

 可使用 cat /dev/ttyUSB*  &

 查詢這個裝置檔案的值

echo “AT+**”  > /dev/ttyUSB*   寫入指令




Android——4.2 - 3G移植之路之 AT 通訊 (四)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.