Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
Diff between coreHTTP example
作成日
4 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
54 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
416 行
すべてコピー
56 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
414 行
すべてコピー
/*
/*
* AWS IoT Device SDK for Embedded C 202103.00
* AWS IoT Device SDK for Embedded C 202103.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
*/
/* Standard includes. */
/* Standard includes. */
#include <assert.h>
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
/* POSIX includes. */
/* POSIX includes. */
#include <unistd.h>
#include <unistd.h>
/* Include Demo Config as the first non-system header. */
/* Include Demo Config as the first non-system header. */
#include "demo_config.h"
#include "demo_config.h"
/* Common HTTP demo utilities. */
/* Common HTTP demo utilities. */
#include "http_demo_utils.h"
#include "http_demo_utils.h"
/* HTTP API header. */
/* HTTP API header. */
#include "core_http_client.h"
#include "core_http_client.h"
/* OpenSSL transport header. */
/* OpenSSL transport header. */
コピー
コピー済み
コピー
コピー済み
#include "
openssl_posix
.h"
#include "
tls_freertos.h"
#include "demo_header
.h"
/* Check that AWS IoT Core endpoint is defined. */
/* Check that AWS IoT Core endpoint is defined. */
コピー
コピー済み
コピー
コピー済み
#ifndef AWS_IOT_ENDPOINT
#define AWS_IOT_ENDPOINT CONFIG_AWS_IOT_ENDPOINT
#error "AWS_IOT_ENDPOINT must be defined to your AWS IoT Core endpoint."
#ifndef ROOT_CA_PEM
#endif
#if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t root_cert_auth_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
/* Check that TLS port used for AWS IoT Core is defined. */
#else
#ifndef AWS_HTTPS_PORT
extern const uint8_t root_cert_auth_pem_start[] asm("_binary_root_cert_auth_pem_start");
#error "Please define a AWS_HTTPS_PORT."
#endif
extern const uint8_t root_cert_auth_pem_end[] asm("_binary_root_cert_auth_pem_end");
#endif
#endif
/* Check that a path for HTTP Method POST is defined. */
/* Check that a path for HTTP Method POST is defined. */
#ifndef POST_PATH
#ifndef POST_PATH
#error "Please define a POST_PATH."
#error "Please define a POST_PATH."
#endif
#endif
/* Check that a path for Root CA certificate is defined. */
/* Check that a path for Root CA certificate is defined. */
コピー
コピー済み
コピー
コピー済み
#ifndef ROOT_CA_CERT_PATH
#error "Please define a ROOT_CA_CERT_PATH."
#endif
/* Check that a path for the client certificate is defined. */
/* Check that a path for the client certificate is defined. */
コピー
コピー済み
コピー
コピー済み
#ifndef CLIENT_
CERT_PATH
#ifndef CLIENT_
CERTIFICATE_PEM
#error "Please define a CLIENT_CERT_PATH."
extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start");
extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end");
#endif
#endif
コピー
コピー済み
コピー
コピー済み
#ifndef CLIENT_PRIVATE_KEY_
PEM
/* Check that a path for the client's private key is defined. */
extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start");
#ifndef CLIENT_PRIVATE_KEY_
PATH
extern const uint8_t client_key_pem_end[] asm("_binary_client_key_end");
#error "Please define a CLIENT_PRIVATE_KEY_PATH."
#endif
#endif
/**
/**
* @brief ALPN protocol name to be sent as part of the ClientHello message.
* @brief ALPN protocol name to be sent as part of the ClientHello message.
*
*
* @note When using ALPN, port 443 must be used to connect to AWS IoT Core.
* @note When using ALPN, port 443 must be used to connect to AWS IoT Core.
*/
*/
コピー
コピー済み
コピー
コピー済み
#define IOT_CORE_ALPN_PROTOCOL_NAME "
\x0ex
-amzn-http-ca"
#define IOT_CORE_ALPN_PROTOCOL_NAME "
x
-amzn-http-ca"
/* Check that transport timeout for transport send and receive is defined. */
/* Check that transport timeout for transport send and receive is defined. */
#ifndef TRANSPORT_SEND_RECV_TIMEOUT_MS
#ifndef TRANSPORT_SEND_RECV_TIMEOUT_MS
コピー
コピー済み
コピー
コピー済み
#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1
0
00 )
#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1
5
00 )
#endif
#endif
/* Check that size of the user buffer is defined. */
/* Check that size of the user buffer is defined. */
#ifndef USER_BUFFER_LENGTH
#ifndef USER_BUFFER_LENGTH
#define USER_BUFFER_LENGTH ( 2048 )
#define USER_BUFFER_LENGTH ( 2048 )
#endif
#endif
/* Check that a request body to send for the POST request is defined. */
/* Check that a request body to send for the POST request is defined. */
#ifndef REQUEST_BODY
#ifndef REQUEST_BODY
#error "Please define a REQUEST_BODY."
#error "Please define a REQUEST_BODY."
#endif
#endif
/**
/**
* @brief The length of the AWS IoT Endpoint.
* @brief The length of the AWS IoT Endpoint.
*/
*/
#define AWS_IOT_ENDPOINT_LENGTH ( sizeof( AWS_IOT_ENDPOINT ) - 1 )
#define AWS_IOT_ENDPOINT_LENGTH ( sizeof( AWS_IOT_ENDPOINT ) - 1 )
/**
/**
* @brief The length of the HTTP POST method.
* @brief The length of the HTTP POST method.
*/
*/
#define HTTP_METHOD_POST_LENGTH ( sizeof( HTTP_METHOD_POST ) - 1 )
#define HTTP_METHOD_POST_LENGTH ( sizeof( HTTP_METHOD_POST ) - 1 )
/**
/**
* @brief The length of the HTTP POST path.
* @brief The length of the HTTP POST path.
*/
*/
#define POST_PATH_LENGTH ( sizeof( POST_PATH ) - 1 )
#define POST_PATH_LENGTH ( sizeof( POST_PATH ) - 1 )
/**
/**
* @brief Length of the request body.
* @brief Length of the request body.
*/
*/
#define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 )
#define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 )
/**
/**
* @brief A buffer used in the demo for storing HTTP request headers and
* @brief A buffer used in the demo for storing HTTP request headers and
* HTTP response headers and body.
* HTTP response headers and body.
*
*
* @note This demo shows how the same buffer can be re-used for storing the HTTP
* @note This demo shows how the same buffer can be re-used for storing the HTTP
* response after the HTTP request is sent out. However, the user can also
* response after the HTTP request is sent out. However, the user can also
* decide to use separate buffers for storing the HTTP request and response.
* decide to use separate buffers for storing the HTTP request and response.
*/
*/
static uint8_t userBuffer[ USER_BUFFER_LENGTH ];
static uint8_t userBuffer[ USER_BUFFER_LENGTH ];
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
コピー
コピー済み
コピー
コピー済み
/* Each compilation unit must define the NetworkContext struct. */
struct NetworkContext
{
OpensslParams_t * pParams;
};
/*-----------------------------------------------------------*/
/**
/**
* @brief Connect to HTTP server with reconnection retries.
* @brief Connect to HTTP server with reconnection retries.
*
*
* @param[out] pNetworkContext The output parameter to return the created network context.
* @param[out] pNetworkContext The output parameter to return the created network context.
*
*
* @return EXIT_FAILURE on failure; EXIT_SUCCESS on successful connection.
* @return EXIT_FAILURE on failure; EXIT_SUCCESS on successful connection.
*/
*/
static int32_t connectToServer( NetworkContext_t * pNetworkContext );
static int32_t connectToServer( NetworkContext_t * pNetworkContext );
/**
/**
* @brief Send an HTTP request based on a specified method and path, then
* @brief Send an HTTP request based on a specified method and path, then
* print the response received from the server.
* print the response received from the server.
*
*
* @param[in] pTransportInterface The transport interface for making network calls.
* @param[in] pTransportInterface The transport interface for making network calls.
* @param[in] pMethod The HTTP request method.
* @param[in] pMethod The HTTP request method.
* @param[in] methodLen The length of the HTTP request method.
* @param[in] methodLen The length of the HTTP request method.
* @param[in] pPath The Request-URI to the objects of interest.
* @param[in] pPath The Request-URI to the objects of interest.
* @param[in] pathLen The length of the Request-URI.
* @param[in] pathLen The length of the Request-URI.
*
*
* @return EXIT_FAILURE on failure; EXIT_SUCCESS on success.
* @return EXIT_FAILURE on failure; EXIT_SUCCESS on success.
*/
*/
static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface,
static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface,
const char * pMethod,
const char * pMethod,
size_t methodLen,
size_t methodLen,
const char * pPath,
const char * pPath,
size_t pathLen );
size_t pathLen );
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
static int32_t connectToServer( NetworkContext_t * pNetworkContext )
static int32_t connectToServer( NetworkContext_t * pNetworkContext )
{
{
int32_t returnStatus = EXIT_FAILURE;
int32_t returnStatus = EXIT_FAILURE;
/* Status returned by OpenSSL transport implementation. */
/* Status returned by OpenSSL transport implementation. */
コピー
コピー済み
コピー
コピー済み
OpensslStatus
_t opensslStatus;
TlsTransportStatus
_t opensslStatus;
/* Credentials to establish the TLS connection. */
/* Credentials to establish the TLS connection. */
コピー
コピー済み
コピー
コピー済み
Openssl
Credentials_t
opensslCredentials
;
Network
Credentials_t
*
opensslCredentials
= (NetworkCredentials_t*) malloc (sizeof (NetworkCredentials_t))
;
/* Information about the server to send the HTTP requests. */
/* Information about the server to send the HTTP requests. */
ServerInfo_t serverInfo;
ServerInfo_t serverInfo;
/* Initialize TLS credentials. */
/* Initialize TLS credentials. */
コピー
コピー済み
コピー
コピー済み
( void ) memset( &
opensslCredentials
, 0, sizeof(
opensslCredentials
) )
;
opensslCredentials
->pClientCert = ( const unsigned char * ) client_cert_pem_start;
opensslCredentials
.pClientCertPath = CLIENT_CERT_PATH
;
opensslCredentials
->clientCertSize = client_cert_pem_end - client_cert_pem_start
;
opensslCredentials
.pP
rivateKey
Path
=
CLIENT_PRIVATE_KEY_PATH
;
opensslCredentials
->pPrivateKey = ( const unsigned char * ) client_key_pem_start
;
opensslCredentials
.
pRootCa
Path
=
ROOT_CA_CERT_PATH
;
opensslCredentials
->p
rivateKey
Size
=
client_key_pem_end - client_key_pem_start
;
opensslCredentials
.sniHostName = AWS_IOT_ENDPOINT;
opensslCredentials
->
pRootCa
=
( const unsigned char * ) root_cert_auth_pem_start
;
opensslCredentials
->rootCaSize = root_cert_auth_pem_end - root_cert_auth_pem_start;
opensslCredentials->disableSni = 0;
/* ALPN is required when communicating to AWS IoT Core over port 443 through HTTP. */
/* ALPN is required when communicating to AWS IoT Core over port 443 through HTTP. */
if( AWS_HTTPS_PORT == 443 )
if( AWS_HTTPS_PORT == 443 )
{
{
コピー
コピー済み
コピー
コピー済み
opensslCredentials.p
AlpnProto
s
= IOT_CORE_ALPN_PROTOCOL_NAME;
static const char * pcAlpnProtocols[] = { NULL, NULL };
opensslCredentials
.a
lpnProtos
Len = strlen( IOT_CORE_ALPN_PROTOCOL_NAME );
pc
AlpnProto
cols[0]
= IOT_CORE_ALPN_PROTOCOL_NAME;
opensslCredentials
->pA
lpnProtos
= pcAlpnProtocols;
} else {
opensslCredentials->pAlpnProtos = NULL;
}
}
/* Initialize server information. */
/* Initialize server information. */
serverInfo.pHostName = AWS_IOT_ENDPOINT;
serverInfo.pHostName = AWS_IOT_ENDPOINT;
serverInfo.hostNameLength = AWS_IOT_ENDPOINT_LENGTH;
serverInfo.hostNameLength = AWS_IOT_ENDPOINT_LENGTH;
serverInfo.port = AWS_HTTPS_PORT;
serverInfo.port = AWS_HTTPS_PORT;
/* Establish a TLS session with the HTTP server. This example connects
/* Establish a TLS session with the HTTP server. This example connects
* to the HTTP server as specified in AWS_IOT_ENDPOINT and AWS_HTTPS_PORT
* to the HTTP server as specified in AWS_IOT_ENDPOINT and AWS_HTTPS_PORT
* in demo_config.h. */
* in demo_config.h. */
LogInfo( ( "Establishing a TLS session to %.*s:%d.",
LogInfo( ( "Establishing a TLS session to %.*s:%d.",
( int32_t ) AWS_IOT_ENDPOINT_LENGTH,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH,
AWS_IOT_ENDPOINT,
AWS_IOT_ENDPOINT,
AWS_HTTPS_PORT ) );
AWS_HTTPS_PORT ) );
コピー
コピー済み
コピー
コピー済み
opensslStatus =
Openssl
_Connect
( pNetworkContext,
opensslStatus =
TLS_FreeRTOS
_Connect
( pNetworkContext,
&
serverInfo
,
serverInfo
.pHostName
,
&
opensslCredentials,
serverInfo.port,
TRANSPORT_SEND_RECV_TIMEOUT_MS,
opensslCredentials,
TRANSPORT_SEND_RECV_TIMEOUT_MS );
TRANSPORT_SEND_RECV_TIMEOUT_MS,
TRANSPORT_SEND_RECV_TIMEOUT_MS );
コピー
コピー済み
コピー
コピー済み
if( opensslStatus ==
OPENSSL
_SUCCESS )
if( opensslStatus ==
TLS_TRANSPORT
_SUCCESS )
{
{
returnStatus = EXIT_SUCCESS;
returnStatus = EXIT_SUCCESS;
}
}
else
else
{
{
returnStatus = EXIT_FAILURE;
returnStatus = EXIT_FAILURE;
}
}
return returnStatus;
return returnStatus;
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface,
static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface,
const char * pMethod,
const char * pMethod,
size_t methodLen,
size_t methodLen,
const char * pPath,
const char * pPath,
size_t pathLen )
size_t pathLen )
{
{
/* Return value of this method. */
/* Return value of this method. */
int32_t returnStatus = EXIT_SUCCESS;
int32_t returnStatus = EXIT_SUCCESS;
/* Configurations of the initial request headers that are passed to
/* Configurations of the initial request headers that are passed to
* #HTTPClient_InitializeRequestHeaders. */
* #HTTPClient_InitializeRequestHeaders. */
HTTPRequestInfo_t requestInfo;
HTTPRequestInfo_t requestInfo;
/* Represents a response returned from an HTTP server. */
/* Represents a response returned from an HTTP server. */
HTTPResponse_t response;
HTTPResponse_t response;
/* Represents header data that will be sent in an HTTP request. */
/* Represents header data that will be sent in an HTTP request. */
HTTPRequestHeaders_t requestHeaders;
HTTPRequestHeaders_t requestHeaders;
/* Return value of all methods from the HTTP Client library API. */
/* Return value of all methods from the HTTP Client library API. */
HTTPStatus_t httpStatus = HTTPSuccess;
HTTPStatus_t httpStatus = HTTPSuccess;
assert( pMethod != NULL );
assert( pMethod != NULL );
assert( pPath != NULL );
assert( pPath != NULL );
/* Initialize all HTTP Client library API structs to 0. */
/* Initialize all HTTP Client library API structs to 0. */
( void ) memset( &requestInfo, 0, sizeof( requestInfo ) );
( void ) memset( &requestInfo, 0, sizeof( requestInfo ) );
( void ) memset( &response, 0, sizeof( response ) );
( void ) memset( &response, 0, sizeof( response ) );
( void ) memset( &requestHeaders, 0, sizeof( requestHeaders ) );
( void ) memset( &requestHeaders, 0, sizeof( requestHeaders ) );
/* Initialize the request object. */
/* Initialize the request object. */
requestInfo.pHost = AWS_IOT_ENDPOINT;
requestInfo.pHost = AWS_IOT_ENDPOINT;
requestInfo.hostLen = AWS_IOT_ENDPOINT_LENGTH;
requestInfo.hostLen = AWS_IOT_ENDPOINT_LENGTH;
requestInfo.pMethod = pMethod;
requestInfo.pMethod = pMethod;
requestInfo.methodLen = methodLen;
requestInfo.methodLen = methodLen;
requestInfo.pPath = pPath;
requestInfo.pPath = pPath;
requestInfo.pathLen = pathLen;
requestInfo.pathLen = pathLen;
/* Set "Connection" HTTP header to "keep-alive" so that multiple requests
/* Set "Connection" HTTP header to "keep-alive" so that multiple requests
* can be sent over the same established TCP connection. */
* can be sent over the same established TCP connection. */
requestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG;
requestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG;
/* Set the buffer used for storing request headers. */
/* Set the buffer used for storing request headers. */
requestHeaders.pBuffer = userBuffer;
requestHeaders.pBuffer = userBuffer;
requestHeaders.bufferLen = USER_BUFFER_LENGTH;
requestHeaders.bufferLen = USER_BUFFER_LENGTH;
httpStatus = HTTPClient_InitializeRequestHeaders( &requestHeaders,
httpStatus = HTTPClient_InitializeRequestHeaders( &requestHeaders,
&requestInfo );
&requestInfo );
if( httpStatus == HTTPSuccess )
if( httpStatus == HTTPSuccess )
{
{
/* Initialize the response object. The same buffer used for storing
/* Initialize the response object. The same buffer used for storing
* request headers is reused here. */
* request headers is reused here. */
response.pBuffer = userBuffer;
response.pBuffer = userBuffer;
response.bufferLen = USER_BUFFER_LENGTH;
response.bufferLen = USER_BUFFER_LENGTH;
LogInfo( ( "Sending HTTP %.*s request to %.*s%.*s...",
LogInfo( ( "Sending HTTP %.*s request to %.*s%.*s...",
( int32_t ) requestInfo.methodLen, requestInfo.pMethod,
( int32_t ) requestInfo.methodLen, requestInfo.pMethod,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) requestInfo.pathLen, requestInfo.pPath ) );
( int32_t ) requestInfo.pathLen, requestInfo.pPath ) );
LogDebug( ( "Request Headers:\n%.*s\n"
LogDebug( ( "Request Headers:\n%.*s\n"
"Request Body:\n%.*s\n",
"Request Body:\n%.*s\n",
( int32_t ) requestHeaders.headersLen,
( int32_t ) requestHeaders.headersLen,
( char * ) requestHeaders.pBuffer,
( char * ) requestHeaders.pBuffer,
( int32_t ) REQUEST_BODY_LENGTH, REQUEST_BODY ) );
( int32_t ) REQUEST_BODY_LENGTH, REQUEST_BODY ) );
/* Send the request and receive the response. */
/* Send the request and receive the response. */
httpStatus = HTTPClient_Send( pTransportInterface,
httpStatus = HTTPClient_Send( pTransportInterface,
&requestHeaders,
&requestHeaders,
( uint8_t * ) REQUEST_BODY,
( uint8_t * ) REQUEST_BODY,
REQUEST_BODY_LENGTH,
REQUEST_BODY_LENGTH,
&response,
&response,
0 );
0 );
}
}
else
else
{
{
LogError( ( "Failed to initialize HTTP request headers: Error=%s.",
LogError( ( "Failed to initialize HTTP request headers: Error=%s.",
HTTPClient_strerror( httpStatus ) ) );
HTTPClient_strerror( httpStatus ) ) );
}
}
if( httpStatus == HTTPSuccess )
if( httpStatus == HTTPSuccess )
{
{
LogInfo( ( "Received HTTP response from %.*s%.*s...\n"
LogInfo( ( "Received HTTP response from %.*s%.*s...\n"
"Response Headers:\n%.*s\n"
"Response Headers:\n%.*s\n"
"Response Status:\n%u\n"
"Response Status:\n%u\n"
"Response Body:\n%.*s\n",
"Response Body:\n%.*s\n",
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) requestInfo.pathLen, requestInfo.pPath,
( int32_t ) requestInfo.pathLen, requestInfo.pPath,
( int32_t ) response.headersLen, response.pHeaders,
( int32_t ) response.headersLen, response.pHeaders,
response.statusCode,
response.statusCode,
( int32_t ) response.bodyLen, response.pBody ) );
( int32_t ) response.bodyLen, response.pBody ) );
}
}
else
else
{
{
LogError( ( "Failed to send HTTP %.*s request to %.*s%.*s: Error=%s.",
LogError( ( "Failed to send HTTP %.*s request to %.*s%.*s: Error=%s.",
( int32_t ) requestInfo.methodLen, requestInfo.pMethod,
( int32_t ) requestInfo.methodLen, requestInfo.pMethod,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT,
( int32_t ) requestInfo.pathLen, requestInfo.pPath,
( int32_t ) requestInfo.pathLen, requestInfo.pPath,
HTTPClient_strerror( httpStatus ) ) );
HTTPClient_strerror( httpStatus ) ) );
}
}
if( httpStatus != HTTPSuccess )
if( httpStatus != HTTPSuccess )
{
{
returnStatus = EXIT_FAILURE;
returnStatus = EXIT_FAILURE;
}
}
return returnStatus;
return returnStatus;
}
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/**
/**
* @brief Entry point of demo.
* @brief Entry point of demo.
*
*
* This example resolves the AWS IoT Core endpoint, establishes a TCP connection,
* This example resolves the AWS IoT Core endpoint, establishes a TCP connection,
* performs a mutually authenticated TLS handshake occurs such that all further
* performs a mutually authenticated TLS handshake occurs such that all further
* communication is encrypted. After which, HTTP Client Library API is used to
* communication is encrypted. After which, HTTP Client Library API is used to
* make a POST request to AWS IoT Core in order to publish a message to a topic
* make a POST request to AWS IoT Core in order to publish a message to a topic
* named topic with QoS=1 so that all clients subscribed to the topic receive
* named topic with QoS=1 so that all clients subscribed to the topic receive
* the message at least once. Any possible errors are also logged.
* the message at least once. Any possible errors are also logged.
*
*
* @note This example is single-threaded and uses statically allocated memory.
* @note This example is single-threaded and uses statically allocated memory.
*
*
*/
*/
コピー
コピー済み
コピー
コピー済み
int
main( int argc,
int
aws_iot_demo_
main( int argc,
char ** argv )
char ** argv )
{
{
/* Return value of main. */
/* Return value of main. */
int32_t returnStatus = EXIT_SUCCESS;
int32_t returnStatus = EXIT_SUCCESS;
/* The transport layer interface used by the HTTP Client library. */
/* The transport layer interface used by the HTTP Client library. */
TransportInterface_t transportInterface;
TransportInterface_t transportInterface;
/* The network context for the transport layer interface. */
/* The network context for the transport layer interface. */
NetworkContext_t networkContext;
NetworkContext_t networkContext;
コピー
コピー済み
コピー
コピー済み
OpensslParams_t opensslParams;
( void ) argc;
( void ) argc;
( void ) argv;
( void ) argv;
/* Set the pParams member of the network context with desired transport. */
/* Set the pParams member of the network context with desired transport. */
コピー
コピー済み
コピー
コピー済み
networkContext.pParams = &opensslParams;
/**************************** Connect. ******************************/
/**************************** Connect. ******************************/
/* Establish TLS connection on top of TCP connection using OpenSSL. */
/* Establish TLS connection on top of TCP connection using OpenSSL. */
if( returnStatus == EXIT_SUCCESS )
if( returnStatus == EXIT_SUCCESS )
{
{
LogInfo( ( "Performing TLS handshake on top of the TCP connection." ) );
LogInfo( ( "Performing TLS handshake on top of the TCP connection." ) );
/* Attempt to connect to the HTTP server. If connection fails, retry after
/* Attempt to connect to the HTTP server. If connection fails, retry after
* a timeout. Timeout value will be exponentially increased till the maximum
* a timeout. Timeout value will be exponentially increased till the maximum
* attempts are reached or maximum timeout value is reached. The function
* attempts are reached or maximum timeout value is reached. The function
* returns EXIT_FAILURE if the TCP connection cannot be established to
* returns EXIT_FAILURE if the TCP connection cannot be established to
* broker after configured number of attempts. */
* broker after configured number of attempts. */
returnStatus = connectToServerWithBackoffRetries( connectToServer,
returnStatus = connectToServerWithBackoffRetries( connectToServer,
&networkContext );
&networkContext );
if( returnStatus == EXIT_FAILURE )
if( returnStatus == EXIT_FAILURE )
{
{
/* Log error to indicate connection failure after all
/* Log error to indicate connection failure after all
* reconnect attempts are over. */
* reconnect attempts are over. */
LogError( ( "Failed to connect to HTTP server %.*s.",
LogError( ( "Failed to connect to HTTP server %.*s.",
( int32_t ) AWS_IOT_ENDPOINT_LENGTH,
( int32_t ) AWS_IOT_ENDPOINT_LENGTH,
AWS_IOT_ENDPOINT ) );
AWS_IOT_ENDPOINT ) );
}
}
}
}
/* Define the transport interface. */
/* Define the transport interface. */
if( returnStatus == EXIT_SUCCESS )
if( returnStatus == EXIT_SUCCESS )
{
{
( void ) memset( &transportInterface, 0, sizeof( transportInterface ) );
( void ) memset( &transportInterface, 0, sizeof( transportInterface ) );
コピー
コピー済み
コピー
コピー済み
transportInterface.recv =
Openssl_Recv
;
transportInterface.recv =
TLS_FreeRTOS_recv
;
transportInterface.send =
Openssl_Send
;
transportInterface.send =
TLS_FreeRTOS_send
;
transportInterface.pNetworkContext = &networkContext;
transportInterface.pNetworkContext = &networkContext;
}
}
/*********************** Send HTTPS request. ************************/
/*********************** Send HTTPS request. ************************/
if( returnStatus == EXIT_SUCCESS )
if( returnStatus == EXIT_SUCCESS )
{
{
returnStatus = sendHttpRequest( &transportInterface,
returnStatus = sendHttpRequest( &transportInterface,
HTTP_METHOD_POST,
HTTP_METHOD_POST,
HTTP_METHOD_POST_LENGTH,
HTTP_METHOD_POST_LENGTH,
POST_PATH,
POST_PATH,
POST_PATH_LENGTH );
POST_PATH_LENGTH );
}
}
if( returnStatus == EXIT_SUCCESS )
if( returnStatus == EXIT_SUCCESS )
{
{
/* Log message indicating an iteration completed successfully. */
/* Log message indicating an iteration completed successfully. */
LogInfo( ( "Demo completed successfully." ) );
LogInfo( ( "Demo completed successfully." ) );
}
}
/************************** Disconnect. *****************************/
/************************** Disconnect. *****************************/
/* End TLS session, then close TCP connection. */
/* End TLS session, then close TCP connection. */
コピー
コピー済み
コピー
コピー済み
( void )
Openssl
_Disconnect( &networkContext );
( void )
TLS_FreeRTOS
_Disconnect( &networkContext );
return returnStatus;
return returnStatus;
}
}
保存された差分
原文
ファイルを開く
/* * AWS IoT Device SDK for Embedded C 202103.00 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Standard includes. */ #include <assert.h> #include <stdlib.h> #include <string.h> /* POSIX includes. */ #include <unistd.h> /* Include Demo Config as the first non-system header. */ #include "demo_config.h" /* Common HTTP demo utilities. */ #include "http_demo_utils.h" /* HTTP API header. */ #include "core_http_client.h" /* OpenSSL transport header. */ #include "openssl_posix.h" /* Check that AWS IoT Core endpoint is defined. */ #ifndef AWS_IOT_ENDPOINT #error "AWS_IOT_ENDPOINT must be defined to your AWS IoT Core endpoint." #endif /* Check that TLS port used for AWS IoT Core is defined. */ #ifndef AWS_HTTPS_PORT #error "Please define a AWS_HTTPS_PORT." #endif /* Check that a path for HTTP Method POST is defined. */ #ifndef POST_PATH #error "Please define a POST_PATH." #endif /* Check that a path for Root CA certificate is defined. */ #ifndef ROOT_CA_CERT_PATH #error "Please define a ROOT_CA_CERT_PATH." #endif /* Check that a path for the client certificate is defined. */ #ifndef CLIENT_CERT_PATH #error "Please define a CLIENT_CERT_PATH." #endif /* Check that a path for the client's private key is defined. */ #ifndef CLIENT_PRIVATE_KEY_PATH #error "Please define a CLIENT_PRIVATE_KEY_PATH." #endif /** * @brief ALPN protocol name to be sent as part of the ClientHello message. * * @note When using ALPN, port 443 must be used to connect to AWS IoT Core. */ #define IOT_CORE_ALPN_PROTOCOL_NAME "\x0ex-amzn-http-ca" /* Check that transport timeout for transport send and receive is defined. */ #ifndef TRANSPORT_SEND_RECV_TIMEOUT_MS #define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1000 ) #endif /* Check that size of the user buffer is defined. */ #ifndef USER_BUFFER_LENGTH #define USER_BUFFER_LENGTH ( 2048 ) #endif /* Check that a request body to send for the POST request is defined. */ #ifndef REQUEST_BODY #error "Please define a REQUEST_BODY." #endif /** * @brief The length of the AWS IoT Endpoint. */ #define AWS_IOT_ENDPOINT_LENGTH ( sizeof( AWS_IOT_ENDPOINT ) - 1 ) /** * @brief The length of the HTTP POST method. */ #define HTTP_METHOD_POST_LENGTH ( sizeof( HTTP_METHOD_POST ) - 1 ) /** * @brief The length of the HTTP POST path. */ #define POST_PATH_LENGTH ( sizeof( POST_PATH ) - 1 ) /** * @brief Length of the request body. */ #define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 ) /** * @brief A buffer used in the demo for storing HTTP request headers and * HTTP response headers and body. * * @note This demo shows how the same buffer can be re-used for storing the HTTP * response after the HTTP request is sent out. However, the user can also * decide to use separate buffers for storing the HTTP request and response. */ static uint8_t userBuffer[ USER_BUFFER_LENGTH ]; /*-----------------------------------------------------------*/ /* Each compilation unit must define the NetworkContext struct. */ struct NetworkContext { OpensslParams_t * pParams; }; /*-----------------------------------------------------------*/ /** * @brief Connect to HTTP server with reconnection retries. * * @param[out] pNetworkContext The output parameter to return the created network context. * * @return EXIT_FAILURE on failure; EXIT_SUCCESS on successful connection. */ static int32_t connectToServer( NetworkContext_t * pNetworkContext ); /** * @brief Send an HTTP request based on a specified method and path, then * print the response received from the server. * * @param[in] pTransportInterface The transport interface for making network calls. * @param[in] pMethod The HTTP request method. * @param[in] methodLen The length of the HTTP request method. * @param[in] pPath The Request-URI to the objects of interest. * @param[in] pathLen The length of the Request-URI. * * @return EXIT_FAILURE on failure; EXIT_SUCCESS on success. */ static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface, const char * pMethod, size_t methodLen, const char * pPath, size_t pathLen ); /*-----------------------------------------------------------*/ static int32_t connectToServer( NetworkContext_t * pNetworkContext ) { int32_t returnStatus = EXIT_FAILURE; /* Status returned by OpenSSL transport implementation. */ OpensslStatus_t opensslStatus; /* Credentials to establish the TLS connection. */ OpensslCredentials_t opensslCredentials; /* Information about the server to send the HTTP requests. */ ServerInfo_t serverInfo; /* Initialize TLS credentials. */ ( void ) memset( &opensslCredentials, 0, sizeof( opensslCredentials ) ); opensslCredentials.pClientCertPath = CLIENT_CERT_PATH; opensslCredentials.pPrivateKeyPath = CLIENT_PRIVATE_KEY_PATH; opensslCredentials.pRootCaPath = ROOT_CA_CERT_PATH; opensslCredentials.sniHostName = AWS_IOT_ENDPOINT; /* ALPN is required when communicating to AWS IoT Core over port 443 through HTTP. */ if( AWS_HTTPS_PORT == 443 ) { opensslCredentials.pAlpnProtos = IOT_CORE_ALPN_PROTOCOL_NAME; opensslCredentials.alpnProtosLen = strlen( IOT_CORE_ALPN_PROTOCOL_NAME ); } /* Initialize server information. */ serverInfo.pHostName = AWS_IOT_ENDPOINT; serverInfo.hostNameLength = AWS_IOT_ENDPOINT_LENGTH; serverInfo.port = AWS_HTTPS_PORT; /* Establish a TLS session with the HTTP server. This example connects * to the HTTP server as specified in AWS_IOT_ENDPOINT and AWS_HTTPS_PORT * in demo_config.h. */ LogInfo( ( "Establishing a TLS session to %.*s:%d.", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, AWS_HTTPS_PORT ) ); opensslStatus = Openssl_Connect( pNetworkContext, &serverInfo, &opensslCredentials, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS ); if( opensslStatus == OPENSSL_SUCCESS ) { returnStatus = EXIT_SUCCESS; } else { returnStatus = EXIT_FAILURE; } return returnStatus; } /*-----------------------------------------------------------*/ static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface, const char * pMethod, size_t methodLen, const char * pPath, size_t pathLen ) { /* Return value of this method. */ int32_t returnStatus = EXIT_SUCCESS; /* Configurations of the initial request headers that are passed to * #HTTPClient_InitializeRequestHeaders. */ HTTPRequestInfo_t requestInfo; /* Represents a response returned from an HTTP server. */ HTTPResponse_t response; /* Represents header data that will be sent in an HTTP request. */ HTTPRequestHeaders_t requestHeaders; /* Return value of all methods from the HTTP Client library API. */ HTTPStatus_t httpStatus = HTTPSuccess; assert( pMethod != NULL ); assert( pPath != NULL ); /* Initialize all HTTP Client library API structs to 0. */ ( void ) memset( &requestInfo, 0, sizeof( requestInfo ) ); ( void ) memset( &response, 0, sizeof( response ) ); ( void ) memset( &requestHeaders, 0, sizeof( requestHeaders ) ); /* Initialize the request object. */ requestInfo.pHost = AWS_IOT_ENDPOINT; requestInfo.hostLen = AWS_IOT_ENDPOINT_LENGTH; requestInfo.pMethod = pMethod; requestInfo.methodLen = methodLen; requestInfo.pPath = pPath; requestInfo.pathLen = pathLen; /* Set "Connection" HTTP header to "keep-alive" so that multiple requests * can be sent over the same established TCP connection. */ requestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG; /* Set the buffer used for storing request headers. */ requestHeaders.pBuffer = userBuffer; requestHeaders.bufferLen = USER_BUFFER_LENGTH; httpStatus = HTTPClient_InitializeRequestHeaders( &requestHeaders, &requestInfo ); if( httpStatus == HTTPSuccess ) { /* Initialize the response object. The same buffer used for storing * request headers is reused here. */ response.pBuffer = userBuffer; response.bufferLen = USER_BUFFER_LENGTH; LogInfo( ( "Sending HTTP %.*s request to %.*s%.*s...", ( int32_t ) requestInfo.methodLen, requestInfo.pMethod, ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath ) ); LogDebug( ( "Request Headers:\n%.*s\n" "Request Body:\n%.*s\n", ( int32_t ) requestHeaders.headersLen, ( char * ) requestHeaders.pBuffer, ( int32_t ) REQUEST_BODY_LENGTH, REQUEST_BODY ) ); /* Send the request and receive the response. */ httpStatus = HTTPClient_Send( pTransportInterface, &requestHeaders, ( uint8_t * ) REQUEST_BODY, REQUEST_BODY_LENGTH, &response, 0 ); } else { LogError( ( "Failed to initialize HTTP request headers: Error=%s.", HTTPClient_strerror( httpStatus ) ) ); } if( httpStatus == HTTPSuccess ) { LogInfo( ( "Received HTTP response from %.*s%.*s...\n" "Response Headers:\n%.*s\n" "Response Status:\n%u\n" "Response Body:\n%.*s\n", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath, ( int32_t ) response.headersLen, response.pHeaders, response.statusCode, ( int32_t ) response.bodyLen, response.pBody ) ); } else { LogError( ( "Failed to send HTTP %.*s request to %.*s%.*s: Error=%s.", ( int32_t ) requestInfo.methodLen, requestInfo.pMethod, ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath, HTTPClient_strerror( httpStatus ) ) ); } if( httpStatus != HTTPSuccess ) { returnStatus = EXIT_FAILURE; } return returnStatus; } /*-----------------------------------------------------------*/ /** * @brief Entry point of demo. * * This example resolves the AWS IoT Core endpoint, establishes a TCP connection, * performs a mutually authenticated TLS handshake occurs such that all further * communication is encrypted. After which, HTTP Client Library API is used to * make a POST request to AWS IoT Core in order to publish a message to a topic * named topic with QoS=1 so that all clients subscribed to the topic receive * the message at least once. Any possible errors are also logged. * * @note This example is single-threaded and uses statically allocated memory. * */ int main( int argc, char ** argv ) { /* Return value of main. */ int32_t returnStatus = EXIT_SUCCESS; /* The transport layer interface used by the HTTP Client library. */ TransportInterface_t transportInterface; /* The network context for the transport layer interface. */ NetworkContext_t networkContext; OpensslParams_t opensslParams; ( void ) argc; ( void ) argv; /* Set the pParams member of the network context with desired transport. */ networkContext.pParams = &opensslParams; /**************************** Connect. ******************************/ /* Establish TLS connection on top of TCP connection using OpenSSL. */ if( returnStatus == EXIT_SUCCESS ) { LogInfo( ( "Performing TLS handshake on top of the TCP connection." ) ); /* Attempt to connect to the HTTP server. If connection fails, retry after * a timeout. Timeout value will be exponentially increased till the maximum * attempts are reached or maximum timeout value is reached. The function * returns EXIT_FAILURE if the TCP connection cannot be established to * broker after configured number of attempts. */ returnStatus = connectToServerWithBackoffRetries( connectToServer, &networkContext ); if( returnStatus == EXIT_FAILURE ) { /* Log error to indicate connection failure after all * reconnect attempts are over. */ LogError( ( "Failed to connect to HTTP server %.*s.", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT ) ); } } /* Define the transport interface. */ if( returnStatus == EXIT_SUCCESS ) { ( void ) memset( &transportInterface, 0, sizeof( transportInterface ) ); transportInterface.recv = Openssl_Recv; transportInterface.send = Openssl_Send; transportInterface.pNetworkContext = &networkContext; } /*********************** Send HTTPS request. ************************/ if( returnStatus == EXIT_SUCCESS ) { returnStatus = sendHttpRequest( &transportInterface, HTTP_METHOD_POST, HTTP_METHOD_POST_LENGTH, POST_PATH, POST_PATH_LENGTH ); } if( returnStatus == EXIT_SUCCESS ) { /* Log message indicating an iteration completed successfully. */ LogInfo( ( "Demo completed successfully." ) ); } /************************** Disconnect. *****************************/ /* End TLS session, then close TCP connection. */ ( void ) Openssl_Disconnect( &networkContext ); return returnStatus; }
変更されたテキスト
ファイルを開く
/* * AWS IoT Device SDK for Embedded C 202103.00 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Standard includes. */ #include <assert.h> #include <stdlib.h> #include <string.h> /* POSIX includes. */ #include <unistd.h> /* Include Demo Config as the first non-system header. */ #include "demo_config.h" /* Common HTTP demo utilities. */ #include "http_demo_utils.h" /* HTTP API header. */ #include "core_http_client.h" /* OpenSSL transport header. */ #include "tls_freertos.h" #include "demo_header.h" /* Check that AWS IoT Core endpoint is defined. */ #define AWS_IOT_ENDPOINT CONFIG_AWS_IOT_ENDPOINT #ifndef ROOT_CA_PEM #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 static const uint8_t root_cert_auth_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; #else extern const uint8_t root_cert_auth_pem_start[] asm("_binary_root_cert_auth_pem_start"); #endif extern const uint8_t root_cert_auth_pem_end[] asm("_binary_root_cert_auth_pem_end"); #endif /* Check that a path for HTTP Method POST is defined. */ #ifndef POST_PATH #error "Please define a POST_PATH." #endif /* Check that a path for Root CA certificate is defined. */ /* Check that a path for the client certificate is defined. */ #ifndef CLIENT_CERTIFICATE_PEM extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start"); extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end"); #endif #ifndef CLIENT_PRIVATE_KEY_PEM extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start"); extern const uint8_t client_key_pem_end[] asm("_binary_client_key_end"); #endif /** * @brief ALPN protocol name to be sent as part of the ClientHello message. * * @note When using ALPN, port 443 must be used to connect to AWS IoT Core. */ #define IOT_CORE_ALPN_PROTOCOL_NAME "x-amzn-http-ca" /* Check that transport timeout for transport send and receive is defined. */ #ifndef TRANSPORT_SEND_RECV_TIMEOUT_MS #define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1500 ) #endif /* Check that size of the user buffer is defined. */ #ifndef USER_BUFFER_LENGTH #define USER_BUFFER_LENGTH ( 2048 ) #endif /* Check that a request body to send for the POST request is defined. */ #ifndef REQUEST_BODY #error "Please define a REQUEST_BODY." #endif /** * @brief The length of the AWS IoT Endpoint. */ #define AWS_IOT_ENDPOINT_LENGTH ( sizeof( AWS_IOT_ENDPOINT ) - 1 ) /** * @brief The length of the HTTP POST method. */ #define HTTP_METHOD_POST_LENGTH ( sizeof( HTTP_METHOD_POST ) - 1 ) /** * @brief The length of the HTTP POST path. */ #define POST_PATH_LENGTH ( sizeof( POST_PATH ) - 1 ) /** * @brief Length of the request body. */ #define REQUEST_BODY_LENGTH ( sizeof( REQUEST_BODY ) - 1 ) /** * @brief A buffer used in the demo for storing HTTP request headers and * HTTP response headers and body. * * @note This demo shows how the same buffer can be re-used for storing the HTTP * response after the HTTP request is sent out. However, the user can also * decide to use separate buffers for storing the HTTP request and response. */ static uint8_t userBuffer[ USER_BUFFER_LENGTH ]; /*-----------------------------------------------------------*/ /** * @brief Connect to HTTP server with reconnection retries. * * @param[out] pNetworkContext The output parameter to return the created network context. * * @return EXIT_FAILURE on failure; EXIT_SUCCESS on successful connection. */ static int32_t connectToServer( NetworkContext_t * pNetworkContext ); /** * @brief Send an HTTP request based on a specified method and path, then * print the response received from the server. * * @param[in] pTransportInterface The transport interface for making network calls. * @param[in] pMethod The HTTP request method. * @param[in] methodLen The length of the HTTP request method. * @param[in] pPath The Request-URI to the objects of interest. * @param[in] pathLen The length of the Request-URI. * * @return EXIT_FAILURE on failure; EXIT_SUCCESS on success. */ static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface, const char * pMethod, size_t methodLen, const char * pPath, size_t pathLen ); /*-----------------------------------------------------------*/ static int32_t connectToServer( NetworkContext_t * pNetworkContext ) { int32_t returnStatus = EXIT_FAILURE; /* Status returned by OpenSSL transport implementation. */ TlsTransportStatus_t opensslStatus; /* Credentials to establish the TLS connection. */ NetworkCredentials_t *opensslCredentials = (NetworkCredentials_t*) malloc (sizeof (NetworkCredentials_t)); /* Information about the server to send the HTTP requests. */ ServerInfo_t serverInfo; /* Initialize TLS credentials. */ opensslCredentials->pClientCert = ( const unsigned char * ) client_cert_pem_start; opensslCredentials->clientCertSize = client_cert_pem_end - client_cert_pem_start; opensslCredentials->pPrivateKey = ( const unsigned char * ) client_key_pem_start; opensslCredentials->privateKeySize = client_key_pem_end - client_key_pem_start; opensslCredentials->pRootCa = ( const unsigned char * ) root_cert_auth_pem_start; opensslCredentials->rootCaSize = root_cert_auth_pem_end - root_cert_auth_pem_start; opensslCredentials->disableSni = 0; /* ALPN is required when communicating to AWS IoT Core over port 443 through HTTP. */ if( AWS_HTTPS_PORT == 443 ) { static const char * pcAlpnProtocols[] = { NULL, NULL }; pcAlpnProtocols[0] = IOT_CORE_ALPN_PROTOCOL_NAME; opensslCredentials->pAlpnProtos = pcAlpnProtocols; } else { opensslCredentials->pAlpnProtos = NULL; } /* Initialize server information. */ serverInfo.pHostName = AWS_IOT_ENDPOINT; serverInfo.hostNameLength = AWS_IOT_ENDPOINT_LENGTH; serverInfo.port = AWS_HTTPS_PORT; /* Establish a TLS session with the HTTP server. This example connects * to the HTTP server as specified in AWS_IOT_ENDPOINT and AWS_HTTPS_PORT * in demo_config.h. */ LogInfo( ( "Establishing a TLS session to %.*s:%d.", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, AWS_HTTPS_PORT ) ); opensslStatus = TLS_FreeRTOS_Connect ( pNetworkContext, serverInfo.pHostName, serverInfo.port, opensslCredentials, TRANSPORT_SEND_RECV_TIMEOUT_MS, TRANSPORT_SEND_RECV_TIMEOUT_MS ); if( opensslStatus == TLS_TRANSPORT_SUCCESS ) { returnStatus = EXIT_SUCCESS; } else { returnStatus = EXIT_FAILURE; } return returnStatus; } /*-----------------------------------------------------------*/ static int32_t sendHttpRequest( const TransportInterface_t * pTransportInterface, const char * pMethod, size_t methodLen, const char * pPath, size_t pathLen ) { /* Return value of this method. */ int32_t returnStatus = EXIT_SUCCESS; /* Configurations of the initial request headers that are passed to * #HTTPClient_InitializeRequestHeaders. */ HTTPRequestInfo_t requestInfo; /* Represents a response returned from an HTTP server. */ HTTPResponse_t response; /* Represents header data that will be sent in an HTTP request. */ HTTPRequestHeaders_t requestHeaders; /* Return value of all methods from the HTTP Client library API. */ HTTPStatus_t httpStatus = HTTPSuccess; assert( pMethod != NULL ); assert( pPath != NULL ); /* Initialize all HTTP Client library API structs to 0. */ ( void ) memset( &requestInfo, 0, sizeof( requestInfo ) ); ( void ) memset( &response, 0, sizeof( response ) ); ( void ) memset( &requestHeaders, 0, sizeof( requestHeaders ) ); /* Initialize the request object. */ requestInfo.pHost = AWS_IOT_ENDPOINT; requestInfo.hostLen = AWS_IOT_ENDPOINT_LENGTH; requestInfo.pMethod = pMethod; requestInfo.methodLen = methodLen; requestInfo.pPath = pPath; requestInfo.pathLen = pathLen; /* Set "Connection" HTTP header to "keep-alive" so that multiple requests * can be sent over the same established TCP connection. */ requestInfo.reqFlags = HTTP_REQUEST_KEEP_ALIVE_FLAG; /* Set the buffer used for storing request headers. */ requestHeaders.pBuffer = userBuffer; requestHeaders.bufferLen = USER_BUFFER_LENGTH; httpStatus = HTTPClient_InitializeRequestHeaders( &requestHeaders, &requestInfo ); if( httpStatus == HTTPSuccess ) { /* Initialize the response object. The same buffer used for storing * request headers is reused here. */ response.pBuffer = userBuffer; response.bufferLen = USER_BUFFER_LENGTH; LogInfo( ( "Sending HTTP %.*s request to %.*s%.*s...", ( int32_t ) requestInfo.methodLen, requestInfo.pMethod, ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath ) ); LogDebug( ( "Request Headers:\n%.*s\n" "Request Body:\n%.*s\n", ( int32_t ) requestHeaders.headersLen, ( char * ) requestHeaders.pBuffer, ( int32_t ) REQUEST_BODY_LENGTH, REQUEST_BODY ) ); /* Send the request and receive the response. */ httpStatus = HTTPClient_Send( pTransportInterface, &requestHeaders, ( uint8_t * ) REQUEST_BODY, REQUEST_BODY_LENGTH, &response, 0 ); } else { LogError( ( "Failed to initialize HTTP request headers: Error=%s.", HTTPClient_strerror( httpStatus ) ) ); } if( httpStatus == HTTPSuccess ) { LogInfo( ( "Received HTTP response from %.*s%.*s...\n" "Response Headers:\n%.*s\n" "Response Status:\n%u\n" "Response Body:\n%.*s\n", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath, ( int32_t ) response.headersLen, response.pHeaders, response.statusCode, ( int32_t ) response.bodyLen, response.pBody ) ); } else { LogError( ( "Failed to send HTTP %.*s request to %.*s%.*s: Error=%s.", ( int32_t ) requestInfo.methodLen, requestInfo.pMethod, ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT, ( int32_t ) requestInfo.pathLen, requestInfo.pPath, HTTPClient_strerror( httpStatus ) ) ); } if( httpStatus != HTTPSuccess ) { returnStatus = EXIT_FAILURE; } return returnStatus; } /*-----------------------------------------------------------*/ /** * @brief Entry point of demo. * * This example resolves the AWS IoT Core endpoint, establishes a TCP connection, * performs a mutually authenticated TLS handshake occurs such that all further * communication is encrypted. After which, HTTP Client Library API is used to * make a POST request to AWS IoT Core in order to publish a message to a topic * named topic with QoS=1 so that all clients subscribed to the topic receive * the message at least once. Any possible errors are also logged. * * @note This example is single-threaded and uses statically allocated memory. * */ int aws_iot_demo_main( int argc, char ** argv ) { /* Return value of main. */ int32_t returnStatus = EXIT_SUCCESS; /* The transport layer interface used by the HTTP Client library. */ TransportInterface_t transportInterface; /* The network context for the transport layer interface. */ NetworkContext_t networkContext; ( void ) argc; ( void ) argv; /* Set the pParams member of the network context with desired transport. */ /**************************** Connect. ******************************/ /* Establish TLS connection on top of TCP connection using OpenSSL. */ if( returnStatus == EXIT_SUCCESS ) { LogInfo( ( "Performing TLS handshake on top of the TCP connection." ) ); /* Attempt to connect to the HTTP server. If connection fails, retry after * a timeout. Timeout value will be exponentially increased till the maximum * attempts are reached or maximum timeout value is reached. The function * returns EXIT_FAILURE if the TCP connection cannot be established to * broker after configured number of attempts. */ returnStatus = connectToServerWithBackoffRetries( connectToServer, &networkContext ); if( returnStatus == EXIT_FAILURE ) { /* Log error to indicate connection failure after all * reconnect attempts are over. */ LogError( ( "Failed to connect to HTTP server %.*s.", ( int32_t ) AWS_IOT_ENDPOINT_LENGTH, AWS_IOT_ENDPOINT ) ); } } /* Define the transport interface. */ if( returnStatus == EXIT_SUCCESS ) { ( void ) memset( &transportInterface, 0, sizeof( transportInterface ) ); transportInterface.recv = TLS_FreeRTOS_recv; transportInterface.send = TLS_FreeRTOS_send; transportInterface.pNetworkContext = &networkContext; } /*********************** Send HTTPS request. ************************/ if( returnStatus == EXIT_SUCCESS ) { returnStatus = sendHttpRequest( &transportInterface, HTTP_METHOD_POST, HTTP_METHOD_POST_LENGTH, POST_PATH, POST_PATH_LENGTH ); } if( returnStatus == EXIT_SUCCESS ) { /* Log message indicating an iteration completed successfully. */ LogInfo( ( "Demo completed successfully." ) ); } /************************** Disconnect. *****************************/ /* End TLS session, then close TCP connection. */ ( void ) TLS_FreeRTOS_Disconnect( &networkContext ); return returnStatus; }
違いを見つける