A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

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