7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

libqmiにQMIのメッセージを追加する

Last updated at Posted at 2016-04-27

APN接続以前の問題

以前にL-03DをRaspberry Piに接続した時は、そもそもLTE serviceStatusavailableにならなかった。この状態では、いくら--wds-start-networkしたところで、APNに接続されない。と思われる。
何が足らないのか。

解析

L-03Dの動きを見る

前回、動いているUSBモデムのQMIメッセージを確認するシステムが構築できたので、これをL-03Dで使ってみる。
実際確認してみると…QMIのメッセージ、いっぱい流れすぎですよ。どれが効果あるか、わかりませんですよ。
ただ、qmicliのコマンドラインオプションを変えて色々試してみたところでは、全く効果がなかったので、libqmiで対応していないメッセージの可能性がある。APN接続のwdsの前に送るメッセージだろうから、ネットワークのnasか。
具体的には、service = "nas"で、message =に説明が入っていないもの、を探す。そのようなメッセージは3種類:

0x003a

QMUX:
  length  = 27
  flags   = 0x80
  service = "nas"
  client  = 1
QMI:
  flags       = "indication"
  transaction = 0
  tlv_length  = 15
  message     = (0x003a)
TLV:
  type   = 0x10
  length = 12
  value  = XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX

0x0026

QMUX:
  length  = 12
  flags   = 0x00
  service = "nas"
  client  = 1
QMI:
  flags       = "none"
  transaction = 29
  tlv_length  = 0
  message     = (0x0026)

0x0023

QMUX:
  length  = 16
  flags   = 0x00
  service = "nas"
  client  = 2
QMI:
  flags       = "none"
  transaction = 27
  tlv_length  = 4
  message     = (0x0023)
TLV:
  type   = 0x10
  length = 1
  value  = 01

正解は

  • 0x003aは、indicationとのことで、ホストからの命令でなさそうなので、除外
  • 0x0026は、responseに長い情報が入っており、get系の命令か?
  • 0x0023は、これを送った後に、
QMUX:
  length  = 67
  flags   = 0x80
  service = "nas"
  client  = 1
QMI:
  flags       = "indication"
  transaction = 0
  tlv_length  = 55
  message     = "Serving System" (0x0024)

で通知される内容が、

TLV:
  type       = "Serving System" (0x01)
  length     = 6
  value      = 00:02:02:02:01:08
  translated = [ registration_state = 'not-registered' cs_attach_state = 'detached' ps_attach_state = 'detached' selected_network = '3gpp' radio_interfaces = '{ [0] = 'lte '}' ]

から、最終的に

TLV:
  type       = "Serving System" (0x01)
  length     = 6
  value      = 01:02:01:02:01:08
  translated = [ registration_state = 'registered' cs_attach_state = 'detached' ps_attach_state = 'attached' selected_network = '3gpp' radio_interfaces = '{ [0] = 'lte '}' ]

に、変化する。故に、0x0023が本命。
後で追加するのは面倒なので、0x0026も同時に追加しておくか。

QMIメッセージの追加実装

メッセージフォーマット

libqmiではQMIのメッセージフォーマットはjsonで記述されている。

data/qmi-service-nas.json
--- a/data/qmi-service-nas.json
+++ b/data/qmi-service-nas.json
@@ -582,6 +582,19 @@
      "output"  : [  { "common-ref" : "Operation Result" } ] },

   // *********************************************************************************
+  {  "name"    : "X0023",
+     "type"    : "Message",
+     "service" : "NAS",
+     "id"      : "0x0023",
+     "version" : "1.0",
+     "input"   : [  { "name"          : "X10",
+                      "id"            : "0x10",
+                      "mandatory"     : "no",
+                      "type"          : "TLV",
+                      "format"        : "guint8" } ],
+     "output"  : [  { "common-ref" : "Operation Result" } ] },
+
+  // *********************************************************************************
   {  "name"    : "Get Serving System",
      "type"    : "Message",
      "service" : "NAS",
@@ -1099,6 +1112,19 @@
                                         "public-format" : "gboolean" } ] } ] },

   // *********************************************************************************
