FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

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