この記事には多数の理論が含まれていますが、実践は2番目の記事で行います。
無線インターフェース層の説明
英語-Radio Interface Layerのいわゆる無線インターフェースのレイヤーを考えてください。 Android OSでは、テレフォニーサービス(android.telephony)とモデム間の抽象的なレイヤーを表します。

図1.無線インターフェースのレイヤー。
図1では、無線インターフェイスの赤い層が強調表示されています。
- 無線インターフェースのJavaレイヤー。
- RILデーモン。
- イベントプランナー。
- RILメーカー。
エアインターフェースレイヤーのコンポーネントは、次のタスクを実行します。
Java Radio Interface Layer (Java RIL)は、ローカルLinuxソケット/ dev / socket / rildを介してRIL要求をデーモンに送信します。 Java RILソースは/telephony/java/com/android/internal/telephony/gsm/RIL.javaファイルにあります。
RILデーモンは、プロデューサーRILとイベントスケジューラをロードして初期化します。 RILデーモンのソースコードは、/ hardware / ril / rild /ディレクトリにあります。
イベントスケジューラは、要求されたコマンドと非請求コマンドを処理します。 これは、RIL JavaとRIL製造業者の間の仲介者です。 イベントスケジューラのソースコードは/ hardware / ril / libril /ディレクトリにあります。
メーカーのRILはモデムを初期化し、モデムと直接対話します。 製造元のRILは、モデムの製造元によって開発された動的ライブラリです。 開発テンプレートは/ hardware / ril / reference-ril /ディレクトリにあります。 現在、モバイルデバイス用のモデムの最も人気のあるメーカーはIntelとQualcommであり、ライブラリのソースコードは利用できません。
RILデーモンの内部構造
図2は、RILデーモンの内部構造を示しています。 RILデーモンのタスクは、OSの起動時に無線インターフェイスのレイヤーを初期化することです。 少量のRILデーモンコードを調べたところ、次のアルゴリズムに従って動作していることがわかります。
1.システム設定から、メーカーRILへのパス(rild.libpath)およびメーカーRILが使用するシステムプロパティを読み取ります。
2.メーカーRILをロードし、イベントスケジューラでイベントループを開始します。
3. RIL_Init関数を呼び出して、製造元のRIL関数への参照を初期化および取得します。
4.イベントプランナーがRIL_register関数を呼び出して、製造元のRIL関数への参照を登録します。

図2. RILデーモンの内部構造。
無線インターフェイスレイヤのコンポーネント間の相互作用には、要請コマンドと非要請コマンドの2種類があります。 要求されたコマンドは、インターネット接続を確立する発信コールなどのテレフォニーサービスによって開始されます。 未承諾コマンドは、モデムによって開始されます。たとえば、着信SMSメッセージ、着信コールなどです。
テレフォニーサービスとイベントプランナーの関係
Java RILとイベントスケジューラ間の相互作用は、ローカルLinuxソケット/ dev / socket / rildを介して発生します 。 ライブラリレベルへの各リクエストは、 com.android.internal.telephony.RILRequestクラスのインスタンスに書き込まれ、無線インターフェースの基礎となるレイヤーからレスポンスが受信されるまで、リクエストに関する情報を保存します。
リクエストパラメータはパーセル構造に書き込まれ、リクエスト自体はcom.android.internal.telephony.RIL.RILSenderクラスに送信されます。 リクエストの形式は次の図に示されています。

com.android.internal.telephony.RIL.RILReceiverクラスはローカルLinuxソケットをリッスンし、イベントスケジューラからの応答を待ちます。 RILReceiverは、要求と非請求の2種類の応答を受け取ります。 それらの形式を以下の図に示します。

図4.要求された応答の形式。

