SORACOM Developers

Documents

SORACOM Beam機能詳細

当ガイドでは、SORACOM Beam(以下、Beam)について技術面から詳細に解説します。

Beamについて

Beamは、IoT デバイスにかかる暗号化等の高負荷処理や接続先の設定を、クラウドにオフロードできるサービスです。Beamはデバイスから受け取ったデータを暗号化した上で外部に送信してくれますのでキャパシティの小さなデバイスに負担をかけることなく、また、多数のデバイスに暗号化のための設定を施したりすることなく、安全なデータ送信環境をつくることができます。サービスに概要についてはSORACOM Beamを併せてご覧ください。

当ドキュメントでは以下の項目について記載します。

エントリポイント

Beamは以下のスクリーンショットのようにグループに対して設定をすることによって、そのグループに所属しているSIMから利用することができます。

configuration

デバイスからみたBeamのURLはエントリポイントと呼ばれ、以下の種類のエントリポイントが提供されています。なお、それぞれの種類のエントリポイントはひとつのグループに対して並列で設定することができます。

ここから先はそれぞれのエントリポイントについてより詳細に解説していきます。

HTTPエントリポイント

デバイスからHTTPリクエストを受け付け、HTTPもしくはHTTPSで転送先へリクエストを転送します。このエントリポイントは、設定項目のひとつであるパス(Beamエントリポイントの受付パス)がかぶらない限り、複数のエントリポイントを作成することができます。

エントリポイントURL

http://beam.soracom.io:8888/${ご自身で設定したパス}

設定項目

動作

リクエスト

Beamはオリジナルのリクエストに対してConnectionヘッダにcloseを設定してリクエストを転送します。

レスポンス

Beamは転送先から返されたHTTPレスポンスをそのままデバイスに返します。

実際の利用例

以下、送信するデータの形式にJSONを選択した場合のデータ送信例です。

