本製品に書込まれているレシピ実行ファイルを、LTE通信により遠隔から変更する仕組み(Over The Air)をレシピで作成する方法を紹介します。
レシピをOver The Air(OTA)で更新することをROTAと示します。
※ROTA機能はベータ版リリースとなります。
ROTA機能の特徴を以下に示します。
ROTA機能を実行するには、本製品に書込まれたレシピ実行ファイル内にROTAの仕組みが含まれていること、変更するレシピ実行ファイル、及びレシピ実行ファイルを配信するためのROTAサーバが必要です。
本製品とROTAサーバとはHTTP GETコマンドで通信を行います。そのため、HTTP GETコマンドに対応したWebサーバである必要があります。
HTTP GETコマンドによる通信はHTTPおよびHTTPSでの通信に対応していますが、セキュリティリスクの観点から閉域網の通信で無い場合は、HTTPSによる暗号化通信を行うことを推奨します。
ROTAサーバに配置するファイル(rcp_info.bin, rcp_prog.bin)は、レシピ言語をビルドして作成された、「rcp_compress.zip」を展開した中身となります。
この2つのファイルをクラウドストレージに保存します。
ROTAの実行を抑制したい場合は、ROTA用のファイル(rcp_info.bin, rcp_prog.bin)を削除することに加えて、「NO_UPDATE」というファイルを置いておくことでROTAの実行を抑制することが出来ます。
ROTAを実行するAPIは以下となります。
API | 内容 | |
---|---|---|
1 | rcplib_KCS_RcpOTA() | ROTAを実行する |
本APIの実⾏により、ROTAが開始されます。
レシピ実行ファイルのダウンロードが完了すると⾃動的に本製品が再起動し、レシピ実行ファイルの更新が実行されます。ダウンロードしたレシピ実行ファイルのタイムスタンプを確認し、現在動作させているものと同じであれば更新は実⾏されません。
rcplib_KCS_RcpOTA(int32 timeout, uint8 sync, uint8 ex_result, str hosturl, uint8 rcv_event_id, str http_header, uint8 protocol, uint8 sni, uint8 auth_mode, uint8 auth_index)
timeout :タイムアウト値[msec] <0:EAPI_TIMEOUT_ZERO>
sync :同期実行 <0:EAPI_SYNC_RESULT>
ex_result :API実行結果 <戻り値>
hosturl :接続先サーバのURL <最大127文字>
rcv_event_id :コールバックを受ける任意のイベントID <1~254>
http_header :HTTPヘッダ指定 <非サポート(NULL)>
protocol :利用する通信プロトコル <MMG_PROTOCOL_HTTPS(HTTP/HTTPS)のみ>
sni :TLS通信利用時のSNI設定 <MMG_SNI_ENABLE(有効)のみ>
auth_mode :TLS通信利用時のmode設定 <MMG_AUTH_SRV(サーバー認証)のみ>
auth_index :認証ID(TLS接続や証明書設定の管理ID) <非サポート("1")>
timeout, sync
APIのタイムアウト設定と実行方法の指定ですが、ここでは両方とも「0」を指定します。
ex_result
ex_resultの戻り値は以下の定義です。
0:成功 (KCS_RCPOTA_RESULT_NO_ERROR)
1:失敗 - 無効なURL (KCS_RCPOTA_RESULT_ERR_INVALID_URL)
2:失敗 - 開始不可 (KCS_RCPOTA_RESULT_ERR_CANNOT_START)
hosturl
接続先のサーバのURL文字列を指定します。HTTP GETでレシピ実行ファイルを取得する際の該当ファイルが保存されているフォルダまでの指定となります。
ex) "http://xxxx.xxxx.com/KC4C-recipe/0001"
※機器ごとに更新するレシピ実行ファイルを変えたい場合などは、URLに特殊なリプレイス文字(*rp_imei*)を付与することで自動的に機器のユニーク番号であるIMEIに置き換える機能を利用する事ができます。
ex) "http://xxxx.xxxx.com/KC4C-recipe/*rp_imei*******/"
↓
"http://xxxx.xxxx.com/KC4C-recipe/012345678901234/"
このAPIではHTTP/HTTPSの区別はurlの先頭部分で行います。このため、http:// 又は、 https:// の指定を意識する必要があります。
rcv_event_id
ROTAのAPIを実行した結果、エラーなど発生した場合の通知を受け取るイベントIDとなります。正しく書き換えが実行された場合は機器がリセットしますので、このイベントは発行されません。
イベントが通知された場合、該当イベントの第一引数(rcplib_TASK_GetArg(0)で取得)には以下の定義のコードが入ります。
resp_code :ROTA開始後に更新完了しない詳細理由
0:成功 - タイムスタンプが同一 (KCS_RCPOTA_RESP_OK)
1:失敗 - 通信エラー/ファイル無し、など (KCS_RCPOTA_RESP_ERR)
2:終了 - NO_UPDATEファイル有 (KCS_RCPOTA_RESP_NO_UPDATE)
3:中断 - FOTA中の中断 (KCS_RCPOTA_RESP_SUSPEND)
4:再開 - FOTA後の再開 (KCS_RCPOTA_RESP_RESUME)
http_header (ベータ版非対応)
非サポートとなるためNULL指定「""」を入力してください。
protocol (ベータ版固定)
プロトコルはHTTP/HTTPSが利用できますがここは「MMG_PROTOCOL_HTTPS」固定で指定してください。HTTP/HTTPSの指定はurlの「http://, https://」で区別します。
sni (ベータ版固定)
TLS通信利用時のSNI設定ですが、MMG_SNI_ENABLEのみ指定可能です。
auth_mode (ベータ版固定)
TLS通信利用時の認証方式はサーバ認証のみ対応です。MMG_AUTH_SRVを指定。
auth_index (ベータ版固定)
TLS接続にかかわる証明書設定してある認証IDを指定しますが、「1」のみ指定可能です。証明書はキッティングツールで書込む「FOTA」用の証明書を利用します。
#incliude "modemMgrTask.h"
#incliude "eventLib.h"
#incliude "bufferLib.h"
~
// 内部非同期イベント
#define UNSYNC_EVENT_INIT 0
#define UNSYNC_EVENT_RECIPE_OTA_RECEIVE 1
// 接続先サーバ設定
#define USER_SETTING_HOST_NAME "http://xxxx.xxxx.com"
#define USER_SETTING_HOST_SUB_URL "/KC4C_test/*rp_imei*******/"
~
// mainループ処理
void main_loop() {
~
// レシピOTAの応答イベント受信時の処理
else if(event_id == UNSYNC_EVENT_RECIPE_OTA_RECEIVE) {
event_recipe_ota_event_receive(rcplib_TASK_GetArg(0));
}
~
// ROTA実行関数
func any_func() {
rcplib_LOG_Print("uapp_1 recipe_ota_exe_proc start");
str ex_result_msg[32];
uint8 ex_result; ex_result = 0;
uint8 ret; ret = 0;
// 接続先URLの文字列 "http://xxxx.xxxx.com/KC4C_test/*rp_imei*******/" を生成
str hosturl[MMG_URL_MAX];
hosturl = USER_SETTING_HOST_NAME;
rcplib_STR_Cat(hosturl, USER_SETTING_HOST_SUB_URL);
// レシピOTAを実行
ret = rcplib_KCS_RcpOTA(
EAPI_TIMEOUT_ZERO,
EAPI_UNSYNC_NORESULT,
ex_result,
hosturl,
UNSYNC_EVENT_RECIPE_OTA_RECEIVE,
"",
MMG_PROTOCOL_HTTPS,
MMG_SNI_ENABLE,
MMG_AUTH_SRV,
1
);
if(ret != 0) {
rcplib_LOG_Print("rcplib_KCS_RcpOTA execute Error!!");
rcplib_FORMAT_String(ex_result_msg, "ex_result:%d", ex_result);
rcplib_LOG_Print(ex_result_msg);
if(ex_result == KCS_RCPOTA_RESULT_NO_ERROR) {
// ret!=0の時、ex_result=0になることはなく、ここに入ることはありません。
rcplib_LOG_Print("KCS_RCPOTA_RESULT_NO_ERROR");
} else if(ex_result == KCS_RCPOTA_RESULT_ERR_INVALID_URL) {
// 接続先サーバのURLの文字列の長さが128文字以上になっている場合のエラー
rcplib_LOG_Print("KCS_RCPOTA_RESULT_ERR_INVALID_URL");
} else if(ex_result == KCS_RCPOTA_RESULT_ERR_CANNOT_START) {
// レシピOTAの実行要求が既に入って、実行中である(多重実行された時)、
// または端末のFirmwareのOTAを実行中であり、レシピOTAの実行が出来ないことを示すエラー
rcplib_LOG_Print("KCS_RCPOTA_RESULT_ERR_CANNOT_START");
}
} else {
rcplib_LOG_Print("rcplib_KCS_RcpOTA execute OK!!");
}
return(0);
}
// レシピOTAの応答イベント
// ※レシピバイナリの更新処理を実行した場合は、このイベントが通知されることなく更新のために端末が再起動されます。
func event_recipe_ota_event_receive(uint16 resp_code) {
str resp_msg[32];
rcplib_LOG_Print("***** RECIPE OTA response event received *****");
rcplib_FORMAT_String(resp_msg, "resp_code:%d", resp_code);
rcplib_LOG_Print(resp_msg);
if(resp_code == KCS_RCPOTA_RESP_OK) {
// 接続先サーバ上からダウンロードしたレシピバイナリのタイムスタンプを確認した結果、現在動作させているものと同じであり、
// 更新処理が必要ないため実行しなかった場合に通知されるイベント
rcplib_LOG_Print("KCS_RCPOTA_RESP_OK");
} else if(resp_code == KCS_RCPOTA_RESP_ERR) {
// 何らかの理由によりレシピOTAの実行に失敗したことを通知されるイベント(通信に失敗した/接続先サーバにファイルが見つからない等)
rcplib_LOG_Print("KCS_RCPOTA_RESP_ERR");
} else if(resp_code == KCS_RCPOTA_RESP_NO_UPDATE) {
// 接続先サーバ上に"NO_UPDATE"ファイルが配置されており、更新処理を実行しなかったことを通知するイベント
rcplib_LOG_Print("KCS_RCPOTA_RESP_NO_UPDATE");
} else if(resp_code == KCS_RCPOTA_RESP_SUSPEND) {
// 端末のFirmwareのOTAが実行され、レシピOTAの処理が中断したことを通知するイベント
rcplib_LOG_Print("KCS_RCPOTA_RESP_SUSPEND");
} else if(resp_code == KCS_RCPOTA_RESP_RESUME) {
// 端末のFirmwareのOTAの実行が終了し、レシピOTAの処理が再開したことを通知するイベント
rcplib_LOG_Print("KCS_RCPOTA_RESP_RESUME");
}
return(0);
}
HTTPSでクラウドストレージにアクセスを行うためには、サーバー証明書(CA証明書)を設定する必要があります。ROTAで利用するサーバー証明書はキッティングツールで書き込むFOTAのサーバ証明書を利用します。ここでは、キッティングツールでの書き込み方を示します。(本リリース版ではFOTAの証明書とROTAの証明書を分ける予定です。)
証明書の書込みは、キッティングツールから行います。
以下の手順でサーバー証明書の書込みをしてください。
設定した証明書は、サンプルコード上の接続先のサーバー設定にて「https://」を指定することで、ここの証明書を使って指定のサーバに接続に行きます。
ボタン押下(1秒以上4秒未満)の契機でROTAの実行をします。利用にあたりいくつかの修正と準備が必要となります。
クラウドストレージ側準備
クラウドストレージには以下のフォルダ構成でファイルを準備しておきます。
/KC4C_test/012345678901234/
- rcp_info.bin
- ucp_prog.bin
※012345678901234の所には、利用機器のIMEIが入ります。
サンプルコード変更
以下のxxxx.xxxx.comの部分をご利用のクラウドストレージのアドレスに変更します。
// 接続先サーバ設定
#define USER_SETTING_HOST_NAME "http://xxxx.xxxx.com"
#define USER_SETTING_HOST_SUB_URL "/KC4C_test/*rp_imei*******/"
上記準備とサンプルコードの変更を行なった後に、ボタン押下(1秒以上4秒未満)を行うことで、ROTAが動きます。成功した場合はレシピが書き変わった後にリセットを行い、書き換えた後のレシピが実行されます。
エラーが発生した場合は、内容がログに出力されますので、ご確認ください。
サンプルコードではボタン押下をトリガーとしていますが、運用の契機としては、MQTTでROTAサーバURLを受信したら受信したURL向けにROTAを実行する等、が考えられます。
各サンプルコードについて動作確認を行っておりますが、全ての環境において動作を保証するものではありません。正しく動作することを確認の上でご利用ください。
対応機種:KC4-C-100A/KC4-C-101A