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 /*
ram54288 0:a7a43371b306 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
ram54288 0:a7a43371b306 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:a7a43371b306 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:a7a43371b306 5 * not use this file except in compliance with the License.
ram54288 0:a7a43371b306 6 * You may obtain a copy of the License at
ram54288 0:a7a43371b306 7 *
ram54288 0:a7a43371b306 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:a7a43371b306 9 *
ram54288 0:a7a43371b306 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:a7a43371b306 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:a7a43371b306 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:a7a43371b306 13 * See the License for the specific language governing permissions and
ram54288 0:a7a43371b306 14 * limitations under the License.
ram54288 0:a7a43371b306 15 */
ram54288 0:a7a43371b306 16 #include "mbed-client-classic/m2mconnectionhandlerpimpl.h"
ram54288 0:a7a43371b306 17 #include "mbed-client/m2mconnectionobserver.h"
ram54288 0:a7a43371b306 18 #include "mbed-client/m2mconstants.h"
ram54288 0:a7a43371b306 19 #include "mbed-client/m2msecurity.h"
ram54288 0:a7a43371b306 20 #include "mbed-client/m2mconnectionhandler.h"
ram54288 0:a7a43371b306 21
ram54288 0:a7a43371b306 22 #include "pal.h"
ram54288 0:a7a43371b306 23 #include "pal_rtos.h"
ram54288 0:a7a43371b306 24 #include "pal_errors.h"
ram54288 0:a7a43371b306 25 #include "pal_macros.h"
ram54288 0:a7a43371b306 26 #include "pal_network.h"
ram54288 0:a7a43371b306 27
ram54288 0:a7a43371b306 28 #include "eventOS_scheduler.h"
ram54288 0:a7a43371b306 29 #include "eventOS_event.h"
ram54288 0:a7a43371b306 30
ram54288 0:a7a43371b306 31 #include "mbed-trace/mbed_trace.h"
ram54288 0:a7a43371b306 32 #include "mbed.h"
ram54288 0:a7a43371b306 33
ram54288 0:a7a43371b306 34 #define TRACE_GROUP "mClt"
ram54288 0:a7a43371b306 35
ram54288 0:a7a43371b306 36 int8_t M2MConnectionHandlerPimpl::_tasklet_id = -1;
ram54288 0:a7a43371b306 37
ram54288 0:a7a43371b306 38 static M2MConnectionHandlerPimpl *connection_handler = NULL;
ram54288 0:a7a43371b306 39
ram54288 0:a7a43371b306 40 extern "C" void connection_event_handler(arm_event_s *event)
ram54288 0:a7a43371b306 41 {
ram54288 0:a7a43371b306 42 if(!connection_handler){
ram54288 0:a7a43371b306 43 return;
ram54288 0:a7a43371b306 44 }
ram54288 0:a7a43371b306 45
ram54288 0:a7a43371b306 46 switch(event->event_type){
ram54288 0:a7a43371b306 47 case M2MConnectionHandlerPimpl::ESocketReadytoRead:
ram54288 0:a7a43371b306 48 connection_handler->receive_handler();
ram54288 0:a7a43371b306 49 break;
ram54288 0:a7a43371b306 50
ram54288 0:a7a43371b306 51 case M2MConnectionHandlerPimpl::ESocketSend:
ram54288 0:a7a43371b306 52 connection_handler->send_socket_data((uint8_t*)event->data_ptr, event->event_data);
ram54288 0:a7a43371b306 53 free(event->data_ptr);
ram54288 0:a7a43371b306 54 break;
ram54288 0:a7a43371b306 55
ram54288 0:a7a43371b306 56 case M2MConnectionHandlerPimpl::ESocketDnsHandler:
ram54288 0:a7a43371b306 57 connection_handler->dns_handler();
ram54288 0:a7a43371b306 58 break;
ram54288 0:a7a43371b306 59
ram54288 0:a7a43371b306 60 default:
ram54288 0:a7a43371b306 61 break;
ram54288 0:a7a43371b306 62 }
ram54288 0:a7a43371b306 63 }
ram54288 0:a7a43371b306 64
ram54288 0:a7a43371b306 65 void M2MConnectionHandlerPimpl::send_receive_event(void)
ram54288 0:a7a43371b306 66 {
ram54288 0:a7a43371b306 67 arm_event_s event;
ram54288 0:a7a43371b306 68 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id;
ram54288 0:a7a43371b306 69 event.sender = 0;
ram54288 0:a7a43371b306 70 event.event_type = ESocketReadytoRead;
ram54288 0:a7a43371b306 71 event.data_ptr = NULL;
ram54288 0:a7a43371b306 72 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT;
ram54288 0:a7a43371b306 73 eventOS_event_send(&event);
ram54288 0:a7a43371b306 74 }
ram54288 0:a7a43371b306 75
ram54288 0:a7a43371b306 76 extern "C" void socket_event_handler(void)
ram54288 0:a7a43371b306 77 {
ram54288 0:a7a43371b306 78 if(!connection_handler) {
ram54288 0:a7a43371b306 79 return;
ram54288 0:a7a43371b306 80 }
ram54288 0:a7a43371b306 81 connection_handler->send_receive_event();
ram54288 0:a7a43371b306 82 }
ram54288 0:a7a43371b306 83
ram54288 0:a7a43371b306 84 M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer,
ram54288 0:a7a43371b306 85 M2MConnectionSecurity* sec,
ram54288 0:a7a43371b306 86 M2MInterface::BindingMode mode,
ram54288 0:a7a43371b306 87 M2MInterface::NetworkStack stack)
ram54288 0:a7a43371b306 88 :_base(base),
ram54288 0:a7a43371b306 89 _observer(observer),
ram54288 0:a7a43371b306 90 _security_impl(sec),
ram54288 0:a7a43371b306 91 _security(NULL),
ram54288 0:a7a43371b306 92 _use_secure_connection(false),
ram54288 0:a7a43371b306 93 _binding_mode(mode),
ram54288 0:a7a43371b306 94 _network_stack(stack),
ram54288 0:a7a43371b306 95 _socket(0),
ram54288 0:a7a43371b306 96 _is_handshaking(false),
ram54288 0:a7a43371b306 97 _listening(true),
ram54288 0:a7a43371b306 98 _server_type(M2MConnectionObserver::LWM2MServer),
ram54288 0:a7a43371b306 99 _server_port(0),
ram54288 0:a7a43371b306 100 _listen_port(0),
ram54288 0:a7a43371b306 101 _running(false),
ram54288 0:a7a43371b306 102 _net_iface(0)
ram54288 0:a7a43371b306 103 {
ram54288 0:a7a43371b306 104 #ifndef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 105 if (is_tcp_connection()) {
ram54288 0:a7a43371b306 106 tr_error("ConnectionHandler: TCP support not available.");
ram54288 0:a7a43371b306 107 return;
ram54288 0:a7a43371b306 108 }
ram54288 0:a7a43371b306 109 #endif
ram54288 0:a7a43371b306 110
ram54288 0:a7a43371b306 111 if(PAL_SUCCESS != pal_init()){
ram54288 0:a7a43371b306 112 tr_error("PAL init failed.");
ram54288 0:a7a43371b306 113 }
ram54288 0:a7a43371b306 114
ram54288 0:a7a43371b306 115 memset(&_address, 0, sizeof _address);
ram54288 0:a7a43371b306 116 memset(&_socket_address, 0, sizeof _socket_address);
ram54288 0:a7a43371b306 117 connection_handler = this;
ram54288 0:a7a43371b306 118 eventOS_scheduler_mutex_wait();
ram54288 0:a7a43371b306 119 if (M2MConnectionHandlerPimpl::_tasklet_id == -1) {
ram54288 0:a7a43371b306 120 M2MConnectionHandlerPimpl::_tasklet_id = eventOS_event_handler_create(&connection_event_handler, ESocketIdle);
ram54288 0:a7a43371b306 121 }
ram54288 0:a7a43371b306 122 eventOS_scheduler_mutex_release();
ram54288 0:a7a43371b306 123 }
ram54288 0:a7a43371b306 124
ram54288 0:a7a43371b306 125 M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl()
ram54288 0:a7a43371b306 126 {
ram54288 0:a7a43371b306 127 tr_debug("~M2MConnectionHandlerPimpl()");
ram54288 0:a7a43371b306 128 stop_listening();
ram54288 0:a7a43371b306 129
ram54288 0:a7a43371b306 130 close_socket();
ram54288 0:a7a43371b306 131
ram54288 0:a7a43371b306 132 delete _security_impl;
ram54288 0:a7a43371b306 133 tr_debug("~M2MConnectionHandlerPimpl() - OUT");
ram54288 0:a7a43371b306 134 }
ram54288 0:a7a43371b306 135
ram54288 0:a7a43371b306 136 bool M2MConnectionHandlerPimpl::bind_connection(const uint16_t listen_port)
ram54288 0:a7a43371b306 137 {
ram54288 0:a7a43371b306 138 _listen_port = listen_port;
ram54288 0:a7a43371b306 139 return true;
ram54288 0:a7a43371b306 140 }
ram54288 0:a7a43371b306 141
ram54288 0:a7a43371b306 142 bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_address,
ram54288 0:a7a43371b306 143 const uint16_t server_port,
ram54288 0:a7a43371b306 144 M2MConnectionObserver::ServerType server_type,
ram54288 0:a7a43371b306 145 const M2MSecurity* security)
ram54288 0:a7a43371b306 146 {
ram54288 0:a7a43371b306 147 arm_event_s event;
ram54288 0:a7a43371b306 148
ram54288 0:a7a43371b306 149 tr_debug("resolve_server_address()");
ram54288 0:a7a43371b306 150
ram54288 0:a7a43371b306 151 _security = security;
ram54288 0:a7a43371b306 152 _server_port = server_port;
ram54288 0:a7a43371b306 153 _server_type = server_type;
ram54288 0:a7a43371b306 154 _server_address = server_address;
ram54288 0:a7a43371b306 155
ram54288 0:a7a43371b306 156 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id;
ram54288 0:a7a43371b306 157 event.sender = 0;
ram54288 0:a7a43371b306 158 event.event_type = ESocketDnsHandler;
ram54288 0:a7a43371b306 159 event.data_ptr = NULL;
ram54288 0:a7a43371b306 160 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT;
ram54288 0:a7a43371b306 161
ram54288 0:a7a43371b306 162 return !eventOS_event_send(&event);
ram54288 0:a7a43371b306 163 }
ram54288 0:a7a43371b306 164
ram54288 0:a7a43371b306 165 void M2MConnectionHandlerPimpl::dns_handler()
ram54288 0:a7a43371b306 166 {
ram54288 0:a7a43371b306 167 palStatus_t status;
ram54288 0:a7a43371b306 168 uint32_t interface_count;
ram54288 0:a7a43371b306 169 status = pal_getNumberOfNetInterfaces(&interface_count);
ram54288 0:a7a43371b306 170 if(PAL_SUCCESS != status ) {
ram54288 0:a7a43371b306 171 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 172 return;
ram54288 0:a7a43371b306 173 }
ram54288 0:a7a43371b306 174 if(interface_count <= 0) {
ram54288 0:a7a43371b306 175 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 176 return;
ram54288 0:a7a43371b306 177 }
ram54288 0:a7a43371b306 178
ram54288 0:a7a43371b306 179 palSocketLength_t _socket_address_len;
ram54288 0:a7a43371b306 180
ram54288 0:a7a43371b306 181 if(PAL_SUCCESS != pal_getAddressInfo(_server_address.c_str(), &_socket_address, &_socket_address_len)){
ram54288 0:a7a43371b306 182 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 183 return;
ram54288 0:a7a43371b306 184 }
ram54288 0:a7a43371b306 185 pal_setSockAddrPort(&_socket_address, _server_port);
ram54288 0:a7a43371b306 186
ram54288 0:a7a43371b306 187 if(_network_stack == M2MInterface::LwIP_IPv4 ||
ram54288 0:a7a43371b306 188 _network_stack == M2MInterface::ATWINC_IPv4){
ram54288 0:a7a43371b306 189 if(PAL_SUCCESS != pal_getSockAddrIPV4Addr(&_socket_address,_ipV4Addr)){
ram54288 0:a7a43371b306 190 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 191 return;
ram54288 0:a7a43371b306 192 }
ram54288 0:a7a43371b306 193
ram54288 0:a7a43371b306 194 tr_debug("IP Address %s",tr_array(_ipV4Addr, 4));
ram54288 0:a7a43371b306 195
ram54288 0:a7a43371b306 196 _address._address = (void*)_ipV4Addr;
ram54288 0:a7a43371b306 197 _address._length = PAL_IPV4_ADDRESS_SIZE;
ram54288 0:a7a43371b306 198 _address._port = _server_port;
ram54288 0:a7a43371b306 199 _address._stack = _network_stack;
ram54288 0:a7a43371b306 200 }
ram54288 0:a7a43371b306 201 else if(_network_stack == M2MInterface::LwIP_IPv6 ||
ram54288 0:a7a43371b306 202 _network_stack == M2MInterface::Nanostack_IPv6){
ram54288 0:a7a43371b306 203 if(PAL_SUCCESS != pal_getSockAddrIPV6Addr(&_socket_address,_ipV6Addr)){
ram54288 0:a7a43371b306 204 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 205 return;
ram54288 0:a7a43371b306 206 }
ram54288 0:a7a43371b306 207
ram54288 0:a7a43371b306 208 tr_debug("IP Address %s",tr_array(_ipV6Addr,sizeof(_ipV6Addr)));
ram54288 0:a7a43371b306 209
ram54288 0:a7a43371b306 210 _address._address = (void*)_ipV6Addr;
ram54288 0:a7a43371b306 211 _address._length = PAL_IPV6_ADDRESS_SIZE;
ram54288 0:a7a43371b306 212 _address._port = _server_port;
ram54288 0:a7a43371b306 213 _address._stack = _network_stack;
ram54288 0:a7a43371b306 214 }
ram54288 0:a7a43371b306 215 else {
ram54288 0:a7a43371b306 216 tr_error("socket config error, %d", (int)_network_stack);
ram54288 0:a7a43371b306 217 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 218 return;
ram54288 0:a7a43371b306 219 }
ram54288 0:a7a43371b306 220
ram54288 0:a7a43371b306 221 close_socket();
ram54288 0:a7a43371b306 222 if(!init_socket()) {
ram54288 0:a7a43371b306 223 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 224 return;
ram54288 0:a7a43371b306 225 }
ram54288 0:a7a43371b306 226
ram54288 0:a7a43371b306 227 if(is_tcp_connection()) {
ram54288 0:a7a43371b306 228 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 229 tr_debug("resolve_server_address - Using TCP");
ram54288 0:a7a43371b306 230 if (pal_connect(_socket, &_socket_address, sizeof(_socket_address)) != PAL_SUCCESS) {
ram54288 0:a7a43371b306 231 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 232 return;
ram54288 0:a7a43371b306 233 }
ram54288 0:a7a43371b306 234 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 235 }
ram54288 0:a7a43371b306 236
ram54288 0:a7a43371b306 237 _running = true;
ram54288 0:a7a43371b306 238
ram54288 0:a7a43371b306 239 if (_security) {
ram54288 0:a7a43371b306 240 if (_security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Certificate ||
ram54288 0:a7a43371b306 241 _security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Psk) {
ram54288 0:a7a43371b306 242 if( _security_impl != NULL ){
ram54288 0:a7a43371b306 243 _security_impl->reset();
ram54288 0:a7a43371b306 244 if (_security_impl->init(_security) == 0) {
ram54288 0:a7a43371b306 245 _is_handshaking = true;
ram54288 0:a7a43371b306 246 tr_debug("resolve_server_address - connect DTLS");
ram54288 0:a7a43371b306 247 if(_security_impl->start_connecting_non_blocking(_base) < 0 ){
ram54288 0:a7a43371b306 248 tr_debug("dns_handler - handshake failed");
ram54288 0:a7a43371b306 249 _is_handshaking = false;
ram54288 0:a7a43371b306 250 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR);
ram54288 0:a7a43371b306 251 close_socket();
ram54288 0:a7a43371b306 252 return;
ram54288 0:a7a43371b306 253 }
ram54288 0:a7a43371b306 254 } else {
ram54288 0:a7a43371b306 255 tr_error("resolve_server_address - init failed");
ram54288 0:a7a43371b306 256 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, false);
ram54288 0:a7a43371b306 257 close_socket();
ram54288 0:a7a43371b306 258 return;
ram54288 0:a7a43371b306 259 }
ram54288 0:a7a43371b306 260 } else {
ram54288 0:a7a43371b306 261 tr_error("dns_handler - sec is null");
ram54288 0:a7a43371b306 262 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, false);
ram54288 0:a7a43371b306 263 close_socket();
ram54288 0:a7a43371b306 264 return;
ram54288 0:a7a43371b306 265 }
ram54288 0:a7a43371b306 266 }
ram54288 0:a7a43371b306 267 }
ram54288 0:a7a43371b306 268 if(!_is_handshaking) {
ram54288 0:a7a43371b306 269 enable_keepalive();
ram54288 0:a7a43371b306 270 _observer.address_ready(_address,
ram54288 0:a7a43371b306 271 _server_type,
ram54288 0:a7a43371b306 272 _address._port);
ram54288 0:a7a43371b306 273 }
ram54288 0:a7a43371b306 274 }
ram54288 0:a7a43371b306 275
ram54288 0:a7a43371b306 276 bool M2MConnectionHandlerPimpl::send_data(uint8_t *data,
ram54288 0:a7a43371b306 277 uint16_t data_len,
ram54288 0:a7a43371b306 278 sn_nsdl_addr_s *address)
ram54288 0:a7a43371b306 279 {
ram54288 0:a7a43371b306 280 arm_event_s event;
ram54288 0:a7a43371b306 281
ram54288 0:a7a43371b306 282 tr_debug("send_data()");
ram54288 0:a7a43371b306 283 if (address == NULL || data == NULL || !data_len || !_running) {
ram54288 0:a7a43371b306 284 return false;
ram54288 0:a7a43371b306 285 }
ram54288 0:a7a43371b306 286
ram54288 0:a7a43371b306 287 event.data_ptr = (uint8_t*)malloc(data_len);
ram54288 0:a7a43371b306 288 if(!event.data_ptr) {
ram54288 0:a7a43371b306 289 return false;
ram54288 0:a7a43371b306 290 }
ram54288 0:a7a43371b306 291 memcpy(event.data_ptr, data, data_len);
ram54288 0:a7a43371b306 292
ram54288 0:a7a43371b306 293 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id;
ram54288 0:a7a43371b306 294 event.sender = 0;
ram54288 0:a7a43371b306 295 event.event_type = ESocketSend;
ram54288 0:a7a43371b306 296 event.event_data = data_len;
ram54288 0:a7a43371b306 297 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT;
ram54288 0:a7a43371b306 298
ram54288 0:a7a43371b306 299 if (eventOS_event_send(&event) != 0) {
ram54288 0:a7a43371b306 300 // Event push failed, free the buffer
ram54288 0:a7a43371b306 301 free(event.data_ptr);
ram54288 0:a7a43371b306 302 return false;
ram54288 0:a7a43371b306 303 }
ram54288 0:a7a43371b306 304
ram54288 0:a7a43371b306 305 return true;
ram54288 0:a7a43371b306 306 }
ram54288 0:a7a43371b306 307
ram54288 0:a7a43371b306 308 void M2MConnectionHandlerPimpl::send_socket_data(uint8_t *data, uint16_t data_len)
ram54288 0:a7a43371b306 309 {
ram54288 0:a7a43371b306 310 size_t sent_len;
ram54288 0:a7a43371b306 311 bool success = false;
ram54288 0:a7a43371b306 312 palStatus_t ret = PAL_ERR_GENERIC_FAILURE;
ram54288 0:a7a43371b306 313
ram54288 0:a7a43371b306 314 if(!data || ! data_len || !_running) {
ram54288 0:a7a43371b306 315 return;
ram54288 0:a7a43371b306 316 }
ram54288 0:a7a43371b306 317
ram54288 0:a7a43371b306 318 tr_debug("send_handler()");
ram54288 0:a7a43371b306 319
ram54288 0:a7a43371b306 320 if( _use_secure_connection ){
ram54288 0:a7a43371b306 321 if( _security_impl->send_message(data, data_len) > 0){
ram54288 0:a7a43371b306 322 success = true;
ram54288 0:a7a43371b306 323 }
ram54288 0:a7a43371b306 324 } else {
ram54288 0:a7a43371b306 325 if(is_tcp_connection()){
ram54288 0:a7a43371b306 326 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 327 //We need to "shim" the length in front
ram54288 0:a7a43371b306 328 uint8_t* d = (uint8_t*)malloc(data_len+4);
ram54288 0:a7a43371b306 329 if(d){
ram54288 0:a7a43371b306 330 d[0] = 0;
ram54288 0:a7a43371b306 331 d[1] = 0;
ram54288 0:a7a43371b306 332 d[2] = (data_len >> 8 )& 0xff;
ram54288 0:a7a43371b306 333 d[3] = data_len & 0xff;
ram54288 0:a7a43371b306 334 memcpy(d + 4, data, data_len);
ram54288 0:a7a43371b306 335 ret = pal_send(_socket, d, data_len+4, &sent_len);
ram54288 0:a7a43371b306 336 free(d);
ram54288 0:a7a43371b306 337 }
ram54288 0:a7a43371b306 338 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 339 } else {
ram54288 0:a7a43371b306 340 ret = pal_sendTo(_socket, data, data_len, &_socket_address, sizeof(_socket_address), &sent_len);
ram54288 0:a7a43371b306 341 }
ram54288 0:a7a43371b306 342 if (ret == PAL_SUCCESS) {
ram54288 0:a7a43371b306 343 success = true;
ram54288 0:a7a43371b306 344 }
ram54288 0:a7a43371b306 345 }
ram54288 0:a7a43371b306 346
ram54288 0:a7a43371b306 347 if (!success) {
ram54288 0:a7a43371b306 348 _observer.socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR, true);
ram54288 0:a7a43371b306 349 close_socket();
ram54288 0:a7a43371b306 350 }
ram54288 0:a7a43371b306 351 else{
ram54288 0:a7a43371b306 352 _observer.data_sent();
ram54288 0:a7a43371b306 353 }
ram54288 0:a7a43371b306 354 }
ram54288 0:a7a43371b306 355
ram54288 0:a7a43371b306 356 bool M2MConnectionHandlerPimpl::start_listening_for_data()
ram54288 0:a7a43371b306 357 {
ram54288 0:a7a43371b306 358 tr_debug("start_listening_for_data()");
ram54288 0:a7a43371b306 359 _listening = true;
ram54288 0:a7a43371b306 360 return true;
ram54288 0:a7a43371b306 361 }
ram54288 0:a7a43371b306 362
ram54288 0:a7a43371b306 363 void M2MConnectionHandlerPimpl::stop_listening()
ram54288 0:a7a43371b306 364 {
ram54288 0:a7a43371b306 365 tr_debug("stop_listening()");
ram54288 0:a7a43371b306 366 _listening = false;
ram54288 0:a7a43371b306 367
ram54288 0:a7a43371b306 368 if(_security_impl) {
ram54288 0:a7a43371b306 369 _security_impl->reset();
ram54288 0:a7a43371b306 370 }
ram54288 0:a7a43371b306 371 }
ram54288 0:a7a43371b306 372
ram54288 0:a7a43371b306 373 int M2MConnectionHandlerPimpl::send_to_socket(const unsigned char *buf, size_t len)
ram54288 0:a7a43371b306 374 {
ram54288 0:a7a43371b306 375 size_t sent_len = 0;
ram54288 0:a7a43371b306 376 palStatus_t status = PAL_ERR_GENERIC_FAILURE;
ram54288 0:a7a43371b306 377
ram54288 0:a7a43371b306 378 if(!_running) {
ram54288 0:a7a43371b306 379 return (-1);
ram54288 0:a7a43371b306 380 }
ram54288 0:a7a43371b306 381
ram54288 0:a7a43371b306 382 tr_debug("send_to_socket len - %d", len);
ram54288 0:a7a43371b306 383
ram54288 0:a7a43371b306 384 if(is_tcp_connection()) {
ram54288 0:a7a43371b306 385 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 386 status = pal_send(_socket, buf, len, &sent_len);
ram54288 0:a7a43371b306 387 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 388 } else {
ram54288 0:a7a43371b306 389 status = pal_sendTo(_socket, buf, len, &_socket_address, sizeof(_socket_address), &sent_len);
ram54288 0:a7a43371b306 390 }
ram54288 0:a7a43371b306 391
ram54288 0:a7a43371b306 392 if(status == PAL_SUCCESS){
ram54288 0:a7a43371b306 393 return sent_len;
ram54288 0:a7a43371b306 394 }
ram54288 0:a7a43371b306 395
ram54288 0:a7a43371b306 396 return (-1);
ram54288 0:a7a43371b306 397 }
ram54288 0:a7a43371b306 398
ram54288 0:a7a43371b306 399 int M2MConnectionHandlerPimpl::receive_from_socket(unsigned char *buf, size_t len)
ram54288 0:a7a43371b306 400 {
ram54288 0:a7a43371b306 401 size_t recv_len;
ram54288 0:a7a43371b306 402 palStatus_t status = PAL_ERR_GENERIC_FAILURE;
ram54288 0:a7a43371b306 403 tr_debug("receive_from_socket");
ram54288 0:a7a43371b306 404
ram54288 0:a7a43371b306 405 if(!_running) {
ram54288 0:a7a43371b306 406 return (-1);
ram54288 0:a7a43371b306 407 }
ram54288 0:a7a43371b306 408
ram54288 0:a7a43371b306 409 if(is_tcp_connection()) {
ram54288 0:a7a43371b306 410 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 411 status = pal_recv(_socket, buf, len, &recv_len);
ram54288 0:a7a43371b306 412 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 413 } else {
ram54288 0:a7a43371b306 414 status = pal_receiveFrom(_socket, buf, len, NULL, NULL, &recv_len);
ram54288 0:a7a43371b306 415 }
ram54288 0:a7a43371b306 416
ram54288 0:a7a43371b306 417 if(status == PAL_SUCCESS){
ram54288 0:a7a43371b306 418 return recv_len;
ram54288 0:a7a43371b306 419 }
ram54288 0:a7a43371b306 420 else if(status == PAL_ERR_SOCKET_WOULD_BLOCK || status == (-65536)){
ram54288 0:a7a43371b306 421 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ;
ram54288 0:a7a43371b306 422 }
ram54288 0:a7a43371b306 423 else {
ram54288 0:a7a43371b306 424 tr_info("PAL Socket returned: %d", status);
ram54288 0:a7a43371b306 425 }
ram54288 0:a7a43371b306 426
ram54288 0:a7a43371b306 427 return (-1);
ram54288 0:a7a43371b306 428 }
ram54288 0:a7a43371b306 429
ram54288 0:a7a43371b306 430 void M2MConnectionHandlerPimpl::handle_connection_error(int error)
ram54288 0:a7a43371b306 431 {
ram54288 0:a7a43371b306 432 tr_debug("handle_connection_error");
ram54288 0:a7a43371b306 433 _observer.socket_error(error);
ram54288 0:a7a43371b306 434 }
ram54288 0:a7a43371b306 435
ram54288 0:a7a43371b306 436 void M2MConnectionHandlerPimpl::set_platform_network_handler(void *handler)
ram54288 0:a7a43371b306 437 {
ram54288 0:a7a43371b306 438 tr_debug("set_platform_network_handler");
ram54288 0:a7a43371b306 439 if(PAL_SUCCESS != pal_registerNetworkInterface(handler, &_net_iface)) {
ram54288 0:a7a43371b306 440 tr_error("Interface registration failed.");
ram54288 0:a7a43371b306 441 }
ram54288 0:a7a43371b306 442 }
ram54288 0:a7a43371b306 443
ram54288 0:a7a43371b306 444 void M2MConnectionHandlerPimpl::receive_handshake_handler()
ram54288 0:a7a43371b306 445 {
ram54288 0:a7a43371b306 446 tr_debug("receive_handshake_handler()");
ram54288 0:a7a43371b306 447 if( _is_handshaking ){
ram54288 0:a7a43371b306 448 int ret = _security_impl->continue_connecting();
ram54288 0:a7a43371b306 449 tr_debug("ret %d", ret);
ram54288 0:a7a43371b306 450 if( ret == M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ ){ //We wait for next readable event
ram54288 0:a7a43371b306 451 tr_debug("We wait for next readable event");
ram54288 0:a7a43371b306 452 return;
ram54288 0:a7a43371b306 453 } else if( ret == 0 ){
ram54288 0:a7a43371b306 454 _is_handshaking = false;
ram54288 0:a7a43371b306 455 _use_secure_connection = true;
ram54288 0:a7a43371b306 456 enable_keepalive();
ram54288 0:a7a43371b306 457 _observer.address_ready(_address,
ram54288 0:a7a43371b306 458 _server_type,
ram54288 0:a7a43371b306 459 _server_port);
ram54288 0:a7a43371b306 460 } else if( ret < 0 ){
ram54288 0:a7a43371b306 461 _is_handshaking = false;
ram54288 0:a7a43371b306 462 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, true);
ram54288 0:a7a43371b306 463 close_socket();
ram54288 0:a7a43371b306 464 }
ram54288 0:a7a43371b306 465 }
ram54288 0:a7a43371b306 466 }
ram54288 0:a7a43371b306 467
ram54288 0:a7a43371b306 468 bool M2MConnectionHandlerPimpl::is_handshake_ongoing()
ram54288 0:a7a43371b306 469 {
ram54288 0:a7a43371b306 470 return _is_handshaking;
ram54288 0:a7a43371b306 471 }
ram54288 0:a7a43371b306 472
ram54288 0:a7a43371b306 473 void M2MConnectionHandlerPimpl::receive_handler()
ram54288 0:a7a43371b306 474 {
ram54288 0:a7a43371b306 475 tr_debug("receive_handler()");
ram54288 0:a7a43371b306 476 if(_is_handshaking){
ram54288 0:a7a43371b306 477 receive_handshake_handler();
ram54288 0:a7a43371b306 478 return;
ram54288 0:a7a43371b306 479 }
ram54288 0:a7a43371b306 480
ram54288 0:a7a43371b306 481 if(!_listening || !_running) {
ram54288 0:a7a43371b306 482 return;
ram54288 0:a7a43371b306 483 }
ram54288 0:a7a43371b306 484
ram54288 0:a7a43371b306 485 if( _use_secure_connection ){
ram54288 0:a7a43371b306 486 int rcv_size;
ram54288 0:a7a43371b306 487 do{
ram54288 0:a7a43371b306 488 rcv_size = _security_impl->read(_recv_buffer, sizeof(_recv_buffer));
ram54288 0:a7a43371b306 489 if(rcv_size > 0){
ram54288 0:a7a43371b306 490 _observer.data_available((uint8_t*)_recv_buffer,
ram54288 0:a7a43371b306 491 rcv_size, _address);
ram54288 0:a7a43371b306 492 } else if (M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ != rcv_size && rcv_size < 0) {
ram54288 0:a7a43371b306 493 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true);
ram54288 0:a7a43371b306 494 close_socket();
ram54288 0:a7a43371b306 495 return;
ram54288 0:a7a43371b306 496 }
ram54288 0:a7a43371b306 497 } while(M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ != rcv_size);
ram54288 0:a7a43371b306 498 } else{
ram54288 0:a7a43371b306 499 size_t recv;
ram54288 0:a7a43371b306 500 palStatus_t status;
ram54288 0:a7a43371b306 501 do{
ram54288 0:a7a43371b306 502 if(is_tcp_connection()){
ram54288 0:a7a43371b306 503 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 504 status = pal_recv(_socket, _recv_buffer, sizeof(_recv_buffer), &recv);
ram54288 0:a7a43371b306 505 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 506 } else{
ram54288 0:a7a43371b306 507 status = pal_receiveFrom(_socket, _recv_buffer, sizeof(_recv_buffer), NULL, NULL, &recv);
ram54288 0:a7a43371b306 508 }
ram54288 0:a7a43371b306 509
ram54288 0:a7a43371b306 510 if(status == PAL_ERR_SOCKET_WOULD_BLOCK){
ram54288 0:a7a43371b306 511 return;
ram54288 0:a7a43371b306 512 }
ram54288 0:a7a43371b306 513 else if (status != PAL_SUCCESS) {
ram54288 0:a7a43371b306 514 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true);
ram54288 0:a7a43371b306 515 close_socket();
ram54288 0:a7a43371b306 516 return;
ram54288 0:a7a43371b306 517 }
ram54288 0:a7a43371b306 518
ram54288 0:a7a43371b306 519 tr_debug("data received, len: %zu", recv);
ram54288 0:a7a43371b306 520
ram54288 0:a7a43371b306 521 if(!is_tcp_connection()){ // Observer for UDP plain mode
ram54288 0:a7a43371b306 522 _observer.data_available((uint8_t*)_recv_buffer, recv, _address);
ram54288 0:a7a43371b306 523 } else {
ram54288 0:a7a43371b306 524 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 525 if( recv < 4 ){
ram54288 0:a7a43371b306 526 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true);
ram54288 0:a7a43371b306 527 close_socket();
ram54288 0:a7a43371b306 528 return;
ram54288 0:a7a43371b306 529 }
ram54288 0:a7a43371b306 530
ram54288 0:a7a43371b306 531 //We need to "shim" out the length from the front
ram54288 0:a7a43371b306 532 uint32_t len = (_recv_buffer[0] << 24 & 0xFF000000) + (_recv_buffer[1] << 16 & 0xFF0000);
ram54288 0:a7a43371b306 533 len += (_recv_buffer[2] << 8 & 0xFF00) + (_recv_buffer[3] & 0xFF);
ram54288 0:a7a43371b306 534 if(len > 0 && len <= recv - 4) {
ram54288 0:a7a43371b306 535 // Observer for TCP plain mode
ram54288 0:a7a43371b306 536 _observer.data_available(_recv_buffer + 4, len, _address);
ram54288 0:a7a43371b306 537 }
ram54288 0:a7a43371b306 538 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 539 }
ram54288 0:a7a43371b306 540 } while(status != PAL_ERR_SOCKET_WOULD_BLOCK);
ram54288 0:a7a43371b306 541 }
ram54288 0:a7a43371b306 542 }
ram54288 0:a7a43371b306 543
ram54288 0:a7a43371b306 544 void M2MConnectionHandlerPimpl::claim_mutex()
ram54288 0:a7a43371b306 545 {
ram54288 0:a7a43371b306 546 eventOS_scheduler_mutex_wait();
ram54288 0:a7a43371b306 547 }
ram54288 0:a7a43371b306 548
ram54288 0:a7a43371b306 549 void M2MConnectionHandlerPimpl::release_mutex()
ram54288 0:a7a43371b306 550 {
ram54288 0:a7a43371b306 551 eventOS_scheduler_mutex_release();
ram54288 0:a7a43371b306 552 }
ram54288 0:a7a43371b306 553
ram54288 0:a7a43371b306 554 static palNetInterfaceInfo_t interface_info;
ram54288 0:a7a43371b306 555 static palIpV4Addr_t interface_address4 = {0,0,0,0};
ram54288 0:a7a43371b306 556 static palIpV6Addr_t interface_address6 = {0};
ram54288 0:a7a43371b306 557
ram54288 0:a7a43371b306 558 bool M2MConnectionHandlerPimpl::init_socket()
ram54288 0:a7a43371b306 559 {
ram54288 0:a7a43371b306 560 tr_debug("init_socket - IN");
ram54288 0:a7a43371b306 561 _is_handshaking = false;
ram54288 0:a7a43371b306 562 _running = true;
ram54288 0:a7a43371b306 563 palSocketType_t socket_type = PAL_SOCK_DGRAM;
ram54288 0:a7a43371b306 564 palStatus_t status;
ram54288 0:a7a43371b306 565 palSocketDomain_t domain;
ram54288 0:a7a43371b306 566 palSocketAddress_t bind_address;
ram54288 0:a7a43371b306 567
ram54288 0:a7a43371b306 568 if(is_tcp_connection()) {
ram54288 0:a7a43371b306 569 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 570 socket_type = PAL_SOCK_STREAM;
ram54288 0:a7a43371b306 571 #else
ram54288 0:a7a43371b306 572 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 573 return;
ram54288 0:a7a43371b306 574 #endif //PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 575 }
ram54288 0:a7a43371b306 576
ram54288 0:a7a43371b306 577 if(_network_stack == M2MInterface::LwIP_IPv4){
ram54288 0:a7a43371b306 578 domain = PAL_AF_INET;
ram54288 0:a7a43371b306 579 } else if(_network_stack == M2MInterface::LwIP_IPv6){
ram54288 0:a7a43371b306 580 domain = PAL_AF_INET6;
ram54288 0:a7a43371b306 581 } else {
ram54288 0:a7a43371b306 582 domain = PAL_AF_UNSPEC;
ram54288 0:a7a43371b306 583 }
ram54288 0:a7a43371b306 584
ram54288 0:a7a43371b306 585 uint32_t interface_count;
ram54288 0:a7a43371b306 586 pal_getNumberOfNetInterfaces(&interface_count);
ram54288 0:a7a43371b306 587 tr_debug("Interface count: %d",interface_count);
ram54288 0:a7a43371b306 588 pal_getNetInterfaceInfo(_net_iface, &interface_info);
ram54288 0:a7a43371b306 589 tr_debug("Interface name: %s",interface_info.interfaceName);
ram54288 0:a7a43371b306 590 tr_debug("Interface no: %d", _net_iface);
ram54288 0:a7a43371b306 591
ram54288 0:a7a43371b306 592 tr_debug("init_socket - port %d", _listen_port);
ram54288 0:a7a43371b306 593
ram54288 0:a7a43371b306 594 status = pal_asynchronousSocket(domain, socket_type, 1, _net_iface, &socket_event_handler, &_socket);
ram54288 0:a7a43371b306 595
ram54288 0:a7a43371b306 596 if(PAL_SUCCESS != status) {
ram54288 0:a7a43371b306 597 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT);
ram54288 0:a7a43371b306 598 return false;
ram54288 0:a7a43371b306 599 }
ram54288 0:a7a43371b306 600
ram54288 0:a7a43371b306 601 if(_network_stack == M2MInterface::LwIP_IPv4){
ram54288 0:a7a43371b306 602 pal_setSockAddrIPV4Addr(&bind_address, interface_address4);
ram54288 0:a7a43371b306 603 } else if(_network_stack == M2MInterface::LwIP_IPv6){
ram54288 0:a7a43371b306 604 pal_setSockAddrIPV6Addr(&bind_address, interface_address6);
ram54288 0:a7a43371b306 605 }
ram54288 0:a7a43371b306 606
ram54288 0:a7a43371b306 607 pal_setSockAddrPort(&bind_address, _listen_port);
ram54288 0:a7a43371b306 608 pal_bind(_socket, &bind_address, sizeof(bind_address));
ram54288 0:a7a43371b306 609
ram54288 0:a7a43371b306 610 tr_debug("init_socket - OUT");
ram54288 0:a7a43371b306 611 return true;
ram54288 0:a7a43371b306 612 }
ram54288 0:a7a43371b306 613
ram54288 0:a7a43371b306 614 bool M2MConnectionHandlerPimpl::is_tcp_connection()
ram54288 0:a7a43371b306 615 {
ram54288 0:a7a43371b306 616 return ( _binding_mode == M2MInterface::TCP ||
ram54288 0:a7a43371b306 617 _binding_mode == M2MInterface::TCP_QUEUE );
ram54288 0:a7a43371b306 618 }
ram54288 0:a7a43371b306 619
ram54288 0:a7a43371b306 620 void M2MConnectionHandlerPimpl::close_socket()
ram54288 0:a7a43371b306 621 {
ram54288 0:a7a43371b306 622 tr_debug("close_socket() - IN");
ram54288 0:a7a43371b306 623 if(_running) {
ram54288 0:a7a43371b306 624 _running = false;
ram54288 0:a7a43371b306 625 pal_close(&_socket);
ram54288 0:a7a43371b306 626 }
ram54288 0:a7a43371b306 627 tr_debug("close_socket() - OUT");
ram54288 0:a7a43371b306 628 }
ram54288 0:a7a43371b306 629
ram54288 0:a7a43371b306 630 void M2MConnectionHandlerPimpl::enable_keepalive()
ram54288 0:a7a43371b306 631 {
ram54288 0:a7a43371b306 632 #if MBED_CLIENT_TCP_KEEPALIVE_TIME
ram54288 0:a7a43371b306 633 #ifdef PAL_NET_TCP_AND_TLS_SUPPORT
ram54288 0:a7a43371b306 634 if(is_tcp_connection()) {
ram54288 0:a7a43371b306 635 int enable = 1;
ram54288 0:a7a43371b306 636 pal_setSocketOptions(_socket, PAL_SO_KEEPALIVE, &enable, sizeof(enable));
ram54288 0:a7a43371b306 637 }
ram54288 0:a7a43371b306 638 #endif
ram54288 0:a7a43371b306 639 #endif
ram54288 0:a7a43371b306 640 }