+  {  "name"    : "X0026",
+     "type"    : "Message",
+     "service" : "NAS",
+     "id"      : "0x0026",
+     "version" : "1.0",
+     "output"  : [  { "common-ref" : "Operation Result" },
+                    { "name"      : "X11",
+                      "id"        : "0x11",
+                      "mandatory" : "no",
+                      "type"      : "TLV",
+                      "format"    : "string" } ] },
+
+  // *********************************************************************************
+  
   {  "name"    : "Set Technology Preference",
      "type"    : "Message",
      "service" : "NAS",

inputには、requestで渡すパラメーターを、outputには、responseで受け取るパラメーターを記載できる。
responseのid=0x02は、Operation Resultとして、あらかじめdata/qmi-common.jsonで定義されている。

処理の追加

コマンドラインオプションの追加

src/qmicli/qmicli-nas.c
--- a/src/qmicli/qmicli-nas.c
+++ b/src/qmicli/qmicli-nas.c
@@ -46,6 +46,8 @@ static gboolean get_signal_strength_flag;
 static gboolean get_signal_info_flag;
 static gchar *get_tx_rx_info_str;
 static gboolean get_home_network_flag;
+static gboolean x0023_flag;
+static gboolean x0026_flag;
 static gboolean get_serving_system_flag;
 static gboolean get_system_info_flag;
 static gboolean get_technology_preference_flag;

これらは、コマンドラインオプションを格納しておく変数。

  • _flagは、パラメーター無しオプションが設定された時に立つフラグ
  • _strは、パラメーター付きオプションのパラメーター文字列
src/qmicli/qmicli-nas.c
@@ -75,6 +77,14 @@ static GOptionEntry entries[] = {
       "Get home network",
       NULL
     },
+    { "nas-0x0023", 0, 0, G_OPTION_ARG_NONE, &x0023_flag,
+      "Message ID 0x0023",
+      NULL
+    },
+    { "nas-0x0026", 0, 0, G_OPTION_ARG_NONE, &x0023_flag,
+      "Message ID 0x0026",
+      NULL
+    },
     { "nas-get-serving-system", 0, 0, G_OPTION_ARG_NONE, &get_serving_system_flag,
       "Get serving system",
       NULL

ここで、コマンドラインオプションの文字列, その種類, オプションを格納する変数, ヘルプ文字列を定義。

src/qmicli/qmicli-nas.c
@@ -150,6 +160,8 @@ qmicli_nas_options_enabled (void)
                  get_signal_info_flag +
                  !!get_tx_rx_info_str +
                  get_home_network_flag +
+                 x0023_flag +
+                 x0026_flag +
                  get_serving_system_flag +
                  get_system_info_flag +
                  get_technology_preference_flag +

ここでコマンドラインオプションが設定されたか、チェックしているらしい。
ここへの追加を忘れたら、いくらオプションを設定しても、反映されなかった。

src/qmicli/qmicli-nas.c
@@ -488,6 +500,87 @@ get_signal_strength_ready (QmiClientNas *client,
     operation_shutdown (TRUE);
 }

## メッセージ本体の作成

+static QmiMessageNasX0023Input *
+x0023_input_create (void)
+{
+    GError *error = NULL;
+    QmiMessageNasX0023Input *input;
+
+    input = qmi_message_nas_x0023_input_new ();
+    if (!qmi_message_nas_x0023_input_set_x10 (
+            input,
+            0x01,
+            &error)) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n",
+                    error->message);
+        g_error_free (error);
+        qmi_message_nas_x0023_input_unref (input);
+        input = NULL;
+    }
+
+    return input;
+}
+

0x0023のrequestは、TLVが1つ付いている。この場合は、_create()でメッセージ作成関数を作り、この中で、_new()_set()を行い、inputで指されるTLV付きrequestメッセージオブジェクトを作成する。
不要になったオブジェクトは、_unref()で解放。

src/qmicli/qmicli-nas.c
+static void
+x0023_ready (QmiClientNas *client,
+             GAsyncResult *res)
+{
+    QmiMessageNasX0023Output *output;
+    GError *error = NULL;
+
+    output = qmi_client_nas_x0023_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_nas_x0023_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't message ID 0x0023: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_nas_x0023_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully message ID 0x0023\n",
+             qmi_device_get_path_display (ctx->device));
+
+    qmi_message_nas_x0023_output_unref (output);
+    operation_shutdown (TRUE);
+}
+

