MSP430F5529 + CC3100 IOTテストデバイスは一部のテストWebサイトにのみ応答します


8

最近、テキサスインスツルメンツのMSP430F5529マイクロコントローラーとCC3100ネットワークプロセッサーを使用してIoTプロジェクトに取り組んでいます。評価には、MSP430F5529ランチパッドとCC3100ブースターパックを使用しています。デバイスをクラウドに接続しようとしています。私は、www.openweathermap.orgに接続するCC3100 天気情報サンプルアプリケーションを正常に実装しました。これは、CC3100 SDKサンプルアプリケーションの例です。プログラムは、www.openweathermap.org Webサイトから正常に受信して応答します。アプリケーションは、GETメソッドを使用してWebサイトからリクエストを行います。

また、www.mocky.ioに対するコードのテストにも成功しています。デバイスは、ステータスコード200 OK応答を受信します。しかし、requestb.inテストサイトに対してテストすると、408タイムアウトエラー応答コードも、302のURLリダイレクト応答コードも取得できません。

#define WEATHER_SERVER  "api.openweathermap.org"
#define TEST_SERVER  "requestb.in"
//#define TEST_SERVER  "www.mocky.io"

#define PREFIX_BUFFER   "GET /data/2.5/weather?q="
#define POST_BUFFER     "&APPID=xxxxxxxxxxxxxxxxxx&mode=xml&units=imperial HTTP/1.1\r\nHost:api.openweathermap.org\r\nAccept: */"
#define POST_BUFFER2    "*\r\n\r\n"

#define PREFIX_BUFFER_TEST    "GET /1m75pgt1"
#define POST_BUFFER_TEST_1    " HTTP/1.1\r\nHost:requestb.in\r\nAccept: */"
#define POST_BUFFER_TEST_2    "\r\n\r\n"*

//#define PREFIX_BUFFER_TEST      "GET /v2/5967a65d1100007d16b6c2b4"
//#define POST_BUFFER_TEST_1    " HTTP/1.1\r\nHost:www.mocky.io\r\nAccept: */"
//#define POST_BUFFER_TEST_2    "\r\n\r\n"*

以下は、いくつかの設定条件を含むメインです。一部のエラー処理コードは、簡潔にするために削除されています。

 int main(int argc, char** argv)
{
    _i32 retVal = -1;

    retVal = initializeAppVariables();
    ASSERT_ON_ERROR(retVal);



    /* Stop WDT and initialize the system-clock of the MCU */
    stopWDT();
    initClk();


    /*
     * Following function configures the device to default state by cleaning
     * the persistent settings stored in NVMEM (viz. connection profiles &
     * policies, power policy etc)
     *
     * Applications may choose to skip this step if the developer is sure
     * that the device is in its default state at start of application
     *
     * Note that all profiles and persistent settings that were done on the
     * device will be lost
     */
    retVal = configureSimpleLinkToDefaultState();


    /*
     * Assumption is that the device is configured in station mode already
     * and it is in its default state
     */
    retVal = sl_Start(0, 0, 0);

    /* Connecting to WLAN AP */
    retVal = establishConnectionWithAP();

    retVal = getCredentials();

    retVal = disconnectFromAP();

    return 0;
}

以下は、get dataを呼び出すgetCredentials()コードです。

<!-- language: lang-c -->
static _i32 getCredentials()
{
    _i32 retVal = -1;

    pal_Strcpy((char *)g_DeviceData.HostName, TEST_SERVER);

    retVal = getHostIP_Device();

    g_DeviceData.SockID = createConnection();
    ASSERT_ON_ERROR(g_DeviceData.SockID);

    retVal = getData();
    ASSERT_ON_ERROR(retVal);

    retVal = sl_Close(g_DeviceData.SockID);
    ASSERT_ON_ERROR(retVal);

    return 0;
}

以下は、エラーが発生するgetdata()関数です。

