Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ftcd_comm_socket.h Source File

ftcd_comm_socket.h

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2017 ARM Ltd.
00003 //  
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //  
00008 //     http://www.apache.org/licenses/LICENSE-2.0
00009 //  
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 // ----------------------------------------------------------------------------
00016 
00017 #ifndef __FTCD_COMM_SOCKET_H__
00018 #define __FTCD_COMM_SOCKET_H__
00019 
00020 #include "ftcd_comm_base.h"
00021 #include "pal.h"
00022 #include <inttypes.h>
00023 
00024 #define INFINITE_SOCKET_TIMEOUT -1
00025 
00026 /**
00027 * List of supported networks domains. Current supported domain is ipv4 only.
00028 */
00029 typedef enum {
00030     FTCD_AF_UNSPEC = 0,//!< Unspecified IP protocol.
00031     FTCD_IPV4 = 2,     //!< Internet IP Protocol.
00032 } ftcd_socket_domain_e;
00033 
00034 /**
00035 * Type for sockets.
00036 */
00037 typedef void* palSocket_t;
00038 /**
00039 * Structure for Ethernet interface info.
00040 */
00041 struct palNetInterfaceInfo;
00042 /**
00043 * Class for Ethernet interface.
00044 */
00045 class EthernetInterface;
00046 
00047 /** FtcdCommSocket implements the logic of listening for TCP connections and
00048 *  process incoming messages from the Factory Tool.
00049 */
00050 class FtcdCommSocket : public FtcdCommBase {
00051 
00052 public:
00053 
00054     /**
00055     * The Socket Constructor
00056     * Initializes private variables and sets network interface handler, IP and port number.
00057     * If port_num is 0, then random port will be generated.
00058     */
00059     FtcdCommSocket(const void *interfaceHandler, ftcd_socket_domain_e domain, const uint16_t port_num, ftcd_comm_network_endianness_e network_endianness = FTCD_COMM_NET_ENDIANNESS_BIG, int32_t timeout = INFINITE_SOCKET_TIMEOUT);
00060 
00061     /**
00062     * The Socket Constructor
00063     * Initializes private variables and sets network interface handler, IP and port number.
00064     * If port_num is 0, then random port will be generated.
00065     */
00066     FtcdCommSocket(const void *interfaceHandler, ftcd_socket_domain_e domain, const uint16_t port_num, ftcd_comm_network_endianness_e network_endianness, const uint8_t *header_token, bool use_signature, int32_t timeout = INFINITE_SOCKET_TIMEOUT);
00067 
00068     /**
00069     * The Socket Destructor
00070     * Closes opened resources and frees allocated memory.
00071     */
00072     virtual ~FtcdCommSocket();
00073 
00074     /**
00075     * Initializes Network interface and prints its address.
00076     */
00077     virtual bool init(void);
00078 
00079     /**
00080     * Closes opened sockets
00081     */
00082     virtual void finish(void);
00083 
00084     /** Wait and read complete message from the communication line.
00085     * The method waits in blocking mode for new message,
00086     * allocate and read the message,
00087     * and sets message_out and message_size_out
00088     *
00089     * @param message_out The message allocated and read from the communication line
00090     * @param message_size_out The message size in bytes
00091     *
00092     * @returns
00093     *     FTCD_COMM_STATUS_SUCCESS - On success. In this case the client socket, and accepted connection remain open waiting for the next message with next call.
00094     *     FTCD_COMM_NETWORK_TIMEOUT - This means a timeout has occurred, client socket close and next call will create a new socket and accept a new connection.
00095     *     Other ftcd_comm_status_e error code - some other error has occurred, client socket will be closed and next call will create and open a new socket, and wait for a new connection.
00096     */
00097     virtual ftcd_comm_status_e wait_for_message(uint8_t **message_out, uint32_t *message_size_out);
00098 
00099     /** Detects the message token from the communication line medium.
00100     *
00101     * @returns
00102     *     true, if token detected and false otherwise
00103     */
00104     virtual ftcd_comm_status_e is_token_detected(void);
00105 
00106     /** Reads the message size in bytes from the communication line medium.
00107     * This is the amount of bytes needed to allocate for the upcoming message bytes.
00108     *
00109     * @returns
00110     *     The message size in bytes in case of success, zero bytes otherwise.
00111     */
00112     virtual uint32_t read_message_size(void);
00113 
00114     /** Reads the message size in bytes from the communication line medium.
00115     * This is the amount of bytes needed to allocate for the upcoming message bytes.
00116     *
00117     * @param message_out The buffer to read into and return to the caller.
00118     * @param message_size The message size in bytes.
00119     *
00120     * @returns
00121     *     true upon success, false otherwise
00122     */
00123     virtual bool read_message(uint8_t *message_out, size_t message_size);
00124 
00125     /** Reads the message size in bytes from the communication line medium.
00126     * This is the amount of bytes needed to allocate for the upcoming message bytes.
00127     *
00128     * @param sig The buffer to read into and return to the caller.
00129     * @param sig_size The sig buffer size in bytes.
00130     *
00131     * @returns
00132     *     The message size in bytes in case of success, zero bytes otherwise.
00133     */
00134     virtual bool read_message_signature(uint8_t *sig, size_t sig_size);
00135 
00136     /** Writes the given data to the communication line medium.
00137     *
00138     * @param data The bytes to send through the communication line medium
00139     * @param data_size The data size in bytes
00140     *
00141     * @returns
00142     *     true upon success, false otherwise
00143     */
00144     virtual bool send(const uint8_t *data, uint32_t data_size);
00145 
00146 private:
00147     enum connection_state_e {
00148         SOCKET_WAIT_FOR_CONNECTION,
00149         SOCKET_CONNECTION_ACCEPTED
00150     };
00151 
00152     connection_state_e _connection_state;
00153     const void *_interface_handler;
00154     palSocket_t _server_socket;
00155     palSocket_t _client_socket;
00156     palNetInterfaceInfo *_net_interface_info;
00157     uint16_t _port;
00158     ftcd_socket_domain_e _current_domain_type;
00159     ftcd_socket_domain_e _required_domain_type;
00160     uint32_t _interface_index;
00161     int32_t _rcv_timeout;
00162     palSemaphoreID_t _async_sem;
00163     palSemaphoreID_t _lock;
00164 
00165 
00166     /** Starts listening for incoming TCP socket connection
00167     *   A single connection allowed at a time
00168     *
00169     *   @returns
00170     *       true, if listen to the socket succeeded.
00171     */
00172     bool _listen(void);
00173 
00174     /**Reads a requested amount of bytes from a TCP socket
00175     *
00176     * @param data_out Pre-allocated buffer to be filled
00177     * @param data_out_size Buffer length in bytes
00178     *
00179     * @returns
00180     *    0, if the number of bytes read from the socket were exactly bufferOutSize, error status otherwise.
00181     */
00182     ftcd_comm_status_e _read_from_socket(void *data_out, int data_out_size);
00183 
00184     // The following comment for describes implementation for both _accept and _recv
00185     // Achieved by trying to _accept/_recv, and then (if accept would have been blocking) wait in _async_sem until event is triggered - then try again
00186     // Important that _accept/_recv first tries and then blocks for the following reasons:
00187     // 1. If 2 events trigger the async callback only once (i.e accept and recv) - blocking first would cause the block before recv to block forever
00188     // 2. If 2 events trigger the async callback prior to _lock release in _wait_for_socket_event - blocking first would cause the second network action to block forever because _async_sem will only be signaled once
00189     // Overall, trying to accept/recv prior to waiting for an event assures us that we go into the waiting stage only when we are certain that an event will be triggered when the desired action may occur 
00190 
00191     // Blocking wrapper to pal_accept() API for non-blocking, async sockets
00192     palStatus_t _accept(palSocket_t socket, palSocketAddress_t* address, palSocketLength_t* addressLen, palSocket_t* acceptedSocket);
00193     // Blocking wrapper to pal_recv() API for non-blocking, async sockets
00194     palStatus_t _recv(palSocket_t socket, void* buf, size_t len, size_t* recievedDataSize);
00195     // Blocking wrapper to pal_send() API for non-blocking, async sockets
00196     palStatus_t _send(palSocket_t socket, const void* buf, size_t len, size_t* sentDataSize);
00197     // block until a socket event occurs
00198     palStatus_t _wait_for_socket_event();
00199     // Callback that is invoked when some network event occurrs socket_obj is a pointer to a valid FtcdCommSocket object
00200     static void _socket_event_ready_cb(void *socket_obj);
00201 };
00202 
00203 
00204 #endif //__FTCD_COMM_SOCKET_H__