MSP430F5529 + CC3100 IOT test device hanya merespon beberapa situs web pengujian

8

Baru-baru ini saya telah mengerjakan proyek IoT menggunakan mikrokontroler MSP430F5529 dan prosesor jaringan CC3100, keduanya dari Texas Instrument. Untuk evaluasi saya menggunakan landasan peluncuran MSP430F5529 dan boosterpack CC3100 . Saya mencoba agar perangkat terhubung ke cloud. Saya telah berhasil mengimplementasikan aplikasi CC3100 get weather example yang terhubung ke www.openweathermap.org . Ini adalah contoh dari Sampel Aplikasi CC3100 SDK . Program ini berhasil menerima dan merespons balik dari situs web www.openweathermap.org . Aplikasi menggunakan metode GET membuat permintaan dari situs web.

Saya juga telah berhasil menguji kode terhadap www.mocky.io . Perangkat menerima kode status 200 respons OK. Tetapi ketika saya menguji terhadap requestb.in situs tes saya tidak mendapatkan kode respons kesalahan 408 Timeout atau kode respon pengalihan URL 302.

#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"*

Di bawah ini adalah utama yang mencakup beberapa kondisi pengaturan. Beberapa kode penanganan kesalahan telah dihapus karena singkatnya.

 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;
}

Di bawah ini adalah kode getCredentials () yang memanggil mendapatkan data.

<!-- 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;
}

Di bawah ini adalah fungsi getdata () di mana saya mendapatkan kesalahan.