/*!
    \brief This function Obtains the required data from the server

    \param[in]      none

    \return         0 on success, -ve otherwise

    \note

    \warning
*/
static _i32 getData()
{
    _u8 *p_startPtr = NULL;
    _u8 *p_endPtr = NULL;
    _u8* p_bufLocation = NULL;
    _i32 retVal = -1;

    pal_Memset(g_DeviceData.Recvbuff, 0, sizeof(g_DeviceData.Recvbuff));

    /* Puts together the HTTP GET string. */
    p_bufLocation = g_DeviceData.SendBuff;

    pal_Strcpy(p_bufLocation, PREFIX_BUFFER_TEST);
    p_bufLocation += pal_Strlen(PREFIX_BUFFER_TEST);

    pal_Strcpy(p_bufLocation, POST_BUFFER_TEST_1);
    p_bufLocation += pal_Strlen(POST_BUFFER_TEST_1);

    pal_Strcpy(p_bufLocation, POST_BUFFER_TEST_2);

    /* Send the HTTP GET string to the open TCP/IP socket. */
    retVal = sl_Send(g_DeviceData.SockID, g_DeviceData.SendBuff, pal_Strlen(g_DeviceData.SendBuff), 0);
    if(retVal != pal_Strlen(g_DeviceData.SendBuff))
        ASSERT_ON_ERROR(HTTP_SEND_ERROR);

    /* Receive response */
    retVal = sl_Recv(g_DeviceData.SockID, &g_DeviceData.Recvbuff[0], MAX_SEND_RCV_SIZE, 0);
    if(retVal <= 0)
        ASSERT_ON_ERROR(HTTP_RECV_ERROR);

    g_DeviceData.Recvbuff[pal_Strlen(g_DeviceData.Recvbuff)] = '\0';
    return SUCCESS;
}

アクセスポイントのセキュリティは、

#define SEC_TYPE        SL_SEC_TYPE_WPA_WPA2    /* Security type of the Access point */

最後に、データをクラウドに転送する必要があるCC3100で製造されたPOCセンサーデバイスはほとんどありません。簡単にするために、ブースターパックを使用していますが、最終的には、POCセンサーデバイスをWifi経由でクラウドと通信させる必要があります。


質問の実際の問題は基本的なHTTPの使用に関するものであり、特定の組み込みプラットフォームであって、モノのインターネットではないため、他のHTTPの質問に対する共通点のプールであるため、私はこの質問をトピック外として閉じることに投票します。まず、実際には他のIoTの質問にはまったく対応していません。
クリスストラットン

1
ちなみに、コード内の特定のrequestb.inインスタンスは明らかにタイムアウトしており、SNIを使用したHTTP over TLS経由でアクセスすると、404が現在有効なものとして機能します。
クリスストラットン2017

@mico、私はあなたがあなたの答えを削除したことに気づきました。また、httpに「s」を追加することについて言及しました。どうすればあなたの提案を実現できるかわかりません。少し教えていただけませんか。
user8055 2017

@ChrisStratton、この質問を閉じるために投票することを聞いて申し訳ありません。この質問をするのに適したQ&Aサイトを勧めてもらえますか?
user8055 2017

あなたはそれらの302と408メッセージを受け取りますか?そうでない場合、どのようなメッセージが表示されますか?
mico 2017

回答:


5

違いは、requestb.inサイトにはSNIを使用したHTTP over TLSが必要なためです。

これはかなり複雑なHTTP / HTTPS プロトコルであり、セキュリティの質問はおそらくSEシステムの他の場所でより適切に対処され、最終的に行う可能性のあるIoTプロジェクトではなく、主にテスト対象のサービスの詳細に関するものです。しかし、それがここに残っている限り...requestb.in


ポート80でHTTPを試行するときのrequestb.in応答コードのデバッグ

あなたが言った:

しかし、requestb.inテストサイトに対してテストすると、408タイムアウトエラー応答コードも、302のURLリダイレクト応答コードも取得できません。

しばらく様子を見てみましょう:

curl -i http://requestb.in/xxxxxxxx
HTTP/1.1 301 Moved Permanently
Location: https://requestb.in/xxxxxxxx

HTTPステータス301は「永久に移動」ですが、予想していた302は一時的なリダイレクトに使用されることがあります。彼らはおそらくポート80上のプレーンTCPソケットでHTTPを使用することを許可する予定はないので、彼らが送信する永続的なリダイレクトはより正しい応答です。

送信されなかった2つだけをリストするのではなく、送信されたステータスコードをキャプチャした方がはるかに役立ちます。

とにかく、サーバーが言っていることは、HTTPSを使用する必要があるということです。


では、HTTPS経由でサーバーに接続するには何をする必要がありますか?

基本的なレベルでは、HTTPSは単純なTCPソケットではなく、TLS(または以前はSSL)で保護された接続を介してHTTPを話すことを意味します。

あなたのCC3100は、TLSとSSLをサポートし、代わりに安全なチャネルを作ることによって、HTTPS接続を実行するためのSDKのHTTPクライアントの例の1つを変更に関するいくつかの最小限の情報がで、利用可能がありますhttp://processors.wiki.ti.com/index.php / CC3100_HTTP_Client

ただし、requestb.inこれでは十分でない場合があります。

非常に単純なGETリクエストをopensslのs_clientコマンドにパイプする場合(またはCC3100で同じことを行う場合)

(echo -en "GET /xxxxxxxx HTTP/1.1\nHost: requestb.in\n\n" ; sleep 10) | \
openssl s_client -connect requestb.in:443

