mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 11:cada08fc8a70 1 /*
mbedAustin 11:cada08fc8a70 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
mbedAustin 11:cada08fc8a70 3 * SPDX-License-Identifier: Apache-2.0
mbedAustin 11:cada08fc8a70 4 * Licensed under the Apache License, Version 2.0 (the License); you may
mbedAustin 11:cada08fc8a70 5 * not use this file except in compliance with the License.
mbedAustin 11:cada08fc8a70 6 * You may obtain a copy of the License at
mbedAustin 11:cada08fc8a70 7 *
mbedAustin 11:cada08fc8a70 8 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 11:cada08fc8a70 9 *
mbedAustin 11:cada08fc8a70 10 * Unless required by applicable law or agreed to in writing, software
mbedAustin 11:cada08fc8a70 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
mbedAustin 11:cada08fc8a70 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 11:cada08fc8a70 13 * See the License for the specific language governing permissions and
mbedAustin 11:cada08fc8a70 14 * limitations under the License.
mbedAustin 11:cada08fc8a70 15 */
mbedAustin 11:cada08fc8a70 16 #include "mbed-client-classic/m2mconnectionhandlerpimpl.h"
mbedAustin 11:cada08fc8a70 17 #include "mbed-client/m2mconnectionobserver.h"
mbedAustin 11:cada08fc8a70 18 #include "mbed-client/m2mconstants.h"
mbedAustin 11:cada08fc8a70 19 #include "mbed-client/m2msecurity.h"
mbedAustin 11:cada08fc8a70 20 #include "mbed-client/m2mconnectionhandler.h"
mbedAustin 11:cada08fc8a70 21
mbedAustin 11:cada08fc8a70 22 #include "Socket/TCPSocketConnection.h"
mbedAustin 11:cada08fc8a70 23 #include "Socket/UDPSocket.h"
mbedAustin 11:cada08fc8a70 24 #include "threadwrapper.h"
mbedAustin 11:cada08fc8a70 25 #include "mbed_error.h"
mbedAustin 11:cada08fc8a70 26
mbedAustin 11:cada08fc8a70 27
mbedAustin 11:cada08fc8a70 28 M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer,
mbedAustin 11:cada08fc8a70 29 M2MConnectionSecurity* sec,
mbedAustin 11:cada08fc8a70 30 M2MInterface::BindingMode mode,
mbedAustin 11:cada08fc8a70 31 M2MInterface::NetworkStack stack)
mbedAustin 11:cada08fc8a70 32 :_base(base),
mbedAustin 11:cada08fc8a70 33 _observer(observer),
mbedAustin 11:cada08fc8a70 34 _security_impl(sec),
mbedAustin 11:cada08fc8a70 35 _use_secure_connection(false),
mbedAustin 11:cada08fc8a70 36 _binding_mode(mode),
mbedAustin 11:cada08fc8a70 37 _network_stack(stack),
mbedAustin 11:cada08fc8a70 38 _resolved(true),
mbedAustin 11:cada08fc8a70 39 _is_handshaking(false),
mbedAustin 11:cada08fc8a70 40 _listening(false),
mbedAustin 11:cada08fc8a70 41 _listen_thread(0),
mbedAustin 11:cada08fc8a70 42 _recv_thread(0),
mbedAustin 11:cada08fc8a70 43 _send_thread(0)
mbedAustin 11:cada08fc8a70 44 {
mbedAustin 11:cada08fc8a70 45 memset(&_address_buffer, 0, sizeof _address_buffer);
mbedAustin 11:cada08fc8a70 46 memset(&_address, 0, sizeof _address);
mbedAustin 11:cada08fc8a70 47 _address._address = _address_buffer;
mbedAustin 11:cada08fc8a70 48
mbedAustin 11:cada08fc8a70 49 if (_network_stack != M2MInterface::LwIP_IPv4) {
mbedAustin 11:cada08fc8a70 50 error("ConnectionHandler: Unsupported network stack, only IPv4 is currently supported");
mbedAustin 11:cada08fc8a70 51 }
mbedAustin 11:cada08fc8a70 52
mbedAustin 11:cada08fc8a70 53 if (_binding_mode == M2MInterface::TCP ||
mbedAustin 11:cada08fc8a70 54 _binding_mode == M2MInterface::TCP_QUEUE) {
mbedAustin 11:cada08fc8a70 55 error("ConnectionHandler: Unsupported binding mode, only UDP based modes are currently supported");
mbedAustin 11:cada08fc8a70 56 }
mbedAustin 11:cada08fc8a70 57
mbedAustin 11:cada08fc8a70 58 _running = true;
mbedAustin 11:cada08fc8a70 59 _recv_thread = rtos::create_thread<
mbedAustin 11:cada08fc8a70 60 M2MConnectionHandlerPimpl,
mbedAustin 11:cada08fc8a70 61 &M2MConnectionHandlerPimpl::recv_handler>(this, osPriorityAboveNormal);
mbedAustin 11:cada08fc8a70 62 _send_thread = rtos::create_thread<
mbedAustin 11:cada08fc8a70 63 M2MConnectionHandlerPimpl,
mbedAustin 11:cada08fc8a70 64 &M2MConnectionHandlerPimpl::send_handler>(this);
mbedAustin 11:cada08fc8a70 65 _listen_thread = rtos::create_thread<
mbedAustin 11:cada08fc8a70 66 M2MConnectionHandlerPimpl,
mbedAustin 11:cada08fc8a70 67 &M2MConnectionHandlerPimpl::listen_handler>(this);
mbedAustin 11:cada08fc8a70 68 }
mbedAustin 11:cada08fc8a70 69
mbedAustin 11:cada08fc8a70 70 M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl()
mbedAustin 11:cada08fc8a70 71 {
mbedAustin 11:cada08fc8a70 72 _listening = false;
mbedAustin 11:cada08fc8a70 73 _running = false;
mbedAustin 11:cada08fc8a70 74
mbedAustin 11:cada08fc8a70 75 if (_listen_thread) {
mbedAustin 11:cada08fc8a70 76 delete _listen_thread;
mbedAustin 11:cada08fc8a70 77 _listen_thread = 0;
mbedAustin 11:cada08fc8a70 78 }
mbedAustin 11:cada08fc8a70 79
mbedAustin 11:cada08fc8a70 80 if (_recv_thread) {
mbedAustin 11:cada08fc8a70 81 delete _recv_thread;
mbedAustin 11:cada08fc8a70 82 _recv_thread = 0;
mbedAustin 11:cada08fc8a70 83 }
mbedAustin 11:cada08fc8a70 84
mbedAustin 11:cada08fc8a70 85 if (_send_thread) {
mbedAustin 11:cada08fc8a70 86 delete _send_thread;
mbedAustin 11:cada08fc8a70 87 _send_thread = 0;
mbedAustin 11:cada08fc8a70 88 }
mbedAustin 11:cada08fc8a70 89
mbedAustin 11:cada08fc8a70 90 delete _security_impl;
mbedAustin 11:cada08fc8a70 91 }
mbedAustin 11:cada08fc8a70 92
mbedAustin 11:cada08fc8a70 93 bool M2MConnectionHandlerPimpl::bind_connection(const uint16_t listen_port)
mbedAustin 11:cada08fc8a70 94 {
mbedAustin 11:cada08fc8a70 95 return !(_socket.bind(listen_port) < 0);
mbedAustin 11:cada08fc8a70 96 }
mbedAustin 11:cada08fc8a70 97
mbedAustin 11:cada08fc8a70 98 bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_address,
mbedAustin 11:cada08fc8a70 99 const uint16_t server_port,
mbedAustin 11:cada08fc8a70 100 M2MConnectionObserver::ServerType server_type,
mbedAustin 11:cada08fc8a70 101 const M2MSecurity* security)
mbedAustin 11:cada08fc8a70 102 {
mbedAustin 11:cada08fc8a70 103 if (_endpoint.set_address(server_address.c_str(), server_port) < 0) {
mbedAustin 11:cada08fc8a70 104 return false;
mbedAustin 11:cada08fc8a70 105 }
mbedAustin 11:cada08fc8a70 106
mbedAustin 11:cada08fc8a70 107 inet_aton(_endpoint.get_address(), _address._address);
mbedAustin 11:cada08fc8a70 108 _address._port = _endpoint.get_port();
mbedAustin 11:cada08fc8a70 109 _address._length = 4;
mbedAustin 11:cada08fc8a70 110 _address._stack = _network_stack;
mbedAustin 11:cada08fc8a70 111
mbedAustin 11:cada08fc8a70 112 if (security) {
mbedAustin 11:cada08fc8a70 113 if (security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Certificate ||
mbedAustin 11:cada08fc8a70 114 security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Psk) {
mbedAustin 11:cada08fc8a70 115 if (_security_impl != NULL) {
mbedAustin 11:cada08fc8a70 116 _security_impl->reset();
mbedAustin 11:cada08fc8a70 117 _security_impl->init(security);
mbedAustin 11:cada08fc8a70 118
mbedAustin 11:cada08fc8a70 119 if (_security_impl->connect(_base) < 0) {
mbedAustin 11:cada08fc8a70 120 return false;
mbedAustin 11:cada08fc8a70 121 }
mbedAustin 11:cada08fc8a70 122
mbedAustin 11:cada08fc8a70 123 _use_secure_connection = true;
mbedAustin 11:cada08fc8a70 124 }
mbedAustin 11:cada08fc8a70 125 }
mbedAustin 11:cada08fc8a70 126 }
mbedAustin 11:cada08fc8a70 127
mbedAustin 11:cada08fc8a70 128 _observer.address_ready(_address,
mbedAustin 11:cada08fc8a70 129 server_type,
mbedAustin 11:cada08fc8a70 130 _address._port);
mbedAustin 11:cada08fc8a70 131
mbedAustin 11:cada08fc8a70 132 return true;
mbedAustin 11:cada08fc8a70 133 }
mbedAustin 11:cada08fc8a70 134
mbedAustin 11:cada08fc8a70 135
mbedAustin 11:cada08fc8a70 136 void M2MConnectionHandlerPimpl::recv_handler()
mbedAustin 11:cada08fc8a70 137 {
mbedAustin 11:cada08fc8a70 138 while (_running) {
mbedAustin 11:cada08fc8a70 139 Endpoint recv_endpoint;
mbedAustin 11:cada08fc8a70 140 int size = _socket.receiveFrom(recv_endpoint,
mbedAustin 11:cada08fc8a70 141 (char*)_recv_buffer, sizeof _recv_buffer);
mbedAustin 11:cada08fc8a70 142
mbedAustin 11:cada08fc8a70 143 if (size > 0) {
mbedAustin 11:cada08fc8a70 144 _recv_queue.put(new std::string(_recv_buffer, _recv_buffer+size));
mbedAustin 11:cada08fc8a70 145 } else {
mbedAustin 11:cada08fc8a70 146 rtos::Thread::wait(1000);
mbedAustin 11:cada08fc8a70 147 }
mbedAustin 11:cada08fc8a70 148 }
mbedAustin 11:cada08fc8a70 149 }
mbedAustin 11:cada08fc8a70 150
mbedAustin 11:cada08fc8a70 151 void M2MConnectionHandlerPimpl::send_handler()
mbedAustin 11:cada08fc8a70 152 {
mbedAustin 11:cada08fc8a70 153 while (_running) {
mbedAustin 11:cada08fc8a70 154 osEvent e = _send_queue.get();
mbedAustin 11:cada08fc8a70 155 if (e.status == osEventMessage) {
mbedAustin 11:cada08fc8a70 156 std::string *packet = (std::string*)e.value.p;
mbedAustin 11:cada08fc8a70 157 int size = _socket.sendTo(_endpoint, (char*)packet->data(), packet->size());
mbedAustin 11:cada08fc8a70 158 delete packet;
mbedAustin 11:cada08fc8a70 159 } else {
mbedAustin 11:cada08fc8a70 160 rtos::Thread::wait(1000);
mbedAustin 11:cada08fc8a70 161 }
mbedAustin 11:cada08fc8a70 162 }
mbedAustin 11:cada08fc8a70 163 }
mbedAustin 11:cada08fc8a70 164
mbedAustin 11:cada08fc8a70 165 bool M2MConnectionHandlerPimpl::send_data(uint8_t *data,
mbedAustin 11:cada08fc8a70 166 uint16_t data_len,
mbedAustin 11:cada08fc8a70 167 sn_nsdl_addr_s *address)
mbedAustin 11:cada08fc8a70 168 {
mbedAustin 11:cada08fc8a70 169 if (address == NULL || data == NULL) {
mbedAustin 11:cada08fc8a70 170 return false;
mbedAustin 11:cada08fc8a70 171 }
mbedAustin 11:cada08fc8a70 172
mbedAustin 11:cada08fc8a70 173 if (_use_secure_connection) {
mbedAustin 11:cada08fc8a70 174 if (_security_impl->send_message(data, data_len) < 0) {
mbedAustin 11:cada08fc8a70 175 return false;
mbedAustin 11:cada08fc8a70 176 }
mbedAustin 11:cada08fc8a70 177 } else {
mbedAustin 11:cada08fc8a70 178 if (send_to_socket(data, data_len) < 0) {
mbedAustin 11:cada08fc8a70 179 return false;
mbedAustin 11:cada08fc8a70 180 }
mbedAustin 11:cada08fc8a70 181 }
mbedAustin 11:cada08fc8a70 182
mbedAustin 11:cada08fc8a70 183 _observer.data_sent();
mbedAustin 11:cada08fc8a70 184 return true;
mbedAustin 11:cada08fc8a70 185 }
mbedAustin 11:cada08fc8a70 186
mbedAustin 11:cada08fc8a70 187 bool M2MConnectionHandlerPimpl::start_listening_for_data()
mbedAustin 11:cada08fc8a70 188 {
mbedAustin 11:cada08fc8a70 189 _listening = true;
mbedAustin 11:cada08fc8a70 190 return true;
mbedAustin 11:cada08fc8a70 191 }
mbedAustin 11:cada08fc8a70 192
mbedAustin 11:cada08fc8a70 193 void M2MConnectionHandlerPimpl::stop_listening()
mbedAustin 11:cada08fc8a70 194 {
mbedAustin 11:cada08fc8a70 195 _listening = false;
mbedAustin 11:cada08fc8a70 196 }
mbedAustin 11:cada08fc8a70 197
mbedAustin 11:cada08fc8a70 198 void M2MConnectionHandlerPimpl::listen_handler()
mbedAustin 11:cada08fc8a70 199 {
mbedAustin 11:cada08fc8a70 200 while (_running) {
mbedAustin 11:cada08fc8a70 201 if (_listening) {
mbedAustin 11:cada08fc8a70 202 memset(_listen_buffer, 0, sizeof _listen_buffer);
mbedAustin 11:cada08fc8a70 203 int size;
mbedAustin 11:cada08fc8a70 204
mbedAustin 11:cada08fc8a70 205 if (_use_secure_connection) {
mbedAustin 11:cada08fc8a70 206 size = _security_impl->read(_listen_buffer, sizeof _listen_buffer);
mbedAustin 11:cada08fc8a70 207 } else {
mbedAustin 11:cada08fc8a70 208 size = receive_from_socket(_listen_buffer, sizeof _listen_buffer);
mbedAustin 11:cada08fc8a70 209 }
mbedAustin 11:cada08fc8a70 210
mbedAustin 11:cada08fc8a70 211 if (size > 0) {
mbedAustin 11:cada08fc8a70 212 _observer.data_available((uint8_t*)_listen_buffer, size, _address);
mbedAustin 11:cada08fc8a70 213 } else if (size != 0) {
mbedAustin 11:cada08fc8a70 214 _listening = false;
mbedAustin 11:cada08fc8a70 215 _observer.socket_error(2);
mbedAustin 11:cada08fc8a70 216 }
mbedAustin 11:cada08fc8a70 217 } else {
mbedAustin 11:cada08fc8a70 218 rtos::Thread::wait(1000);
mbedAustin 11:cada08fc8a70 219 }
mbedAustin 11:cada08fc8a70 220 }
mbedAustin 11:cada08fc8a70 221 }
mbedAustin 11:cada08fc8a70 222
mbedAustin 11:cada08fc8a70 223
mbedAustin 11:cada08fc8a70 224 int M2MConnectionHandlerPimpl::send_to_socket(const unsigned char *buf, size_t len)
mbedAustin 11:cada08fc8a70 225 {
mbedAustin 11:cada08fc8a70 226 if (_send_queue.put(new std::string(buf, buf+len)) != osOK) {
mbedAustin 11:cada08fc8a70 227 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_WRITE;
mbedAustin 11:cada08fc8a70 228 } else {
mbedAustin 11:cada08fc8a70 229 return len;
mbedAustin 11:cada08fc8a70 230 }
mbedAustin 11:cada08fc8a70 231 }
mbedAustin 11:cada08fc8a70 232
mbedAustin 11:cada08fc8a70 233 int M2MConnectionHandlerPimpl::receive_from_socket(unsigned char *buf, size_t len)
mbedAustin 11:cada08fc8a70 234 {
mbedAustin 11:cada08fc8a70 235 osEvent e = _recv_queue.get();
mbedAustin 11:cada08fc8a70 236 if (e.status == osEventMessage) {
mbedAustin 11:cada08fc8a70 237 std::string *packet = (std::string*)e.value.p;
mbedAustin 11:cada08fc8a70 238 int size = packet->size();
mbedAustin 11:cada08fc8a70 239
mbedAustin 11:cada08fc8a70 240 if (size <= len) {
mbedAustin 11:cada08fc8a70 241 memcpy(buf, packet->data(), size);
mbedAustin 11:cada08fc8a70 242 delete packet;
mbedAustin 11:cada08fc8a70 243 return size;
mbedAustin 11:cada08fc8a70 244 }
mbedAustin 11:cada08fc8a70 245 }
mbedAustin 11:cada08fc8a70 246
mbedAustin 11:cada08fc8a70 247 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ;
mbedAustin 11:cada08fc8a70 248 }
mbedAustin 11:cada08fc8a70 249
mbedAustin 11:cada08fc8a70 250 void M2MConnectionHandlerPimpl::handle_connection_error(int /*error*/)
mbedAustin 11:cada08fc8a70 251 {
mbedAustin 11:cada08fc8a70 252 _observer.socket_error(4);
mbedAustin 11:cada08fc8a70 253 }