test

Committer:
peyo
Date:
Wed Apr 12 14:07:09 2017 +0200
Revision:
0:cd5404401c2f
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peyo 0:cd5404401c2f 1 #Porting Guide
peyo 0:cd5404401c2f 2
peyo 0:cd5404401c2f 3 ##Scope
peyo 0:cd5404401c2f 4 The scope of this document is to provide instructions to modify the provided source files and functions in this SDK to run in a variety of embedded C–based environments (e.g. real-time OS, embedded Linux) and to be adjusted to use a specific TLS implementation as available with specific hardware platforms.
peyo 0:cd5404401c2f 5
peyo 0:cd5404401c2f 6 ##Contents of the SDK
peyo 0:cd5404401c2f 7
peyo 0:cd5404401c2f 8 The SDK ported for linux can be downloaded from the below link:
peyo 0:cd5404401c2f 9 * [mbedTLS from ARM](https://s3.amazonaws.com/aws-iot-device-sdk-embedded-c/linux_mqtt_mbedtls-2.0.0.tar)
peyo 0:cd5404401c2f 10
peyo 0:cd5404401c2f 11 The C-code files of this SDK are delivered via the following directory structure (see comment behind folder name for an explanation of its content).
peyo 0:cd5404401c2f 12
peyo 0:cd5404401c2f 13 Current SDK Directory Layout (mbedTLS)
peyo 0:cd5404401c2f 14
peyo 0:cd5404401c2f 15 |--`certs` (Private key, device certificate and Root CA) <br>
peyo 0:cd5404401c2f 16 |--`docs` (Developer guide & API documentation) <br>
peyo 0:cd5404401c2f 17 |--`external_libs` (external libraries - jsmn, mbedTLS) <br>
peyo 0:cd5404401c2f 18 |--`include` (Header files of the AWS IoT device SDK) <br>
peyo 0:cd5404401c2f 19 |--`src` (Source files of the AWS IoT device SDK) <br>
peyo 0:cd5404401c2f 20 |--`platform` (Platform specific files) <br>
peyo 0:cd5404401c2f 21 |--`samples` (Samples including makefiles for building on mbedTLS) <br>
peyo 0:cd5404401c2f 22 |--`tests` (Tests for verifying SDK is functioning as expected) <br>
peyo 0:cd5404401c2f 23
peyo 0:cd5404401c2f 24 All makefiles in this SDK were configured using the documented folder structure above, so moving or renaming folders will require modifications to makefiles.
peyo 0:cd5404401c2f 25
peyo 0:cd5404401c2f 26 ##Explanation of folders and their content
peyo 0:cd5404401c2f 27
peyo 0:cd5404401c2f 28 * `certs` : This directory is initially empty and will need to contain the private key, the client certificate and the root CA. The client certificate and private key can be downloaded from the AWS IoT console or be created using the AWS CLI commands. The root CA can be downloaded from [Symantec](https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem).
peyo 0:cd5404401c2f 29
peyo 0:cd5404401c2f 30 * `docs` : SDK API and file documentation.
peyo 0:cd5404401c2f 31
peyo 0:cd5404401c2f 32 * `external_libs` : The mbedTLS and jsmn source files. The jsmn source files are always present. The mbedTLS source files are only included when downloading the tarball version of the SDK.
peyo 0:cd5404401c2f 33
peyo 0:cd5404401c2f 34 * `include` : This directory contains the header files that an application using the SDK needs to include.
peyo 0:cd5404401c2f 35
peyo 0:cd5404401c2f 36 * `src` : This directory contains the SDK source code including the MQTT library, device shadow code and utilities.
peyo 0:cd5404401c2f 37
peyo 0:cd5404401c2f 38 * `platform` : Platform specific files for timer, TLS and threading layers. Includes a reference implementation for the linux using mbedTLS and pthread.
peyo 0:cd5404401c2f 39
peyo 0:cd5404401c2f 40 * `samples` : This directory contains sample applications as well as their makefiles. The samples include a simple MQTT example which publishes and subscribes to the AWS IoT service as well as a device shadow example that shows example usage of the device shadow functionality.
peyo 0:cd5404401c2f 41
peyo 0:cd5404401c2f 42 * `tests` : Contains tests for verifying SDK functionality. For further details please check the readme file included with the tests [here](https://github.com/aws/aws-iot-device-sdk-embedded-C/blob/master/tests/README.md/).
peyo 0:cd5404401c2f 43
peyo 0:cd5404401c2f 44 ##Integrating the SDK into your environment
peyo 0:cd5404401c2f 45
peyo 0:cd5404401c2f 46 This section explains the API calls that need to be implemented in order for the Device SDK to run on your platform. The SDK interfaces follow the driver model where only prototypes are defined by the Device SDK itself while the implementation is delegated to the user of the SDK to adjust it to the platform in use. The following sections list the needed functionality for the device SDK to run successfully on any given platform.
peyo 0:cd5404401c2f 47
peyo 0:cd5404401c2f 48 ###Timer Functions
peyo 0:cd5404401c2f 49
peyo 0:cd5404401c2f 50 A timer implementation is necessary to handle request timeouts (sending MQTT connect, subscribe, etc. commands) as well as connection maintenance (MQTT keep-alive pings). Timers need millisecond resolution and are polled for expiration so these can be implemented using a "milliseconds since startup" free-running counter if desired. In the synchronous sample provided with this SDK only one command will be "in flight" at one point in time plus the client's ping timer.
peyo 0:cd5404401c2f 51
peyo 0:cd5404401c2f 52 Define the `Timer` Struct as in `timer_platform.h`
peyo 0:cd5404401c2f 53
peyo 0:cd5404401c2f 54 `void init_timer(Timer *);`
peyo 0:cd5404401c2f 55 init_timer - A timer structure is initialized to a clean state.
peyo 0:cd5404401c2f 56
peyo 0:cd5404401c2f 57 `bool has_timer_expired(Timer *);`
peyo 0:cd5404401c2f 58 has_timer_expired - a polling function to determine if the timer has expired.
peyo 0:cd5404401c2f 59
peyo 0:cd5404401c2f 60 `void countdown_ms(Timer *, uint32_t);`
peyo 0:cd5404401c2f 61 countdown_ms - set the timer to expire in x milliseconds and start the timer.
peyo 0:cd5404401c2f 62
peyo 0:cd5404401c2f 63 `void countdown_sec(Timer *, uint32_t);`
peyo 0:cd5404401c2f 64 countdown_sec - set the timer to expire in x seconds and start the timer.
peyo 0:cd5404401c2f 65
peyo 0:cd5404401c2f 66 `uint32_t left_ms(Timer *);`
peyo 0:cd5404401c2f 67 left_ms - query time in milliseconds left on the timer.
peyo 0:cd5404401c2f 68
peyo 0:cd5404401c2f 69
peyo 0:cd5404401c2f 70 ###Network Functions
peyo 0:cd5404401c2f 71
peyo 0:cd5404401c2f 72 In order for the MQTT client stack to be able to communicate via the TCP/IP network protocol stack using a mutually authenticated TLS connection, the following API calls need to be implemented for your platform.
peyo 0:cd5404401c2f 73
peyo 0:cd5404401c2f 74 For additional details about API parameters refer to the [API documentation](http://aws-iot-device-sdk-embedded-c-docs.s3-website-us-east-1.amazonaws.com/index.html).
peyo 0:cd5404401c2f 75
peyo 0:cd5404401c2f 76 Define the `TLSDataParams` Struct as in `network_platform.h`
peyo 0:cd5404401c2f 77 This is used for data specific to the TLS library being used.
peyo 0:cd5404401c2f 78
peyo 0:cd5404401c2f 79 `IoT_Error_t iot_tls_init(Network *pNetwork, char *pRootCALocation, char *pDeviceCertLocation,
peyo 0:cd5404401c2f 80 char *pDevicePrivateKeyLocation, char *pDestinationURL,
peyo 0:cd5404401c2f 81 uint16_t DestinationPort, uint32_t timeout_ms, bool ServerVerificationFlag);`
peyo 0:cd5404401c2f 82 Initialize the network client / structure.
peyo 0:cd5404401c2f 83
peyo 0:cd5404401c2f 84 `IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *TLSParams);`
peyo 0:cd5404401c2f 85 Create a TLS TCP socket to the configure address using the credentials provided via the NewNetwork API call. This will include setting up certificate locations / arrays.
peyo 0:cd5404401c2f 86
peyo 0:cd5404401c2f 87
peyo 0:cd5404401c2f 88 `IoT_Error_t iot_tls_write(Network*, unsigned char*, size_t, Timer *, size_t *);`
peyo 0:cd5404401c2f 89 Write to the TLS network buffer.
peyo 0:cd5404401c2f 90
peyo 0:cd5404401c2f 91 `IoT_Error_t iot_tls_read(Network*, unsigned char*, size_t, Timer *, size_t *);`
peyo 0:cd5404401c2f 92 Read from the TLS network buffer.
peyo 0:cd5404401c2f 93
peyo 0:cd5404401c2f 94 `IoT_Error_t iot_tls_disconnect(Network *pNetwork);`
peyo 0:cd5404401c2f 95 Disconnect API
peyo 0:cd5404401c2f 96
peyo 0:cd5404401c2f 97 `IoT_Error_t iot_tls_destroy(Network *pNetwork);`
peyo 0:cd5404401c2f 98 Clean up the connection
peyo 0:cd5404401c2f 99
peyo 0:cd5404401c2f 100 `IoT_Error_t iot_tls_is_connected(Network *pNetwork);`
peyo 0:cd5404401c2f 101 Check if the TLS layer is still connected
peyo 0:cd5404401c2f 102
peyo 0:cd5404401c2f 103 The TLS library generally provides the API for the underlying TCP socket.
peyo 0:cd5404401c2f 104
peyo 0:cd5404401c2f 105
peyo 0:cd5404401c2f 106 ###Threading Functions
peyo 0:cd5404401c2f 107
peyo 0:cd5404401c2f 108 The MQTT client uses a state machine to control operations in multi-threaded situations. However it requires a mutex implementation to guarantee thread safety. This is not required in situations where thread safety is not important and it is disabled by default. The _ENABLE_THREAD_SUPPORT_ macro needs to be defined in aws_iot_config.h to enable this layer. You will also need to add the -lpthread linker flag for the compiler if you are using the provided reference implementation.
peyo 0:cd5404401c2f 109
peyo 0:cd5404401c2f 110 For additional details about API parameters refer to the [API documentation](http://aws-iot-device-sdk-embedded-c-docs.s3-website-us-east-1.amazonaws.com/index.html).
peyo 0:cd5404401c2f 111
peyo 0:cd5404401c2f 112 Define the `IoT_Mutex_t` Struct as in `threads_platform.h`
peyo 0:cd5404401c2f 113 This is used for data specific to the TLS library being used.
peyo 0:cd5404401c2f 114
peyo 0:cd5404401c2f 115 `IoT_Error_t aws_iot_thread_mutex_init(IoT_Mutex_t *);`
peyo 0:cd5404401c2f 116 Initialize the mutex provided as argument.
peyo 0:cd5404401c2f 117
peyo 0:cd5404401c2f 118 `IoT_Error_t aws_iot_thread_mutex_lock(IoT_Mutex_t *);`
peyo 0:cd5404401c2f 119 Lock the mutex provided as argument
peyo 0:cd5404401c2f 120
peyo 0:cd5404401c2f 121 `IoT_Error_t aws_iot_thread_mutex_unlock(IoT_Mutex_t *);`
peyo 0:cd5404401c2f 122 Unlock the mutex provided as argument.
peyo 0:cd5404401c2f 123
peyo 0:cd5404401c2f 124 `IoT_Error_t aws_iot_thread_mutex_destroy(IoT_Mutex_t *);`
peyo 0:cd5404401c2f 125 Destroy the mutex provided as argument.
peyo 0:cd5404401c2f 126
peyo 0:cd5404401c2f 127 The threading layer provides the implementation of mutexes used for thread-safe operations.
peyo 0:cd5404401c2f 128
peyo 0:cd5404401c2f 129 ###Sample Porting:
peyo 0:cd5404401c2f 130
peyo 0:cd5404401c2f 131 Marvell has ported the SDK for their development boards. [These](https://github.com/marvell-iot/aws_starter_sdk/tree/master/sdk/external/aws_iot/platform/wmsdk) files are example implementations of the above mentioned functions.
peyo 0:cd5404401c2f 132 This provides a port of the timer and network layer. The threading layer is not a part of this port.
peyo 0:cd5404401c2f 133
peyo 0:cd5404401c2f 134 ##Time source for certificate validation
peyo 0:cd5404401c2f 135
peyo 0:cd5404401c2f 136 As part of the TLS handshake the device (client) needs to validate the server certificate which includes validation of the certificate lifetime requiring that the device is aware of the actual time. Devices should be equipped with a real time clock or should be able to obtain the current time via NTP. Bypassing validation of the lifetime of a certificate is not recommended as it exposes the device to a security vulnerability, as it will still accept server certificates even when they have already has_timer_expired.
peyo 0:cd5404401c2f 137
peyo 0:cd5404401c2f 138 ##Integration into operating system
peyo 0:cd5404401c2f 139 ###Single-Threaded implementation
peyo 0:cd5404401c2f 140
peyo 0:cd5404401c2f 141 The single threaded implementation implies that the sample application code (SDK + MQTT client) is called periodically by the firmware application running on the main thread. This is done by calling the function `aws_iot_mqtt_yield` (in the simple pub-sub example) and by calling `aws_iot_shadow_yield()` (in the device shadow example). In both cases the keep-alive time is set to 10 seconds. This means that the yield functions need to be called at a minimum frequency of once every 10 seconds. Note however that the `iot_mqtt_yield()` function takes care of reading incoming MQTT messages from the IoT service as well and hence should be called more frequently depending on the timing requirements of an application. All incoming messages can only be processed at the frequency at which `yield` is called.
peyo 0:cd5404401c2f 142
peyo 0:cd5404401c2f 143 ###Multi-Threaded implementation
peyo 0:cd5404401c2f 144
peyo 0:cd5404401c2f 145 In the simple multi-threaded case the `yield` function can be moved to a background thread. Ensure this task runs at the frequency described above. In this case, depending on the OS mechanism, a message queue or mailbox could be used to proxy incoming MQTT messages from the callback to the worker task responsible for responding to or dispatching messages. A similar mechanism could be employed to queue publish messages from threads into a publish queue that are processed by a publishing task. Ensure the threading layer is enabled as the library is not thread safe otherwise.
peyo 0:cd5404401c2f 146 There is a validation test for the multi-threaded implementation that can be found with the integration tests. You can find further details in the Readme for the integration tests [here](https://github.com/aws/aws-iot-device-sdk-embedded-C/blob/master/tests/integration/README.md). We have run the validation test with 10 threads sending 500 messages each and verified to be working fine. It can be used as a reference testing application to validate whether your use case will work with multi-threading enabled.
peyo 0:cd5404401c2f 147
peyo 0:cd5404401c2f 148 ##Sample applications
peyo 0:cd5404401c2f 149
peyo 0:cd5404401c2f 150 The sample apps in this SDK provide a working implementation for mbedTLS. They use a reference implementation for linux provided with the SDK. Threading layer is enabled in the subscribe publish sample.