(これsleepは、opensslが入力の終わりにハングアップするのではなく、応答を待つようにすることです)

奇妙なエラーが発生します。

SSLルーチン:SSL23_GET_SERVER_HELLO:sslv3アラートハンドシェイクの失敗

これはSSLバージョンとTLSバージョンに関係していると思われるかもしれませんが、実際には、サーバー名表示(Wikipedia)requestb.inと呼ばれるものが必要なためです。これは事実上、SSLスタックに、どのサーバー名で認証するかサーバーに伝える必要があることを意味します。

コマンドラインのデモを続けるには、-servername引数を追加するだけです。

(echo -en "GET /xxxxxxxx HTTP/1.1\nHost: requestb.in\n\n" ; sleep 10) |\
openssl s_client -connect requestb.in:443 -servername requestb.in

有効なrequestb.inインスタンスのURLハッシュを使用してこれを行うと、結果が生成され、それを作成したブラウザーのログパネルに表示されます。


CC3xxxでのサーバー名表示(SNI)の実装

CC3xxxのTLS実装がSNIをサポートしいないこと、およびこれを追加する具体的な計画がないことを示唆するフォーラム投稿がいくつかあります。ただし、それがまだ当てはまるかどうかを確認できます。

ただし、ネットワーク層のツリーが含まれていることを覚えておくことが重要です。

WiFi
  IP packets
    TCP session
      TLS session
        HTTP protocol

CC3100ではTCPを話すことができるため(実際には既存のコードでそうしていました)、SNIをサポートするTLS実装を「独自に」作成することができます。たとえば、このブログ投稿では、mbed TLS(旧称PolarSSL)ライブラリをCC3xxxに移植することについて説明し、SNIを機能として言及しています。

TL; DR

requestb.inは、TLSで保護されたセッション上でHTTPを使用し、サーバー名表示を実装する必要があるため、難しいターゲットです。このホストとの対話が最終的なプロジェクトの一部でない場合は、単純にそれらのホストに移動する方がよい場合があります-IoTデバイス上の最小限の組み込みクライアントでの使用を意図したものは、物事を少し簡単にするように構成されている場合がありますSNIを使用しない。

また、発生する問題の詳細をキャプチャする習慣を身に付けると、はるかに効率的になります。組み込み開発は常にデバッグが難しく、ロギングやデバッガを介してキャプチャする障害に関する情報が少ないほど、推測に費やす時間が長くなります。 。


良い答えに見えますが、私の理解を超えています。近い将来、このレベルの深い知識を身につけたいと思います。でもご回答ありがとうございます。
user8055 2017

1
SNIの要件は確かに複雑になります。私の推奨は、requestb.inをスキップし、実際のプロジェクトで実際に話そうとしていることの要件に集中し、必要に応じて、より類似したモッキングサービスを見つけることです。その要件。
クリスストラットン2017

これを読んで、2つの競争力のある取り組みを削除した後、同じことをお勧めします。クリスの努力を受け入れてください。
mico 2017

1

openweathermap.orgとwww.mocky.ioの両方がhttpまたはポート80をサポートしている可能性が高いです。以下にいくつかの手がかりを示します。

openweathermap.org

OpenWeathermap

openweathermap-url

www.mocky.io

モッキー

mocky-url

requestb.inはHTTPSまたはポート443のみをサポートしているようです。

requestb.in

リクエストb

requestb-url

これは問題を説明するかもしれません。以下に役立つ参考資料をいくつか示します。

CC3100データシートには、HTTPSで動作するCC3100への言及はありません。すべての参照はHTTPのみに関するものです。これはおそらく問題をよりよく説明します。以下をデータシート以外から添付してください。

CC3100-データシート以外

データシートCC3120はHTTPSをサポートしているように見えます。下の添付はデータシートからです。HTTPSへの言及はほとんどありません。

CC3100-データシート以外

最も可能性の高いパスは、CC3100をCC3120に置き換えることです。

参照:


1
数多くの編集がエラーを導入し、それらを修正した後、これは可能性が、実際の答えている近づいています。しかし、それでも本当にそれを書き換える必要があります。あるサイトがhttpをサポートし、他のサイトはhttpsのみをサポートしているという論文の場合は、そのことを前もって言ってください。
クリスストラットン

2
そして、CC3100の分析と交換の推奨は完全に誤りのままです。それはTLS / SSLをサポートしていることを明確に示していますが、質問がサーバーであることとは何の関係もない場合、Webサーバーの機能を誤って調べてはいけないと主張しようとします。問題は、実際にはHTTPライブラリをまったく使用していないことですが、TCPソケット上で手動で実行しています。HTTPSサーバーに接続するには、SSL接続上で同様の操作を実行する必要があります。
クリスストラットン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.