FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:35:07 2017 +0000
Revision:
0:a2cb7295a1f7
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a2cb7295a1f7 1 <span class="notes">**Note:** To port mbed Client, you need to [install yotta and its dependencies](https://github.com/ARMmbed/yotta/blob/master/docs/index.md).</span>
ram54288 0:a2cb7295a1f7 2
ram54288 0:a2cb7295a1f7 3 # mbed Client structure and build process
ram54288 0:a2cb7295a1f7 4
ram54288 0:a2cb7295a1f7 5 <span class="tips">**Tip:** Before embarking on your own port, you should build the core mbed Client for an existing compilation target to get an understanding of how the mbed Client builds.</span>
ram54288 0:a2cb7295a1f7 6
ram54288 0:a2cb7295a1f7 7 mbed Client is structured as a set of modules. Each module declares which other modules it depends on. When you build a module, our build system `yotta` looks at these dependencies and installs the necessary modules before completing the build.
ram54288 0:a2cb7295a1f7 8
ram54288 0:a2cb7295a1f7 9 This is also the process to build applications for the mbed Client (including the example application in the release). The application declares dependencies on the mbed Client and when it is built, `yotta` ensures that the modules (and anything that they depend on, recursively) are present before building.
ram54288 0:a2cb7295a1f7 10
ram54288 0:a2cb7295a1f7 11 In general, `yotta` downloads and installs the necessary modules over the internet from the public yotta Registry (which saves published versions of modules) or from a specified source control URL.
ram54288 0:a2cb7295a1f7 12
ram54288 0:a2cb7295a1f7 13 # Components of mbed Client
ram54288 0:a2cb7295a1f7 14
ram54288 0:a2cb7295a1f7 15 ## Component software modules
ram54288 0:a2cb7295a1f7 16
ram54288 0:a2cb7295a1f7 17 mbed Client consists of one main component. More major components will be added in future development phases:
ram54288 0:a2cb7295a1f7 18
ram54288 0:a2cb7295a1f7 19 * `mbed-client` is the core mbed Client, providing C++ APIs for the mbed Client.
ram54288 0:a2cb7295a1f7 20
ram54288 0:a2cb7295a1f7 21 This module depends on further internal modules:
ram54288 0:a2cb7295a1f7 22
ram54288 0:a2cb7295a1f7 23 ```
ram54288 0:a2cb7295a1f7 24 mbed-client x.x.x
ram54288 0:a2cb7295a1f7 25 |
ram54288 0:a2cb7295a1f7 26 |_mbed-client-c x.x.x
ram54288 0:a2cb7295a1f7 27 | |_mbed-client-libservice x.x.x
ram54288 0:a2cb7295a1f7 28 |
ram54288 0:a2cb7295a1f7 29 |_mbed-client-linux x.x.x
ram54288 0:a2cb7295a1f7 30 ```
ram54288 0:a2cb7295a1f7 31
ram54288 0:a2cb7295a1f7 32 To list the dependency trees, use the [`yotta list --all` command](http://docs.yottabuild.org/reference/commands.html).
ram54288 0:a2cb7295a1f7 33
ram54288 0:a2cb7295a1f7 34 <span class="notes">**Note**: In this case, we have listed the dependencies for the `x86-linux-native` compilation target. Different modules are needed for different compilation targets.</span>
ram54288 0:a2cb7295a1f7 35
ram54288 0:a2cb7295a1f7 36 We are using the [mbed Client Linux example](https://github.com/ARMmbed/mbed-client-linux-example) in this document. You can see that it depends directly only on the `mbed-client` and `mbed-client-linux` modules. These modules depend internally on various other modules.
ram54288 0:a2cb7295a1f7 37
ram54288 0:a2cb7295a1f7 38 ```
ram54288 0:a2cb7295a1f7 39 mbed-client-linux-example x.x.x
ram54288 0:a2cb7295a1f7 40 |
ram54288 0:a2cb7295a1f7 41 |_mbed-client x.x.x
ram54288 0:a2cb7295a1f7 42 |
ram54288 0:a2cb7295a1f7 43 |_mbed-client-c x.x.x
ram54288 0:a2cb7295a1f7 44 | |_mbed-client-libservice x.x.x
ram54288 0:a2cb7295a1f7 45 |
ram54288 0:a2cb7295a1f7 46 |_mbed-client-linux x.x.x
ram54288 0:a2cb7295a1f7 47 ```
ram54288 0:a2cb7295a1f7 48
ram54288 0:a2cb7295a1f7 49 ## Compilation targets
ram54288 0:a2cb7295a1f7 50
ram54288 0:a2cb7295a1f7 51 To compile for a target board, you need a [target description](http://docs.yottabuild.org/tutorial/targets.html) that describes how to compile for the target.
ram54288 0:a2cb7295a1f7 52
ram54288 0:a2cb7295a1f7 53 The `mbed-client` module uses the platform name that each target defines to choose which `mbed-client-<platform-name>` module to depend on to provide the platform-specific implementation.
ram54288 0:a2cb7295a1f7 54
ram54288 0:a2cb7295a1f7 55 # Porting mbed Client to a different platform
ram54288 0:a2cb7295a1f7 56
ram54288 0:a2cb7295a1f7 57 To port mbed Client to a new platform:
ram54288 0:a2cb7295a1f7 58
ram54288 0:a2cb7295a1f7 59 1. [Request for a development repository](#requesting-for-a-development-repository).
ram54288 0:a2cb7295a1f7 60 2. [Create a yotta compilation target for your board](#creating-a-yotta-compilation-target).
ram54288 0:a2cb7295a1f7 61 3. [Implement the `mbed-client-xxx` module for your target platform](#implementing-mbed-client-xxx).
ram54288 0:a2cb7295a1f7 62 4. [Modify the `module.json` of the `mbed-client` module](#modifying-the-json-file-in-the-mbed-client-module).
ram54288 0:a2cb7295a1f7 63 5. [Verify that your implementation is correct](#testing-and-verification).
ram54288 0:a2cb7295a1f7 64
ram54288 0:a2cb7295a1f7 65 The `yotta` build system is designed for easy reuse of generic modules. If you intend to support multiple platforms that share common features, we recommend moving the common functionality into a separate module and use it for each platform.
ram54288 0:a2cb7295a1f7 66
ram54288 0:a2cb7295a1f7 67 ## Requesting for a development repository
ram54288 0:a2cb7295a1f7 68
ram54288 0:a2cb7295a1f7 69 We provide private git repositories to our partners porting mbed Client. Only the members of the mbed Client team and relevant partner contacts and engineers have access to these repositories.
ram54288 0:a2cb7295a1f7 70
ram54288 0:a2cb7295a1f7 71 When you contact `support@mbed.org`, a repository will be created for your module. You also need to provide the target description of your board as follows:
ram54288 0:a2cb7295a1f7 72
ram54288 0:a2cb7295a1f7 73 - **`mbed-client-<platform-name>`** is the module that provides the `mbed-client-xxx` implementation for your platform. You may choose to split it into further modules in the future, to enable sharing of code, but we recommend that you implement the port for your first board in this module itself.
ram54288 0:a2cb7295a1f7 74
ram54288 0:a2cb7295a1f7 75 - **`target-<targetname>`** contains the yotta target description of the target you are porting to. This is usually your platform name.
ram54288 0:a2cb7295a1f7 76
ram54288 0:a2cb7295a1f7 77 ## Creating a yotta compilation target
ram54288 0:a2cb7295a1f7 78
ram54288 0:a2cb7295a1f7 79 An example on compiling for linux target can be found in the `yotta_targets` directory of [the example application] (https://github.com/ARMmbed/mbed-client-linux-example).
ram54288 0:a2cb7295a1f7 80
ram54288 0:a2cb7295a1f7 81 Please, refer to the [yotta documentation](http://yottadocs.mbed.com/tutorial/targets.html) for setting up your compilation target.
ram54288 0:a2cb7295a1f7 82
ram54288 0:a2cb7295a1f7 83 1.To make your target available locally (without publishing it), you use the `yotta link-target` command to link it into the global install targets directory:
ram54288 0:a2cb7295a1f7 84
ram54288 0:a2cb7295a1f7 85 ```
ram54288 0:a2cb7295a1f7 86 # in the directory of your target:
ram54288 0:a2cb7295a1f7 87 yotta link-target
ram54288 0:a2cb7295a1f7 88 ```
ram54288 0:a2cb7295a1f7 89
ram54288 0:a2cb7295a1f7 90 2.Use `yotta link-target <targetname>` command to make the globally linked target available when compiling another module.
ram54288 0:a2cb7295a1f7 91
ram54288 0:a2cb7295a1f7 92 3.Use the `yotta target <targetname>` command to select your target for the compilation.
ram54288 0:a2cb7295a1f7 93
ram54288 0:a2cb7295a1f7 94 ## Implementing mbed-client-xxx
ram54288 0:a2cb7295a1f7 95
ram54288 0:a2cb7295a1f7 96 Clone your `mbed-client-<your-platform-name>` module and `mbed-client` modules from GitHub.
ram54288 0:a2cb7295a1f7 97
ram54288 0:a2cb7295a1f7 98 The `mbed-client-<your-platform-name>` module needs to provide a socket and timer implementation for your target platform. The `mbed-client-xxx` module should include files `m2mconnectionhandler.h`and `m2mtimer.h` from `mbed-client` and implement a corresponding `.cpp` file that points to the platform-specific private implementations of the timer and the socket.
ram54288 0:a2cb7295a1f7 99
ram54288 0:a2cb7295a1f7 100 <span class="notes">**Note**: Private implementation classes **must** be named as `M2MConnectionHandlerPimpl` and `M2MTimerPimpl`, because of forward declarations.</span>
ram54288 0:a2cb7295a1f7 101
ram54288 0:a2cb7295a1f7 102 An example of mbed-client-platform:
ram54288 0:a2cb7295a1f7 103
ram54288 0:a2cb7295a1f7 104 ```
ram54288 0:a2cb7295a1f7 105 |_module.json
ram54288 0:a2cb7295a1f7 106 |
ram54288 0:a2cb7295a1f7 107 |_mbed-client-platform
ram54288 0:a2cb7295a1f7 108 | |_m2mconnectionhandlerpimpl.h
ram54288 0:a2cb7295a1f7 109 | |_m2mtimerpimpl.h
ram54288 0:a2cb7295a1f7 110 |
ram54288 0:a2cb7295a1f7 111 |_source
ram54288 0:a2cb7295a1f7 112 |_m2mconnectionhandler.cpp
ram54288 0:a2cb7295a1f7 113 |_m2mconnectionhandlerpimpl.cpp
ram54288 0:a2cb7295a1f7 114 |_m2mtimer.cpp
ram54288 0:a2cb7295a1f7 115 |_m2mtimerpimpl.cpp
ram54288 0:a2cb7295a1f7 116 ```
ram54288 0:a2cb7295a1f7 117
ram54288 0:a2cb7295a1f7 118 To make your module available to other modules that you want to build, you need to use the [`yotta link`](http://docs.yottabuild.org/reference/commands.html#yotta-link) command to link it to the module where you want to test it out.
ram54288 0:a2cb7295a1f7 119
ram54288 0:a2cb7295a1f7 120 For example, to use your local your in-development mbed-client implementation, use the command `yotta link mbed-client-xxx` in the main `mbed-client` module.
ram54288 0:a2cb7295a1f7 121
ram54288 0:a2cb7295a1f7 122 ```
ram54288 0:a2cb7295a1f7 123 # in mbed-client, link your module:
ram54288 0:a2cb7295a1f7 124 yotta link mbed-client-xxx
ram54288 0:a2cb7295a1f7 125 ```
ram54288 0:a2cb7295a1f7 126
ram54288 0:a2cb7295a1f7 127 You can also just commit and push your untested code to GitHub, but it is always a good idea to test before committing.
ram54288 0:a2cb7295a1f7 128
ram54288 0:a2cb7295a1f7 129 Your `mbed-client-xxx` module must provide a platform-specific implementation for the mbed-client. The APIs that need porting are defined in the `mbed-client-linux` module. The header files contain documentation alongside the declaration of each function, where the function is described along with its parameters and return value.
ram54288 0:a2cb7295a1f7 130
ram54288 0:a2cb7295a1f7 131 There are two header files that require porting for your platform:
ram54288 0:a2cb7295a1f7 132
ram54288 0:a2cb7295a1f7 133 - `m2mconnectionhandler.h`
ram54288 0:a2cb7295a1f7 134 - `m2mtimer.h`
ram54288 0:a2cb7295a1f7 135
ram54288 0:a2cb7295a1f7 136 To see how this is done in Linux, check the `mbed-client-linux` module from the mbed [Client Linux Example](https://github.com/ARMmbed/mbed-client-linux-example).
ram54288 0:a2cb7295a1f7 137
ram54288 0:a2cb7295a1f7 138 ### Implementing the M2MConnectionHandler class for your platform
ram54288 0:a2cb7295a1f7 139
ram54288 0:a2cb7295a1f7 140 ```
ram54288 0:a2cb7295a1f7 141 /*
ram54288 0:a2cb7295a1f7 142 * Copyright (c) 2015 ARM. All rights reserved.
ram54288 0:a2cb7295a1f7 143 */
ram54288 0:a2cb7295a1f7 144 #ifndef M2M_CONNECTION_HANDLER_H__
ram54288 0:a2cb7295a1f7 145 #define M2M_CONNECTION_HANDLER_H__
ram54288 0:a2cb7295a1f7 146
ram54288 0:a2cb7295a1f7 147 #include "mbed-client/m2mconfig.h"
ram54288 0:a2cb7295a1f7 148 #include "mbed-client/m2minterface.h"
ram54288 0:a2cb7295a1f7 149 #include "mbed-client/m2mconnectionobserver.h"
ram54288 0:a2cb7295a1f7 150 #include "nsdl-c/sn_nsdl.h"
ram54288 0:a2cb7295a1f7 151
ram54288 0:a2cb7295a1f7 152 /**
ram54288 0:a2cb7295a1f7 153 * \brief M2MConnectionHandler.
ram54288 0:a2cb7295a1f7 154 * This class handles the socket connection for the LWM2M Client.
ram54288 0:a2cb7295a1f7 155 */
ram54288 0:a2cb7295a1f7 156
ram54288 0:a2cb7295a1f7 157 class M2MConnectionHandler {
ram54288 0:a2cb7295a1f7 158 public:
ram54288 0:a2cb7295a1f7 159
ram54288 0:a2cb7295a1f7 160 /**
ram54288 0:a2cb7295a1f7 161 * @enum ConnectionError
ram54288 0:a2cb7295a1f7 162 * This enum defines an error that can come from
ram54288 0:a2cb7295a1f7 163 * socket read and write operation.
ram54288 0:a2cb7295a1f7 164 */
ram54288 0:a2cb7295a1f7 165 typedef enum {
ram54288 0:a2cb7295a1f7 166 CONNECTION_ERROR_WANTS_READ = -1000,
ram54288 0:a2cb7295a1f7 167 CONNECTION_ERROR_WANTS_WRITE = -1001,
ram54288 0:a2cb7295a1f7 168 ERROR_NONE = 0,
ram54288 0:a2cb7295a1f7 169 SSL_CONNECTION_ERROR,
ram54288 0:a2cb7295a1f7 170 SOCKET_READ_ERROR,
ram54288 0:a2cb7295a1f7 171 SOCKET_SEND_ERROR,
ram54288 0:a2cb7295a1f7 172 SOCKET_ABORT,
ram54288 0:a2cb7295a1f7 173 DNS_RESOLVING_ERROR,
ram54288 0:a2cb7295a1f7 174 SSL_HANDSHAKE_ERROR
ram54288 0:a2cb7295a1f7 175 }ConnectionError;
ram54288 0:a2cb7295a1f7 176
ram54288 0:a2cb7295a1f7 177
ram54288 0:a2cb7295a1f7 178 public:
ram54288 0:a2cb7295a1f7 179
ram54288 0:a2cb7295a1f7 180 /**
ram54288 0:a2cb7295a1f7 181 * \brief Constructor
ram54288 0:a2cb7295a1f7 182 */
ram54288 0:a2cb7295a1f7 183 M2MConnectionHandler(M2MConnectionObserver &observer,
ram54288 0:a2cb7295a1f7 184 M2MConnectionSecurity* sec,
ram54288 0:a2cb7295a1f7 185 M2MInterface::BindingMode mode,
ram54288 0:a2cb7295a1f7 186 M2MInterface::NetworkStack stack);
ram54288 0:a2cb7295a1f7 187
ram54288 0:a2cb7295a1f7 188 /**
ram54288 0:a2cb7295a1f7 189 * \brief Destructor
ram54288 0:a2cb7295a1f7 190 */
ram54288 0:a2cb7295a1f7 191 ~M2MConnectionHandler();
ram54288 0:a2cb7295a1f7 192
ram54288 0:a2cb7295a1f7 193 /**
ram54288 0:a2cb7295a1f7 194 * \brief This binds the socket connection.
ram54288 0:a2cb7295a1f7 195 * \param listen_port Port to be listened to for an incoming connection.
ram54288 0:a2cb7295a1f7 196 * \return True if successful, else false.
ram54288 0:a2cb7295a1f7 197 */
ram54288 0:a2cb7295a1f7 198 bool bind_connection(const uint16_t listen_port);
ram54288 0:a2cb7295a1f7 199
ram54288 0:a2cb7295a1f7 200 /**
ram54288 0:a2cb7295a1f7 201 * \brief This resolves the server address. Output is
ram54288 0:a2cb7295a1f7 202 * returned through a callback.
ram54288 0:a2cb7295a1f7 203 * \param String The server address.
ram54288 0:a2cb7295a1f7 204 * \param uint16_t The server port.
ram54288 0:a2cb7295a1f7 205 * \param ServerType The server type to be resolved.
ram54288 0:a2cb7295a1f7 206 * \param security The M2MSecurity object that determines which
ram54288 0:a2cb7295a1f7 207 * type of secure connection will be used by the socket.
ram54288 0:a2cb7295a1f7 208 * \return True if address is valid, else false.
ram54288 0:a2cb7295a1f7 209 */
ram54288 0:a2cb7295a1f7 210 bool resolve_server_address(const String& server_address,
ram54288 0:a2cb7295a1f7 211 const uint16_t server_port,
ram54288 0:a2cb7295a1f7 212 M2MConnectionObserver::ServerType server_type,
ram54288 0:a2cb7295a1f7 213 const M2MSecurity* security);
ram54288 0:a2cb7295a1f7 214
ram54288 0:a2cb7295a1f7 215 /**
ram54288 0:a2cb7295a1f7 216 * \brief Sends data to the connected server.
ram54288 0:a2cb7295a1f7 217 * \param data_ptr The data to be sent.
ram54288 0:a2cb7295a1f7 218 * \param data_len The length of data to be sent.
ram54288 0:a2cb7295a1f7 219 * \param address_ptr The address structure to which the data needs to be sent.
ram54288 0:a2cb7295a1f7 220 * \return True if data is sent successfully, else false.
ram54288 0:a2cb7295a1f7 221 */
ram54288 0:a2cb7295a1f7 222 bool send_data(uint8_t *data_ptr,
ram54288 0:a2cb7295a1f7 223 uint16_t data_len,
ram54288 0:a2cb7295a1f7 224 sn_nsdl_addr_s *address_ptr);
ram54288 0:a2cb7295a1f7 225
ram54288 0:a2cb7295a1f7 226 /**
ram54288 0:a2cb7295a1f7 227 * \brief Listens to the incoming data from a remote server.
ram54288 0:a2cb7295a1f7 228 * \return True if successful, else false.
ram54288 0:a2cb7295a1f7 229 */
ram54288 0:a2cb7295a1f7 230 bool start_listening_for_data();
ram54288 0:a2cb7295a1f7 231
ram54288 0:a2cb7295a1f7 232 /**
ram54288 0:a2cb7295a1f7 233 * \brief Stops listening to the incoming data.
ram54288 0:a2cb7295a1f7 234 */
ram54288 0:a2cb7295a1f7 235 void stop_listening();
ram54288 0:a2cb7295a1f7 236
ram54288 0:a2cb7295a1f7 237 /**
ram54288 0:a2cb7295a1f7 238 * \brief Sends directly to the socket. This is used by
ram54288 0:a2cb7295a1f7 239 * security classes to send the data after it has been encrypted.
ram54288 0:a2cb7295a1f7 240 * \param buf Buffer to send.
ram54288 0:a2cb7295a1f7 241 * \param len The length of the buffer.
ram54288 0:a2cb7295a1f7 242 * \return Number of bytes sent or -1 if failed.
ram54288 0:a2cb7295a1f7 243 */
ram54288 0:a2cb7295a1f7 244 int send_to_socket(const unsigned char *buf, size_t len);
ram54288 0:a2cb7295a1f7 245
ram54288 0:a2cb7295a1f7 246 /**
ram54288 0:a2cb7295a1f7 247 * \brief Receives directly from the socket. This
ram54288 0:a2cb7295a1f7 248 * is used by the security classes to receive raw data to be decrypted.
ram54288 0:a2cb7295a1f7 249 * \param buf Buffer to send.
ram54288 0:a2cb7295a1f7 250 * \param len The length of the buffer.
ram54288 0:a2cb7295a1f7 251 * \return Number of bytes read or -1 if failed.
ram54288 0:a2cb7295a1f7 252 */
ram54288 0:a2cb7295a1f7 253 int receive_from_socket(unsigned char *buf, size_t len);
ram54288 0:a2cb7295a1f7 254
ram54288 0:a2cb7295a1f7 255 /**
ram54288 0:a2cb7295a1f7 256 * \brief Closes the open connection.
ram54288 0:a2cb7295a1f7 257 */
ram54288 0:a2cb7295a1f7 258 void close_connection();
ram54288 0:a2cb7295a1f7 259
ram54288 0:a2cb7295a1f7 260 /**
ram54288 0:a2cb7295a1f7 261 * \brief Error handling for DTLS connectivity.
ram54288 0:a2cb7295a1f7 262 * \param error Error code from the TLS library.
ram54288 0:a2cb7295a1f7 263 */
ram54288 0:a2cb7295a1f7 264 void handle_connection_error(int error);
ram54288 0:a2cb7295a1f7 265
ram54288 0:a2cb7295a1f7 266 /**
ram54288 0:a2cb7295a1f7 267 * \brief Sets the network interface handler that is used by client to connect
ram54288 0:a2cb7295a1f7 268 * to a network over IP..
ram54288 0:a2cb7295a1f7 269 * \param handler A network interface handler that is used by client to connect.
ram54288 0:a2cb7295a1f7 270 * This API is optional but provides a mechanism for different platforms to
ram54288 0:a2cb7295a1f7 271 * manage usage of underlying network interface by client.
ram54288 0:a2cb7295a1f7 272 */
ram54288 0:a2cb7295a1f7 273 void set_platform_network_handler(void *handler = NULL);
ram54288 0:a2cb7295a1f7 274
ram54288 0:a2cb7295a1f7 275 /**
ram54288 0:a2cb7295a1f7 276 * \brief Claims mutex to prevent thread clashes
ram54288 0:a2cb7295a1f7 277 * in multithreaded environment.
ram54288 0:a2cb7295a1f7 278 */
ram54288 0:a2cb7295a1f7 279 void claim_mutex();
ram54288 0:a2cb7295a1f7 280
ram54288 0:a2cb7295a1f7 281 /**
ram54288 0:a2cb7295a1f7 282 * \brief Releases mutex to prevent thread clashes
ram54288 0:a2cb7295a1f7 283 * in multithreaded environment.
ram54288 0:a2cb7295a1f7 284 */
ram54288 0:a2cb7295a1f7 285 void release_mutex();
ram54288 0:a2cb7295a1f7 286
ram54288 0:a2cb7295a1f7 287 private:
ram54288 0:a2cb7295a1f7 288
ram54288 0:a2cb7295a1f7 289 M2MConnectionObserver &_observer;
ram54288 0:a2cb7295a1f7 290 M2MConnectionHandlerPimpl *_private_impl;
ram54288 0:a2cb7295a1f7 291
ram54288 0:a2cb7295a1f7 292 friend class Test_M2MConnectionHandler;
ram54288 0:a2cb7295a1f7 293 friend class Test_M2MConnectionHandler_mbed;
ram54288 0:a2cb7295a1f7 294 friend class Test_M2MConnectionHandler_linux;
ram54288 0:a2cb7295a1f7 295 friend class M2MConnection_TestObserver;
ram54288 0:a2cb7295a1f7 296 };
ram54288 0:a2cb7295a1f7 297
ram54288 0:a2cb7295a1f7 298 #endif //M2M_CONNECTION_HANDLER_H__
ram54288 0:a2cb7295a1f7 299
ram54288 0:a2cb7295a1f7 300 ```
ram54288 0:a2cb7295a1f7 301
ram54288 0:a2cb7295a1f7 302 Please note that some of these functions are asynchronous in nature and some are expecting a callback from the network. For example, receiving data from a socket needs to be communicated back to `mbed-client` so that the library can act on the data received. The callback comes through the Observer class defined in `M2MConnectionObserver`.
ram54288 0:a2cb7295a1f7 303
ram54288 0:a2cb7295a1f7 304 The file `m2mconnectionobserver.h` is present in `mbed-client`. To see how the callback needs to be called, check the implementation in `m2mconnectionhandlerpimpl.cpp` in `mbed-client-linux`.
ram54288 0:a2cb7295a1f7 305
ram54288 0:a2cb7295a1f7 306 ```
ram54288 0:a2cb7295a1f7 307 /*
ram54288 0:a2cb7295a1f7 308 * Copyright (c) 2015 ARM. All rights reserved.
ram54288 0:a2cb7295a1f7 309 */
ram54288 0:a2cb7295a1f7 310 #ifndef M2M_CONNECTION_OBSERVER_H__
ram54288 0:a2cb7295a1f7 311 #define M2M_CONNECTION_OBSERVER_H__
ram54288 0:a2cb7295a1f7 312
ram54288 0:a2cb7295a1f7 313 #include "mbed-client/m2minterface.h"
ram54288 0:a2cb7295a1f7 314
ram54288 0:a2cb7295a1f7 315 /**
ram54288 0:a2cb7295a1f7 316 * @brief Observer class for informing socket activity to the state machine
ram54288 0:a2cb7295a1f7 317 */
ram54288 0:a2cb7295a1f7 318
ram54288 0:a2cb7295a1f7 319 class M2MConnectionObserver
ram54288 0:a2cb7295a1f7 320 {
ram54288 0:a2cb7295a1f7 321
ram54288 0:a2cb7295a1f7 322 public :
ram54288 0:a2cb7295a1f7 323
ram54288 0:a2cb7295a1f7 324 /**
ram54288 0:a2cb7295a1f7 325 * \enum ServerType, Defines the type of the
ram54288 0:a2cb7295a1f7 326 * server that the client wants to use.
ram54288 0:a2cb7295a1f7 327 */
ram54288 0:a2cb7295a1f7 328 typedef enum {
ram54288 0:a2cb7295a1f7 329 Bootstrap,
ram54288 0:a2cb7295a1f7 330 LWM2MServer
ram54288 0:a2cb7295a1f7 331 }ServerType;
ram54288 0:a2cb7295a1f7 332
ram54288 0:a2cb7295a1f7 333 /**
ram54288 0:a2cb7295a1f7 334 * \brief The M2MSocketAddress struct.
ram54288 0:a2cb7295a1f7 335 * Unified container for holding socket address data
ram54288 0:a2cb7295a1f7 336 * across different platforms.
ram54288 0:a2cb7295a1f7 337 */
ram54288 0:a2cb7295a1f7 338 struct SocketAddress{
ram54288 0:a2cb7295a1f7 339 M2MInterface::NetworkStack _stack;
ram54288 0:a2cb7295a1f7 340 void *_address;
ram54288 0:a2cb7295a1f7 341 uint8_t _length;
ram54288 0:a2cb7295a1f7 342 uint16_t _port;
ram54288 0:a2cb7295a1f7 343 };
ram54288 0:a2cb7295a1f7 344
ram54288 0:a2cb7295a1f7 345 /**
ram54288 0:a2cb7295a1f7 346 * \brief Indicates that data is available from socket.
ram54288 0:a2cb7295a1f7 347 * \param data The data read from the socket.
ram54288 0:a2cb7295a1f7 348 * \param data_size The length of the data read from the socket.
ram54288 0:a2cb7295a1f7 349 * \param address The address of the server where the data is coming from.
ram54288 0:a2cb7295a1f7 350 */
ram54288 0:a2cb7295a1f7 351 virtual void data_available(uint8_t* data,
ram54288 0:a2cb7295a1f7 352 uint16_t data_size,
ram54288 0:a2cb7295a1f7 353 const M2MConnectionObserver::SocketAddress &address) = 0;
ram54288 0:a2cb7295a1f7 354
ram54288 0:a2cb7295a1f7 355 /**
ram54288 0:a2cb7295a1f7 356 * \brief Indicates an error occured in socket.
ram54288 0:a2cb7295a1f7 357 * \param error_code The error code from socket, it cannot be used any further.
ram54288 0:a2cb7295a1f7 358 * \param retry Indicates whether to re-establish connection.
ram54288 0:a2cb7295a1f7 359 */
ram54288 0:a2cb7295a1f7 360 virtual void socket_error(uint8_t error_code, bool retry = true) = 0;
ram54288 0:a2cb7295a1f7 361
ram54288 0:a2cb7295a1f7 362 /**
ram54288 0:a2cb7295a1f7 363 * \brief Indicates that the server address resolving is ready.
ram54288 0:a2cb7295a1f7 364 * \param address The resolved socket address.
ram54288 0:a2cb7295a1f7 365 * \param server_type The type of the server.
ram54288 0:a2cb7295a1f7 366 * \param server_port The port of the resolved server address.
ram54288 0:a2cb7295a1f7 367 */
ram54288 0:a2cb7295a1f7 368 virtual void address_ready(const M2MConnectionObserver::SocketAddress &address,
ram54288 0:a2cb7295a1f7 369 M2MConnectionObserver::ServerType server_type,
ram54288 0:a2cb7295a1f7 370 const uint16_t server_port) = 0;
ram54288 0:a2cb7295a1f7 371
ram54288 0:a2cb7295a1f7 372 /**
ram54288 0:a2cb7295a1f7 373 * \brief Indicates that data has been sent successfully.
ram54288 0:a2cb7295a1f7 374 */
ram54288 0:a2cb7295a1f7 375 virtual void data_sent() = 0;
ram54288 0:a2cb7295a1f7 376 };
ram54288 0:a2cb7295a1f7 377
ram54288 0:a2cb7295a1f7 378 #endif // M2M_CONNECTION_OBSERVER_H__
ram54288 0:a2cb7295a1f7 379
ram54288 0:a2cb7295a1f7 380 ```
ram54288 0:a2cb7295a1f7 381
ram54288 0:a2cb7295a1f7 382 ### Implementing M2MTimer class for your platform
ram54288 0:a2cb7295a1f7 383
ram54288 0:a2cb7295a1f7 384 This class provides the periodic timer functionality for your platform.
ram54288 0:a2cb7295a1f7 385
ram54288 0:a2cb7295a1f7 386 ```
ram54288 0:a2cb7295a1f7 387 /*
ram54288 0:a2cb7295a1f7 388 * Copyright (c) 2015 ARM. All rights reserved.
ram54288 0:a2cb7295a1f7 389 */
ram54288 0:a2cb7295a1f7 390 #ifndef M2M_TIMER_H
ram54288 0:a2cb7295a1f7 391 #define M2M_TIMER_H
ram54288 0:a2cb7295a1f7 392
ram54288 0:a2cb7295a1f7 393 #include <stdint.h>
ram54288 0:a2cb7295a1f7 394
ram54288 0:a2cb7295a1f7 395 class M2MTimerObserver;
ram54288 0:a2cb7295a1f7 396 /**
ram54288 0:a2cb7295a1f7 397 * @brief M2MTimerImpl
ram54288 0:a2cb7295a1f7 398 * Private implementation class for timer, this can be
ram54288 0:a2cb7295a1f7 399 * modified based on the board on which mbed Client needs
ram54288 0:a2cb7295a1f7 400 * to be used.
ram54288 0:a2cb7295a1f7 401 */
ram54288 0:a2cb7295a1f7 402 class M2MTimerImpl
ram54288 0:a2cb7295a1f7 403 {
ram54288 0:a2cb7295a1f7 404 private:
ram54288 0:a2cb7295a1f7 405
ram54288 0:a2cb7295a1f7 406 // Prevents the use of assignment operator
ram54288 0:a2cb7295a1f7 407 M2MTimer& operator=(const M2MTimer& other);
ram54288 0:a2cb7295a1f7 408
ram54288 0:a2cb7295a1f7 409 // Prevents the use of copy constructor
ram54288 0:a2cb7295a1f7 410 M2MTimer(const M2MTimer& other);
ram54288 0:a2cb7295a1f7 411
ram54288 0:a2cb7295a1f7 412 public:
ram54288 0:a2cb7295a1f7 413
ram54288 0:a2cb7295a1f7 414 /**
ram54288 0:a2cb7295a1f7 415 * Constructor.
ram54288 0:a2cb7295a1f7 416 */
ram54288 0:a2cb7295a1f7 417 M2MTimer(M2MTimerObserver& _observer);
ram54288 0:a2cb7295a1f7 418
ram54288 0:a2cb7295a1f7 419 /**
ram54288 0:a2cb7295a1f7 420 * Destructor.
ram54288 0:a2cb7295a1f7 421 */
ram54288 0:a2cb7295a1f7 422 virtual ~M2MTimer();
ram54288 0:a2cb7295a1f7 423
ram54288 0:a2cb7295a1f7 424 /**
ram54288 0:a2cb7295a1f7 425 * Starts timer
ram54288 0:a2cb7295a1f7 426 * @param interval Timer's interval in milliseconds
ram54288 0:a2cb7295a1f7 427 * @param single_shot defines if timer is ticked
ram54288 0:a2cb7295a1f7 428 * once or is it restarted everytime timer expires.
ram54288 0:a2cb7295a1f7 429 */
ram54288 0:a2cb7295a1f7 430 void start_timer(uint64_t interval, bool single_shot = true);
ram54288 0:a2cb7295a1f7 431
ram54288 0:a2cb7295a1f7 432 /**
ram54288 0:a2cb7295a1f7 433 * @brief Starts timer in DTLS manner.
ram54288 0:a2cb7295a1f7 434 * @param intermediate_interval Intermediate interval to use, must be smaller than tiotal (usually 1/4 of total).
ram54288 0:a2cb7295a1f7 435 * @param total_interval Total interval to use, this is the timeout value of a DTLS packet.
ram54288 0:a2cb7295a1f7 436 * @param type Type of the timer
ram54288 0:a2cb7295a1f7 437 */
ram54288 0:a2cb7295a1f7 438 void start_dtls_timer(uint64_t intermediate_interval, uint64_t total_interval,
ram54288 0:a2cb7295a1f7 439 M2MTimerObserver::Type type = M2MTimerObserver::Dtls);
ram54288 0:a2cb7295a1f7 440
ram54288 0:a2cb7295a1f7 441 /**
ram54288 0:a2cb7295a1f7 442 * Stops timer.
ram54288 0:a2cb7295a1f7 443 * This cancels the ongoing timer.
ram54288 0:a2cb7295a1f7 444 */
ram54288 0:a2cb7295a1f7 445 void stop_timer();
ram54288 0:a2cb7295a1f7 446
ram54288 0:a2cb7295a1f7 447 /**
ram54288 0:a2cb7295a1f7 448 * @brief Checks if the intermediate interval has passed.
ram54288 0:a2cb7295a1f7 449 * @return true if interval has passed, false otherwise.
ram54288 0:a2cb7295a1f7 450 */
ram54288 0:a2cb7295a1f7 451 bool is_intermediate_interval_passed();
ram54288 0:a2cb7295a1f7 452
ram54288 0:a2cb7295a1f7 453 /**
ram54288 0:a2cb7295a1f7 454 * @brief Checks if the total interval has passed.
ram54288 0:a2cb7295a1f7 455 * @return true if interval has passed, false otherwise.
ram54288 0:a2cb7295a1f7 456 */
ram54288 0:a2cb7295a1f7 457 bool is_total_interval_passed();
ram54288 0:a2cb7295a1f7 458
ram54288 0:a2cb7295a1f7 459 };
ram54288 0:a2cb7295a1f7 460
ram54288 0:a2cb7295a1f7 461 #endif // M2M_TIMER_H
ram54288 0:a2cb7295a1f7 462 ```
ram54288 0:a2cb7295a1f7 463
ram54288 0:a2cb7295a1f7 464 The timer API functions are asynchronous in nature and whenever a timer event is available, `mbed-client` is notified, so that the library can act on the _timer expired_ signal. The callback is received through an Observer class defined in `M2MTimerObserver` .
ram54288 0:a2cb7295a1f7 465
ram54288 0:a2cb7295a1f7 466 The file `m2mtimerobserver.h` is present in `mbed-client`. To see how the callback needs to be called, check the implementation in `m2mtimerimpl.cpp` in `mbed-client-linux`.
ram54288 0:a2cb7295a1f7 467
ram54288 0:a2cb7295a1f7 468 ```
ram54288 0:a2cb7295a1f7 469 /*
ram54288 0:a2cb7295a1f7 470 * Copyright (c) 2015 ARM. All rights reserved.
ram54288 0:a2cb7295a1f7 471 */
ram54288 0:a2cb7295a1f7 472 #ifndef M2M_TIMER_OBSERVER_H
ram54288 0:a2cb7295a1f7 473 #define M2M_TIMER_OBSERVER_H
ram54288 0:a2cb7295a1f7 474
ram54288 0:a2cb7295a1f7 475 /**
ram54288 0:a2cb7295a1f7 476 * Observer class for informing the parent class of the timer expiry.
ram54288 0:a2cb7295a1f7 477 */
ram54288 0:a2cb7295a1f7 478 class M2MTimerObserver
ram54288 0:a2cb7295a1f7 479 {
ram54288 0:a2cb7295a1f7 480 public:
ram54288 0:a2cb7295a1f7 481 /**
ram54288 0:a2cb7295a1f7 482 * \enum Defines the types of timer
ram54288 0:a2cb7295a1f7 483 * that can be created for mbed Client.
ram54288 0:a2cb7295a1f7 484 */
ram54288 0:a2cb7295a1f7 485 typedef enum {
ram54288 0:a2cb7295a1f7 486 Notdefined,
ram54288 0:a2cb7295a1f7 487 Registration,
ram54288 0:a2cb7295a1f7 488 NsdlExecution,
ram54288 0:a2cb7295a1f7 489 PMinTimer,
ram54288 0:a2cb7295a1f7 490 PMaxTimer,
ram54288 0:a2cb7295a1f7 491 Dtls,
ram54288 0:a2cb7295a1f7 492 QueueSleep,
ram54288 0:a2cb7295a1f7 493 RetryTimer
ram54288 0:a2cb7295a1f7 494 }Type;
ram54288 0:a2cb7295a1f7 495
ram54288 0:a2cb7295a1f7 496 /**
ram54288 0:a2cb7295a1f7 497 * \brief Indicates that the timer has expired.
ram54288 0:a2cb7295a1f7 498 * \param type The type of the timer that has expired.
ram54288 0:a2cb7295a1f7 499 */
ram54288 0:a2cb7295a1f7 500 virtual void timer_expired(M2MTimerObserver::Type type =
ram54288 0:a2cb7295a1f7 501 M2MTimerObserver::Notdefined) = 0;
ram54288 0:a2cb7295a1f7 502 };
ram54288 0:a2cb7295a1f7 503
ram54288 0:a2cb7295a1f7 504 #endif // M2M_TIMER_OBSERVER_H
ram54288 0:a2cb7295a1f7 505 ```
ram54288 0:a2cb7295a1f7 506
ram54288 0:a2cb7295a1f7 507 ## Modifying the `json` file in the `mbed-client` module
ram54288 0:a2cb7295a1f7 508
ram54288 0:a2cb7295a1f7 509 You need to add your target name to `module.json` so that when you set `yt target <platform>`, yotta can resolve the dependency correctly and link the main library with your module.
ram54288 0:a2cb7295a1f7 510
ram54288 0:a2cb7295a1f7 511 Two platforms, mbed OS and Linux, are already supported. You just need to add your module support after that.
ram54288 0:a2cb7295a1f7 512
ram54288 0:a2cb7295a1f7 513 ```
ram54288 0:a2cb7295a1f7 514 {
ram54288 0:a2cb7295a1f7 515 "name": "mbed-client",
ram54288 0:a2cb7295a1f7 516 "version": "1.12.0",
ram54288 0:a2cb7295a1f7 517 "description": "Mbed Client API",
ram54288 0:a2cb7295a1f7 518 "private": true,
ram54288 0:a2cb7295a1f7 519 "keywords": [],
ram54288 0:a2cb7295a1f7 520 "author": "XXX XXX <xxx.xxx@xxx.com>",
ram54288 0:a2cb7295a1f7 521 "homepage": "https://github.com/ARMmbed/mbed-client",
ram54288 0:a2cb7295a1f7 522 "licenses": [
ram54288 0:a2cb7295a1f7 523 {
ram54288 0:a2cb7295a1f7 524 "url": "https://spdx.org/licenses/Apache-2.0",
ram54288 0:a2cb7295a1f7 525 "type": "Apache-2.0"
ram54288 0:a2cb7295a1f7 526 }
ram54288 0:a2cb7295a1f7 527 ],
ram54288 0:a2cb7295a1f7 528 "dependencies": {
ram54288 0:a2cb7295a1f7 529 "mbed-client-c": "^2.0.0"
ram54288 0:a2cb7295a1f7 530 },
ram54288 0:a2cb7295a1f7 531 "targetDependencies": {
ram54288 0:a2cb7295a1f7 532 "arm": {
ram54288 0:a2cb7295a1f7 533 "mbed-client-mbed": "^3.0.0"
ram54288 0:a2cb7295a1f7 534 },
ram54288 0:a2cb7295a1f7 535 "linux": {
ram54288 0:a2cb7295a1f7 536 "mbed-client-linux": "^3.0.0"
ram54288 0:a2cb7295a1f7 537 },
ram54288 0:a2cb7295a1f7 538 "<your platform as defined in target.json>" : {
ram54288 0:a2cb7295a1f7 539 "mbed-client-platform": "<published version , can be done later, first link locally as explained in the steps above>"
ram54288 0:a2cb7295a1f7 540 },
ram54288 0:a2cb7295a1f7 541 }
ram54288 0:a2cb7295a1f7 542 }
ram54288 0:a2cb7295a1f7 543 ```
ram54288 0:a2cb7295a1f7 544
ram54288 0:a2cb7295a1f7 545 ## Testing and verification
ram54288 0:a2cb7295a1f7 546
ram54288 0:a2cb7295a1f7 547 You can build your mbed-client port immediately:
ram54288 0:a2cb7295a1f7 548
ram54288 0:a2cb7295a1f7 549 ```
ram54288 0:a2cb7295a1f7 550 # use the target we previously made locally available (not necessary if your target has been published):
ram54288 0:a2cb7295a1f7 551 yotta link-target <yourtargetname>
ram54288 0:a2cb7295a1f7 552 # build!
ram54288 0:a2cb7295a1f7 553 yotta build
ram54288 0:a2cb7295a1f7 554 ```
ram54288 0:a2cb7295a1f7 555
ram54288 0:a2cb7295a1f7 556 A `helloworld-mbedclient` program will be produced inside the `build/<yourtargetname>/test/` directory. This test application may require some changes to compile and run for your platform. Check for compilation errors. If you find any, fix the test application for your testing.
ram54288 0:a2cb7295a1f7 557
ram54288 0:a2cb7295a1f7 558 Follow the `readme` [instructions](https://github.com/ARMmbed/mbed-client-linux-example) of the `mbed-client-linux` example to see what the test application can do.