This is a fork due to permission issues

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of 6_songs-from-the-cloud by MakingMusicWorkshop

Committer:
timbeight
Date:
Thu May 19 16:02:10 2016 +0000
Revision:
1:0ddbe2d3319c
Parent:
0:f7c60d3e7b8a
This is my first commit while in the class.

Who changed what in which revision?

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