Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud by
m2mconnectionhandlerpimpl.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * 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, WITHOUT 00012 * 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 #include "mbed-client-classic/m2mconnectionhandlerpimpl.h" 00017 #include "mbed-client/m2mconnectionobserver.h" 00018 #include "mbed-client/m2mconstants.h" 00019 #include "mbed-client/m2msecurity.h" 00020 #include "mbed-client/m2mconnectionhandler.h" 00021 00022 #include "Socket/TCPSocketConnection.h" 00023 #include "Socket/UDPSocket.h" 00024 #include "threadwrapper.h" 00025 #include "mbed_error.h" 00026 00027 00028 M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer, 00029 M2MConnectionSecurity* sec, 00030 M2MInterface::BindingMode mode, 00031 M2MInterface::NetworkStack stack) 00032 :_base(base), 00033 _observer(observer), 00034 _security_impl(sec), 00035 _use_secure_connection(false), 00036 _binding_mode(mode), 00037 _network_stack(stack), 00038 _resolved(true), 00039 _is_handshaking(false), 00040 _listening(false), 00041 _listen_thread(0), 00042 _recv_thread(0), 00043 _send_thread(0) 00044 { 00045 memset(&_address_buffer, 0, sizeof _address_buffer); 00046 memset(&_address, 0, sizeof _address); 00047 _address._address = _address_buffer; 00048 00049 if (_network_stack != M2MInterface::LwIP_IPv4) { 00050 error("ConnectionHandler: Unsupported network stack, only IPv4 is currently supported"); 00051 } 00052 00053 if (_binding_mode == M2MInterface::TCP || 00054 _binding_mode == M2MInterface::TCP_QUEUE) { 00055 error("ConnectionHandler: Unsupported binding mode, only UDP based modes are currently supported"); 00056 } 00057 00058 _running = true; 00059 _recv_thread = rtos::create_thread< 00060 M2MConnectionHandlerPimpl, 00061 &M2MConnectionHandlerPimpl::recv_handler>(this, osPriorityAboveNormal); 00062 _send_thread = rtos::create_thread< 00063 M2MConnectionHandlerPimpl, 00064 &M2MConnectionHandlerPimpl::send_handler>(this); 00065 _listen_thread = rtos::create_thread< 00066 M2MConnectionHandlerPimpl, 00067 &M2MConnectionHandlerPimpl::listen_handler>(this); 00068 } 00069 00070 M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl() 00071 { 00072 _listening = false; 00073 _running = false; 00074 00075 if (_listen_thread) { 00076 delete _listen_thread; 00077 _listen_thread = 0; 00078 } 00079 00080 if (_recv_thread) { 00081 delete _recv_thread; 00082 _recv_thread = 0; 00083 } 00084 00085 if (_send_thread) { 00086 delete _send_thread; 00087 _send_thread = 0; 00088 } 00089 00090 delete _security_impl; 00091 } 00092 00093 bool M2MConnectionHandlerPimpl::bind_connection(const uint16_t listen_port) 00094 { 00095 return !(_socket.bind(listen_port) < 0); 00096 } 00097 00098 bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_address, 00099 const uint16_t server_port, 00100 M2MConnectionObserver::ServerType server_type, 00101 const M2MSecurity* security) 00102 { 00103 if (_endpoint.set_address(server_address.c_str(), server_port) < 0) { 00104 return false; 00105 } 00106 00107 inet_aton(_endpoint.get_address(), _address._address); 00108 _address._port = _endpoint.get_port(); 00109 _address._length = 4; 00110 _address._stack = _network_stack; 00111 00112 if (security) { 00113 if (security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Certificate || 00114 security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Psk) { 00115 if (_security_impl != NULL) { 00116 _security_impl->reset(); 00117 _security_impl->init(security); 00118 00119 if (_security_impl->connect(_base) < 0) { 00120 return false; 00121 } 00122 00123 _use_secure_connection = true; 00124 } 00125 } 00126 } 00127 00128 _observer.address_ready(_address, 00129 server_type, 00130 _address._port); 00131 00132 return true; 00133 } 00134 00135 00136 void M2MConnectionHandlerPimpl::recv_handler() 00137 { 00138 while (_running) { 00139 Endpoint recv_endpoint; 00140 int size = _socket.receiveFrom(recv_endpoint, 00141 (char*)_recv_buffer, sizeof _recv_buffer); 00142 00143 if (size > 0) { 00144 _recv_queue.put(new std::string(_recv_buffer, _recv_buffer+size)); 00145 } else { 00146 rtos::Thread::wait(1000); 00147 } 00148 } 00149 } 00150 00151 void M2MConnectionHandlerPimpl::send_handler() 00152 { 00153 while (_running) { 00154 osEvent e = _send_queue.get(); 00155 if (e.status == osEventMessage) { 00156 std::string *packet = (std::string*)e.value.p; 00157 int size = _socket.sendTo(_endpoint, (char*)packet->data(), packet->size()); 00158 delete packet; 00159 } else { 00160 rtos::Thread::wait(1000); 00161 } 00162 } 00163 } 00164 00165 bool M2MConnectionHandlerPimpl::send_data(uint8_t *data, 00166 uint16_t data_len, 00167 sn_nsdl_addr_s *address) 00168 { 00169 if (address == NULL || data == NULL) { 00170 return false; 00171 } 00172 00173 if (_use_secure_connection) { 00174 if (_security_impl->send_message(data, data_len) < 0) { 00175 return false; 00176 } 00177 } else { 00178 if (send_to_socket(data, data_len) < 0) { 00179 return false; 00180 } 00181 } 00182 00183 _observer.data_sent(); 00184 return true; 00185 } 00186 00187 bool M2MConnectionHandlerPimpl::start_listening_for_data() 00188 { 00189 _listening = true; 00190 return true; 00191 } 00192 00193 void M2MConnectionHandlerPimpl::stop_listening() 00194 { 00195 _listening = false; 00196 } 00197 00198 void M2MConnectionHandlerPimpl::listen_handler() 00199 { 00200 while (_running) { 00201 if (_listening) { 00202 memset(_listen_buffer, 0, sizeof _listen_buffer); 00203 int size; 00204 00205 if (_use_secure_connection) { 00206 size = _security_impl->read(_listen_buffer, sizeof _listen_buffer); 00207 } else { 00208 size = receive_from_socket(_listen_buffer, sizeof _listen_buffer); 00209 } 00210 00211 if (size > 0) { 00212 _observer.data_available((uint8_t*)_listen_buffer, size, _address); 00213 } else if (size != 0) { 00214 _listening = false; 00215 _observer.socket_error(2); 00216 } 00217 } else { 00218 rtos::Thread::wait(1000); 00219 } 00220 } 00221 } 00222 00223 00224 int M2MConnectionHandlerPimpl::send_to_socket(const unsigned char *buf, size_t len) 00225 { 00226 if (_send_queue.put(new std::string(buf, buf+len)) != osOK) { 00227 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_WRITE; 00228 } else { 00229 return len; 00230 } 00231 } 00232 00233 int M2MConnectionHandlerPimpl::receive_from_socket(unsigned char *buf, size_t len) 00234 { 00235 osEvent e = _recv_queue.get(); 00236 if (e.status == osEventMessage) { 00237 std::string *packet = (std::string*)e.value.p; 00238 int size = packet->size(); 00239 00240 if (size <= len) { 00241 memcpy(buf, packet->data(), size); 00242 delete packet; 00243 return size; 00244 } 00245 } 00246 00247 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ; 00248 } 00249 00250 void M2MConnectionHandlerPimpl::handle_connection_error(int /*error*/) 00251 { 00252 _observer.socket_error(4); 00253 }
Generated on Tue Jul 12 2022 12:47:47 by