$ curl -v -XPOST -H 'Content-Type:application/json' -d '{"key":"value"}' http://beam.soracom.io:8888/
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 100.127.127.100...
* Connected to beam.soracom.io (100.127.127.100) port 8888 (#0)
> POST / HTTP/1.1
> Host: beam.soracom.io:8888
> User-Agent: curl/7.49.0
> Accept: */*
> Content-Type:application/json
> Content-Length: 15
>
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Wed, 21 Dec 2016 02:25:01 GMT
< Connection: close
< Transfer-Encoding: chunked
<
* Closing connection 0

Webサイトエントリポイント

デバイスからHTTPリクエストを受け付け、HTTPもしくはHTTPSで転送先へリクエストを転送します。HTTPエントリポイントとの違いはパスを予め固定的に決めておく必要がないということです。例えばhttp://beam.soracom.io:18080/path/to/targethttps://${TARGET}/path/to/targetへ転送されます。

エントリポイントURL

http://beam.soracom.io:18080

設定項目

挙動はHTTPエントリポイントと同じなので、リクエストやレスポンス、実際の利用例は割愛します。

MQTTエントリポイント

MQTTのPublish、Subscribeを転送先となるMQTTブローカーに転送します。MQTTブローカーからのメッセージのPublishもデバイスに対して転送します。

エントリポイントURL

beam.soracom.io:1883

設定項目

Publish

mosquittoを使ってデバイスからbeamへ実際にPublishしてみます。

デバイス側

$ mosquitto_pub -h beam.soracom.io -p 1883 -t test -m message -d
Client mosqpub/82534-MBP sending CONNECT
Client mosqpub/82534-MBP received CONNACK
Client mosqpub/82534-MBP sending PUBLISH (d0, q0, r0, m1, 'test', ... (7 bytes))
Client mosqpub/82534-MBP sending DISCONNECT

転送先のMQTTブローカー

1482290763: New connection from 52.198.245.54 on port 8080.
1482290763: New client connected from 52.198.245.54 as mosqpub/82534-MBP (c1, k60).
1482290763: Sending CONNACK to mosqpub/82534-MBP (0, 0)
1482290767: Received PUBLISH from mosqpub/82534-MBP (d0, q0, r0, m0, 'test/4401031********', ... (7 bytes))
1482290767: Received DISCONNECT from mosqpub/82534-MBP
1482290767: Client mosqpub/82534-MBP disconnected.

この試験ではIMSI付与をオンにしているのでトピックの末尾にIMSIが付与されているのが確認できます。(ドキュメントに載せるため、後半8桁をマスクしています。)

Subscribe

mosquittoを使ってデバイスからbeamへ実際にSubscribeし、転送先のMQTTブローカーからメッセージをPublishしてみます。

デバイスからのSubscribe

$ mosquitto_sub -h beam.soracom.io -p 1883 -t test -d
Client mosqsub/82586-MBP sending CONNECT
Client mosqsub/82586-MBP received CONNACK
Client mosqsub/82586-MBP sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 0)
Client mosqsub/82586-MBP received SUBACK
Subscribed (mid: 1): 0

Subscribeを受ける転送先MQTTブローカー

1482291094: New connection from 52.198.245.54 on port 8080.
1482291094: New client connected from 52.198.245.54 as mosqsub/82586-MBP (c1, k60).
1482291094: Sending CONNACK to mosqsub/82586-MBP (0, 0)
1482291094: Received SUBSCRIBE from mosqsub/82586-MBP
1482291094:     test (QoS 0)
1482291094: mosqsub/82586-MBP 0 test
1482291094: Sending SUBACK to mosqsub/82586-MBP

MQTTブローカーに別のクライアントからメッセージをPublish

1482291169: New connection from 127.0.0.1 on port 8080.
1482291169: New client connected from 127.0.0.1 as mosqpub/3516-ip-10-0-0- (c1, k60).
1482291169: Sending CONNACK to mosqpub/3516-ip-10-0-0- (0, 0)
1482291169: Received PUBLISH from mosqpub/3516-ip-10-0-0- (d0, q0, r0, m0, 'test', ... (7 bytes))
1482291169: Sending PUBLISH to mosqsub/82586-MBP (d0, q0, r0, m0, 'test', ... (7 bytes))
1482291169: Received DISCONNECT from mosqpub/3516-ip-10-0-0-
1482291169: Client mosqpub/3516-ip-10-0-0- disconnected.

PublishされたメッセージをBeam経由でデバイスが受け取る様子

Client mosqsub/82586-MBP received PUBLISH (d0, q0, r0, m0, 'test', ... (7 bytes))
message

TCP → TCP/TCPSエントリポイント

TCP上で送信されたデータをTCPパケットもしくはTCPSパケットとして転送先に送信します。

エントリポイントURL

beam.soracom.io:8023

設定項目

実際の利用例

署名ヘッダ付与(IMSI と IMEI 両方が有効)の場合、最初の行として以下が送信されます。

imei=XXXXXXXX7613276 imsi=XXXXXXXX4074449 timestamp=1496832866258;signature=XXXXXXXXXXXXXXXXXXXX8d0e32a8df182c4bd48d21287fdb1275e37d108eb2b4 version=20151001

TCP → HTTP/HTTPSエントリポイント

TCP上で送信されたデータをクラウドサービスに送信します。

エントリポイントURL

beam.soracom.io:23080

設定項目

リクエスト

Beamは送信されたメッセージをBase64エンコードしたうえで以下のようなJSONにし、HTTP POSTリクエストのボディに設定します。

{"payload":"Base64エンコードされたメッセージ"}

TCP上で送信されたデータをクラウドサービスに送信します。なお、HTTPヘッダのuser_agentには“SORACOM Beam"という文字列が設定されます。

レスポンス

TCPにはHTTPのようなリクエスト&レスポンスの概念はありませんので、下記のBodyに記述されているコードやメッセージをペイロードとして含んだTCPパケットがエントリポイントから送信されます。フォーマットは以下のようになります。レスポンス送信のタイミングは、転送先サーバーからのレスポンスに基づきます。

${HTTP_STATUS_CODE} ${転送先から返されたHTTPレスポンスのボディ}

実際の利用例

# BeamエントリポイントとのTCPセッションの確立
$ nc -v funnel.soracom.io 23080
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif en0
    src 192.168.43.232 port 51053
    dst 100.127.65.43 port 23080
    rank info not available
    TCP aux info available

Connection to funnel.soracom.io port 23080 [tcp/*] succeeded!

ボディのないレスポンス例 200

ボディのあるレスポンス例 400 Message from server

UDP → HTTP/HTTPSエントリポイント

デバイスから送信されたUDPの1パケット(厳密には1UDPデータグラム)を1つのHTTPリクエストとして転送先に送信します。

エントリポイントURL

beam.soracom.io:23080

設定項目

リクエスト

Beamは送信されたメッセージをBase64エンコードしたうえで以下のようなJSONにし、HTTP POSTリクエストのボディに設定します。

{"payload":"Base64エンコードされたメッセージ"}

1メッセージあたりの最大送信データサイズは1つのUDPデータグラムで送信できるペイロード長と等しくなります。

レスポンス

UDPにはHTTPのようなリクエスト&レスポンスの概念はありませんので、下記のBodyに記述されているコードやメッセージをペイロードとして含んだTCPパケットがエントリポイントから送信されます。フォーマットは以下のようになります。レスポンス送信のタイミングは、転送先サーバーからのレスポンスに基づきます。

${HTTP_STATUS_CODE} ${転送先から返されたHTTPレスポンスのボディ}

実際の利用例

ボディのないレスポンス例

$ echo "test message" | nc -v -u beam.soracom.io 23080
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif (null)
    src 192.168.43.232 port 61852
    dst 100.127.127.100 port 23080
    rank info not available

Connection to beam.soracom.io port 23080 [udp/*] succeeded!

200

ボディのあるレスポンス例

$ echo "bad message" | nc -v -u beam.soracom.io 23080
found 0 associations
found 1 connections:
     1: flags=82<CONNECTED,PREFERRED>
    outif (null)
    src 192.168.43.232 port 61852
    dst 100.127.127.100 port 23080
    rank info not available

Connection to beam.soracom.io port 23080 [udp/*] succeeded!

400 Message from server

LoRa → HTTP/HTTPSエントリポイント

LoRa デバイスからの Uplink データを HTTP もしくは HTTPS で転送先へリクエストを転送します。このエントリポイントは1つのLoRaグループに対して1個だけ作成することができます。

※LoRaデバイスから使えるBeamエントリポイントはこのエントリポイントだけです。他のエントリポイントはAir for Cellularのみ対応しています。

エントリポイント

LoRaWANの場合、エントリポイントをデータ送信元で意識する必要はありません。LoRaグループでBeamを有効化すると自動的にエントリポイントにデータが送信されます。

設定項目

リクエスト

Beamはオリジナルのリクエストに対してConnectionヘッダにcloseを設定、HTTPメソッドはPOST、ペイロードフォーマットはJSONとしてリクエストを転送します。

このとき、自動的にデータ送信時刻をHTTPヘッダ x-soracom-operator-id: オペレータID ならびに x-soracom-timestamp: #{unixtime(msec)} として付与します。

サンプルheader

SORACOM Beamの設定直後の状態

x-soracom-timestamp: 1494817070730
x-soracom-operator-id: YOUR_OPERATOR_ID
connection: close

SORACOM Beamの設定 "ヘッダ操作” 内で設定した場合

設定内容;

x-soracom-timestamp: 1494817070730
x-soracom-lora-device-id: YOUR_LORA_DEVEUI
x-soracom-operator-id: YOUR_OPERATOR_ID
x-add-custom: foobar
x-soracom-signature: 2b6f5126922ace000a88c6df92519acd252364b194b8e1ab3e6a70f29a6ce9a4
x-soracom-signature-version: 20151001
connection: close

サンプルbody

※実際はcompactなJSONで送信されます

{
    "date": "2017-05-15T02:39:59.886193",
    "gatewayData": [
        {
            "date": "2017-05-15T02:39:59.886193",
            "rssi": -35,
            "snr": 12,
            "gwid": "000b78fffeb00006",
            "channel": 923200000
        }
    ],
    "data": "7b2274223a32352e35307d",
    "deveui": "YOUR_LORA_DEVEUI"
}

body内の data について

SORACOM Air for LoRaWAN から SORACOM Beam を通過した場合、実データ(ペイロード)は JSON内の data にASCIIによるHEXデータ表現で格納されています (Arduino library for LoRaWAN Deviceを使用した場合。2017年4月現在)
そのため、実際に利用する場合はデコードが必要です

各言語におけるデコード例

Python 2.7

raw_data = '7b2274223a32352e35307d'.decode('hex')
#=> {"t":25.50}

Perl

$raw_data =  pack("H*", "7b2274223a32352e35307d")
#=> {"t":25.50}

Ruby

raw_data = ["7b2274223a32352e35307d"].pack("H*")
#=> {"t":25.50}

レスポンス

転送先から返されたHTTPレスポンスはBeamに到達した際に破棄されます。LoRaゲートウェイ/デバイスではHTTPレスポンスを受け取ることはできません。

転送先からエラーレスポンスが返却された場合には、エラーの内容がログとして記録されます。エラーログは、ユーザコンソールの「ログ」画面から確認できます。

Beamが付与する署名ヘッダと事前共有鍵について

仕様

Air for Cellular で通信している場合

署名は下記のように計算され、X-Soracom-Signatureとしてリクエストに付与されます。

SHA256(${事前共有鍵文字列}+x-soracom-imei=${IMEI}x-soracom-imsi=${IMSI}x-soracom-timestamp=${TIMESTAMP})

例えば下記のような前提条件の場合

事前共有鍵: topsecret
IMSI: 440101111111111
IMEI: 1111122222333333
TIMESTAMP: 1445587157992

具体的には以下のように計算されます。

SHA256('topsecret'+'x-soracom-imei=1111122222333333x-soracom-imsi=440101111111111x-soracom-timestamp=1445587157992')

IMEI を含めない場合は、以下のように計算されます。

SHA256('topsecret'+'x-soracom-imsi=440101111111111x-soracom-timestamp=1445587157992')

検証方法

BeamのHTTPエントリポイントをhttps://beamtest.soracom.io:443/ に設定したうえで署名ヘッダを付与してリクエストを行うと実際の動作の様子が下記のように確認できます。

$ curl beam.soracom.io:8888
Hello SORACOM Beam Client 4401031******** !

== HTTP Headers ==
HTTP_X_SORACOM_IMEI = 3545660********
HTTP_X_SORACOM_IMSI = 4401031********
HTTP_X_SORACOM_SIGNATURE = ccc2594804064311344a46e880465b27992750a6a3fdf19463fefa584becf5b1
HTTP_X_SORACOM_SIGNATURE_VERSION = 20151001
HTTP_X_SORACOM_TIMESTAMP = 1482303563385

= Signature Verification =
Pre shared key = topsecret

stringToSign:
x-soracom-imei=3545660********x-soracom-imsi=4401031********x-soracom-timestamp=1482303563385

calculated_signature:
SHA256('topsecret'+stringToSign) = ccc2594804064311344a46e880465b27992750a6a3fdf19463fefa584becf5b1

provided_signature:
ccc2594804064311344a46e880465b27992750a6a3fdf19463fefa584becf5b1

signature:
Match!

Air for LoRaWAN で通信している場合

LoRaWANで通信している場合も同様に署名は下記のように計算されます。署名はX-Soracom-Signatureとしてリクエストに付与されます。

SHA256(${事前共有鍵文字列}+x-soracom-lora-device-id=${LoRa device id}x-soracom-timestamp=${timestamp})

例えば下記のような前提条件の場合

事前共有鍵: topsecret
LoRa device id: 000b78fffe000001
timestamp: 1492414740191

具体的には以下のように計算されます。

SHA256('topsecret'+'x-soracom-lora-device-id=000b78fffe000001x-soracom-timestamp=1492414740191')

UDP, TCP -> HTTP/HTTPS エントリポイントでステータスコードを返さないオプション

UDP -> HTTP/HTTPS, TCP -> HTTP/HTTPS エントリポイントの設定では、ステータスコードを返さないオプションが利用できます。この設定は、エントリポイントの設定画面から切り替えられます。

当オプションをOFFにしている場合、以下のようにレスポンスとしてHTTPステータスコードが返ってきます。

$ nc -u beam.soracom.io 23080
{"message":"Hello SORACOM Beam via UDP!"} [Enter]
200

一方、当オプションをONとした場合は、以下のようにステータスコードが返りません。

$ nc -u beam.soracom.io 23080
{"message":"Hello SORACOM Beam via UDP!"} [Enter]

例えば Input プロトコルに UDP を利用した場合で、いわゆる Fire-and-Forget のユースケースを実現する場合、サーバ側からの応答を完全に無しにできます。

また、サーバからのレスポンスでデバイスにメッセージを送りたい場合など、ステータスコード部分を外すパース処理する必要がなくなり、処理を簡略化できます。

Getting Started

SORACOM Air for セルラー

SORACOM Air for LoRaWAN

SORACOM Air for Sigfox

SORACOM Beam

SORACOM Canal/Direct/Door

SORACOM Endorse

SORACOM Funnel

SORACOM Gate

SORACOM Harvest

SORACOM Inventory

SORACOM Junction

サービス機能詳細

Developer Tools

pagetop