/*!
    \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;
}

Keamanan untuk titik akses diatur sebagai

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

Akhirnya ada beberapa perangkat sensor POC yang dibuat dengan CC3100 yang perlu mentransfer data ke cloud. Untuk kesederhanaan kita menggunakan paket booster, pada akhirnya kita perlu mendapatkan perangkat sensor POC berkomunikasi ke cloud melalui Wifi.

pengguna8055
sumber
Saya memberikan suara untuk menutup pertanyaan ini sebagai di luar topik karena masalah sebenarnya dari pertanyaan ini adalah tentang penggunaan HTTP dasar dan pada tingkat yang lebih rendah platform tertanam tertentu, bukan Internet of Things, oleh karena itu kumpulan kesamaan adalah untuk pertanyaan HTTP lainnya pertama, dan tidak benar-benar ke pertanyaan IOT lainnya sama sekali.
Chris Stratton
1
FYI requestb.in spesifik dalam kode Anda tampaknya sudah habis dan sekarang 404 ketika diakses melalui HTTP melalui TLS dengan SNI sebagai karya untuk yang saat ini valid.
Chris Stratton
@ mico, saya perhatikan bahwa Anda telah menghapus jawaban Anda. Anda juga menyebutkan menambahkan "s" ke http. Saya tidak yakin bagaimana saya bisa mencapai saran Anda. Tolong beri saya wawasan.
user8055
@ ChrisStratton, Maaf mendengar Anda memilih untuk menutup pertanyaan ini. Bisakah Anda merekomendasikan saya sebuah situs tanya jawab yang baik untuk mengajukan pertanyaan ini?
user8055
Apakah Anda mendapatkan pesan-pesan 302 dan 408 atau tidak? Jika tidak, lalu pesan apa yang Anda dapatkan?
mico

Jawaban:

5

Perbedaannya adalah karena situs requestb.in membutuhkan HTTP over TLS dengan SNI

Ini adalah cukup kompleks HTTP / HTTPS protokol dan keamanan pertanyaan kemungkinan yang lebih baik dibahas di tempat lain dalam sistem SE, dan sebagian besar mengenai rincian dari requestb.inlayanan yang Anda menguji melawan daripada apa pun proyek IOT Anda mungkin akhirnya akan lakukan. Tapi selama itu tetap di sini ...


Debugging requestb.in kode respons ketika mencoba HTTP pada port 80

Kamu berkata:

Tetapi ketika saya menguji terhadap requestb.in situs pengujian saya tidak mendapatkan kode respons kesalahan 408 Timeout atau kode respon pengalihan URL 302.

Mari lihat apa yang terjadi:

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

Status HTTP 301 adalah "Dipindahkan Secara Permanen", sedangkan 302 yang Anda harapkan kadang-kadang digunakan untuk pengalihan sementara . Karena mereka mungkin tidak berencana untuk membiarkan Anda menggunakan HTTP pada soket TCP biasa pada port 80, pengalihan permanen yang mereka kirim adalah respons yang lebih benar.

Itu akan jauh lebih bermanfaat jika Anda telah menangkap kode status yang _was_ kirim daripada hanya daftar dua yang _tidak dikirim_

Bagaimanapun, apa yang dikatakan server adalah bahwa kita harus menggunakan HTTPS.


Jadi apa yang perlu Anda lakukan untuk terhubung ke server melalui HTTPS?

Pada tingkat dasar, HTTPS berarti berbicara HTTP melalui koneksi yang dijamin dengan TLS (atau sebelumnya, SSL), daripada melakukannya melalui soket TCP biasa.

CC3100 Anda mendukung TLS dan SSL , dan ada beberapa informasi minimal tentang memodifikasi salah satu contoh klien HTTP SDK untuk melakukan koneksi HTTPS dengan membuat saluran yang aman, tersedia di http://processors.wiki.ti.com/index.php / CC3100_HTTP_Client

Namun, dalam hal requestb.inini mungkin tidak cukup.

Jika Anda mengirim permintaan GET yang sangat sederhana ke s_clientperintah openssl (atau melakukan hal yang sama pada CC3100)

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

( sleepis untuk membuat openssl menunggu respons daripada hangup pada akhir input)

Anda akan mendapatkan kesalahan aneh:

Rutinitas SSL: SSL23_GET_SERVER_HELLO: kegagalan jabat tangan sslv3 peringatan

Anda mungkin ada hubungannya dengan versi SSL vs TLS, tetapi sebenarnya itu karena requestb.inmemerlukan sesuatu yang disebut Indikasi Nama Server (Wikipedia) . Ini secara efektif berarti Anda harus memberi tahu tumpukan SSL untuk memberi tahu server mana nama server yang harus diautentikasi.

Melanjutkan dengan demonstrasi baris perintah, kami cukup menambahkan -servernameargumen:

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

Jika ini dilakukan dengan hash URL dari requestb.in yang valid dalam contoh, itu menghasilkan hasil dan terlihat di panel log browser yang dibuat itu.


Menerapkan Indikasi Nama Server (SNI) di CC3xxx

Ada beberapa posting forum menunjukkan bahwa pelaksanaan TLS pada CC3xxx telah tidak didukung SNI, dan bahwa tidak ada rencana konkret untuk menambahkan ini; Namun, Anda dapat memverifikasi jika itu masih terjadi.

Tetapi penting untuk diingat bahwa ada pohon lapisan jaringan yang terlibat:

WiFi
  IP packets
    TCP session
      TLS session
        HTTP protocol

Karena CC3100 memungkinkan Anda untuk berbicara TCP (dan sebenarnya Anda melakukannya dalam kode yang ada), Anda bebas untuk "membawa sendiri" implementasi TLS yang memang memiliki dukungan SNI. Sebagai contoh, posting blog ini membahas porting TLS (sebelumnya PolarSSL) yang dipasangi librari ke CC3xxx dan menyebutkan SNI sebagai kapabilitas.

TL; DR

requestb.inadalah target yang menantang karena mengharuskan Anda berbicara HTTP selama sesi yang dijamin dengan TLS dan menerapkan Indikasi Nama Server . Jika berbicara dengan host ini bukan bagian dari proyek pamungkas Anda, mungkin lebih baik Anda beralih ke host-host yang ada - yang dimaksudkan untuk digunakan dengan klien seminimal mungkin yang tertanam pada perangkat IoT mungkin dikonfigurasikan untuk membuat segalanya sedikit lebih mudah dengan tidak menggunakan SNI.

Ini juga akan jauh lebih efisien jika Anda terbiasa menangkap detail masalah yang Anda temui - pengembangan yang disematkan selalu menantang untuk di-debug, dan semakin sedikit informasi tentang kegagalan yang Anda tangkap melalui pencatatan atau debugger, semakin banyak waktu yang dihabiskan untuk menebak. .

Chris Stratton
sumber
Tampak jawaban yang bagus, tetapi di luar pemahaman saya. Saya berharap dapat mencapai tingkat pengetahuan mendalam ini dalam waktu dekat. Tapi terima kasih banyak atas tanggapannya.
user8055
1
Persyaratan SNI memang membuatnya rumit - rekomendasi saya adalah untuk melompati requestb.in, berkonsentrasilah pada persyaratan apa pun yang sebenarnya Anda coba ajak bicara dalam proyek nyata Anda, dan jika perlu temukan layanan mengejek yang lebih mirip dengan persyaratan itu.
Chris Stratton
Sekarang ketika membaca ini dan setelah menghapus dua upaya kompetitif saya, saya menyarankan hal yang sama, lakukan sesuatu yang lebih produktif. Dan terima upaya Chris.
mico
1

Sangat mungkin bahwa openweathermap.org dan www.mocky.io mendukung http atau port 80. Berikut adalah beberapa petunjuk.

openweathermap.org

Openweathermap

openweathermap-url

www.mocky.io

mocky

mocky-url

Sepertinya requestb.in hanya mendukung HTTPS atau port 443.

requestb.in

requestb

requestb-url

Ini mungkin menjelaskan masalahnya. Di bawah ini ada beberapa referensi yang mungkin bisa membantu.

Dalam datasheet CC3100 tidak ada referensi ke CC3100 yang bekerja dengan HTTPS. Semua referensi hanya untuk HTTP. Ini mungkin lebih baik menjelaskan masalahnya. Lampirkan di bawah ini kecuali dari lembar data.

CC3100 - Kecuali lembar data

Sepertinya per lembar data CC3120 mendukung HTTPS. Lampirkan di bawah ini kecuali dari lembar data. Ada beberapa referensi ke HTTPS.

CC3100 - Kecuali lembar data

Jalur ke depan yang paling mungkin adalah mengganti CC3100 dengan CC3120.

Referensi:

Mahendra Gunawardena
sumber
1
Setelah banyak pengeditan memperkenalkan kesalahan dan kemudian memperbaikinya, ini sekarang mungkin mendekati menjadi jawaban yang sebenarnya. Tetapi Anda benar-benar masih perlu menulis ulang: jika tesis Anda adalah bahwa satu situs mendukung http dan yang lainnya hanya https, maka katakan saja di muka.
Chris Stratton
2
Dan analisis Anda tentang CC3100 dan rekomendasi penggantian tetap sepenuhnya salah. Secara eksplisit mengatakan ini mendukung TLS / SSL, sementara Anda mencoba untuk membantah bahwa itu tidak dengan keliru melihat kemampuan server webnya, ketika pertanyaannya tidak ada hubungannya dengan menjadi server. Pertanyaannya sebenarnya tidak menggunakan perpustakaan HTTP sama sekali, tetapi melakukannya secara manual di atas soket TCP. Untuk menghubungi server HTTPS, perlu melakukan operasi serupa di atas koneksi SSL.
Chris Stratton