responseを受け取った時のコールバック関数は、_ready()で定義。_finish()でresponse全体を取得、_get_result()で中身の結果を取得。

src/qmicli/qmicli-nas.c
+static void
+x0026_ready (QmiClientNas *client,
+             GAsyncResult *res)
+{
+    QmiMessageNasX0026Output *output;
+    GError *error = NULL;
+
+    output = qmi_client_nas_x0026_finish (client, res, &error);
+    if (!output) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    if (!qmi_message_nas_x0026_output_get_result (output, &error)) {
+        g_printerr ("error: couldn't message ID 0x0026: %s\n", error->message);
+        g_error_free (error);
+        qmi_message_nas_x0026_output_unref (output);
+        operation_shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully message ID 0x0023\n",
+             qmi_device_get_path_display (ctx->device));
+
+    qmi_message_nas_x0026_output_unref (output);
+    operation_shutdown (TRUE);
+}
+
 static void
 get_tx_rx_info_ready (QmiClientNas *client,
                       GAsyncResult *res,

0x0026のほうは、requestにTLVが無いので、_ready()のコールバックのみ定義。

src/qmicli/qmicli-nas.c
@@ -3005,6 +3098,40 @@ qmicli_nas_run (QmiDevice *device,
         return;
     }

+    /* Request message ID 0x0023? */
+    if (x0023_flag) {
+        QmiMessageNasX0023Input *input;
+
+        input = x0023_input_create ();
+
+        if (!input) {
+            operation_shutdown (FALSE);
+            return;
+        }
+
+        g_debug ("Asynchronously message ID 0x0023...");
+        qmi_client_nas_x0023 (ctx->client,
+                              input,
+                              10,
+                              ctx->cancellable,
+                              (GAsyncReadyCallback)x0023_ready,
+                              NULL);
+        qmi_message_nas_x0023_input_unref (input);
+        return;
+    }
+
+    /* Request message ID 0x0026? */
+    if (x0026_flag) {
+        g_debug ("Asynchronously message ID 0x0026...");
+        qmi_client_nas_x0026 (ctx->client,
+                              NULL,
+                              10,
+                              ctx->cancellable,
+                              (GAsyncReadyCallback)x0026_ready,
+                              NULL);
+        return;
+    }
+
     /* Request to get serving system? */
     if (get_serving_system_flag) {
         g_debug ("Asynchronously getting serving system...");

コマンドラインオプションに応じ、メッセージの作成し、qmi_client_nas_()など、jsonから自動生成されたlibqmiのAPIを呼び出す。

結果

# qmicli -d /dev/cdc-wdm0 --nas-get-system-info
[/dev/cdc-wdm0] Successfully got system info:
	GSM service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	WCDMA service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	LTE service:
		Status: 'limited'
		True Status: 'limited-regional'
		Preferred data path: 'no'
		Domain: 'unknown'
		Service capability: 'cs-ps'
		Roaming status: 'off'
		Forbidden: 'no'
		Location Area Code: 'xx'
		Cell ID: 'xxxxxxxx'
		MCC: '440'
		MNC: '10'
		Tracking Area Code: '0'
		Voice support: 'yes'
# qmicli -d /dev/cdc-wdm0 --nas-0x0023
[/dev/cdc-wdm0] Successfully message ID 0x0023
# qmicli -d /dev/cdc-wdm0 --nas-get-system-info
[/dev/cdc-wdm0] Successfully got system info:
	GSM service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	WCDMA service:
		Status: 'none'
		True Status: 'none'
		Preferred data path: 'no'
	LTE service:
		Status: 'available'
		True Status: 'none'
		Preferred data path: 'no'
		Domain: 'ps'
		Service capability: 'ps'
		Roaming status: 'off'
		Forbidden: 'no'
		Location Area Code: 'xxxxx'
		Cell ID: 'xxxxxxxx'
		MCC: '440'
		MNC: '10'
		Tracking Area Code: 'xxxx'
		Voice support: 'yes'

はい、LTEがlimitedからavailableに。

次回

最終章、Raspberry PiとUSBモデムでLTEのIPv4/IPv6デュアルスタックの世界。
IoTのご時世なのに、遠すぎだよこの世界…。

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?