図5.未承諾応答の形式。
RILメーカーの実装
メーカーのRILを実装するために、モデムのメーカーは、Androidオペレーティングシステムがモデム宛のリクエストを処理するために必要な多くの機能を実装する動的ライブラリを開発しています。 その名前は、次の規則で定義されています。libril- <会社名>-<RILのバージョン> .so
ヘッダーファイル/include/telephony/ril.hには以下が含まれます。
- 多くの構造の説明。たとえば、RIL_RadioState、RIL_Data_Call_Response。
- 関数プロトタイプ、例えば:RIL_Init、RIL_onRequestComplete;
- 要求されたコマンドと非請求コマンドの数値定義。例:#define RIL_REQUEST_SETUP_DATA_CALL 27。
エアインターフェースレイヤーはハードウェアに依存せず、製造元のRILは任意のプロトコルを使用してモデムと対話できます。 原則として、多くの標準化されたHayes ATコマンドが使用されますが、一部のモデムメーカーは独自の拡張機能でATコマンドの標準セットを補完します。
要求されたコマンドを管理するには、モデムの製造元が一連の機能を実装する必要があります。そのプロトタイプを以下に説明します。 要求されたコマンドの要求タイプは、ril.hヘッダーファイルでプレフィックスRIL_REQUEST_で定義されます。
これは、要求されたコマンドを処理するための機能です。 ヘッダーファイルril.hで定義され、プレフィックスRIL_REQUEST_で始まる要求されたコマンドを処理します。void (*RIL_RequestFunc)(int request,void *data, size_t datalen,RIL_Token t)
RIL_RadioState (*RIL_RadioStateRequest)()
int (*RIL_Supports)(int requestCode)
void (*RIL_Cancel)(RIL_Token t)
const char * (*RIL_GetVersion) (void)
製造元のRILは、次のコールバックを使用してRILデーモンと通信します。
void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen)
void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime)
RIL製造元が非送信請求コマンドを実行するために使用するコールバック関数は、次のようになります。
void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t datalen);
要求されたコマンド
61チームが要求されています。 次のようにグループ化できます。
- SIMカード、入力/出力、デバイスの一意の識別子(11)を使用します。
- 呼び出しステータスと処理(16);
- ネットワーク状態(4);
- ネットワーク設定(12);
- SMSメッセージ(3);
- パケットデータプロトコルを使用した接続(4);
- 電源と再起動(2);
- 追加サービス(5);
- メーカーの定義とサポート(4)。
図6は、要求されたコマンド「インターネット接続の確立」を受信したときの、無線インターフェース層のさまざまなレベルでの呼び出しのシーケンスを示しています。
1. RIL JavaはRILSender.handleMessage()を呼び出し、ローカルLinuxソケット/ dev / socket / rild経由でグループ化された引数を使用してイベントスケジューラを送信します。
2.イベントプランナーは、listenCallback()、processCommandCallback()、proccessCommandBuffer()を順番に呼び出し、データを前処理して、ディスパッチ(要求コード)を呼び出します。
3.製造元のRILで、OnRequest()関数が呼び出されます。この関数では、アクションコード(SETUP_DATA_CALL)が将来実行するアクションを決定します。 製造元のRILは、要求に対応するモデムに一連のATコマンドを送信し、それらに対する応答を受信します。 OnRequestComplete()関数を呼び出して、要求コードの処理を終了します。 必要に応じて、イベントプランナーに応答を送信します。
4.イベントスケジューラは、製造元RILからの応答を処理し、応答(要求コード)関数を呼び出し、Java RIL応答を送信します。
5. RIL Javaは、RILReceiver.run()メソッドを使用して応答を受け入れます。

図6.要求されたコマンド。
非請求コマンド
次のようにグループ化された11の非請求チームがあります。
- ネットワーク状態の変化(4);
- 着信SMSメッセージ(3);
- 着信USSD通知(2);
- 信号強度または時間の変化(2)。

図7.非請求コマンド。
図7は、未承諾の「着信SMSメッセージ」コマンドを受信したときの無線インターフェイスレイヤーのさまざまなレベルでの呼び出しシーケンスを示しています。
1. AT応答はモデムから送信され、メーカーのRILはそれを読み取り、対応する関数ハンドラーを呼び出します。 製造元のRILは、イベントプランナーに送信するデータを準備します。 OnUnsolicitedResponse()を呼び出して処理を終了します。
2.イベントスケジューラは、応答とともに送信されたデータを処理し、ローカルLinuxソケット/ dev / socket / rildを介してJava RIL応答を送信します。
3. RIL Javaは、RILReceiver.run()を使用して応答を受け入れます。
次の記事では、モデムと直接対話するための独自のプログラムの作成方法と、この方法で達成できることについて説明する予定です。
記事を書くとき、次のものが使用されました。
1. Android OSソースコードandroid.googlesource.com
2.dpsm.wordpress.com/2010/09/01/smart-phones-are-still-phones
3.www.netmite.com/android/mydroid/development/pdk/docs/telephony.html
4.www.slideshare.net/ssusere3af56/android-radio-layer-interface