This is an example of BLE GATT Client, which receives broadcast data from BLE_Server_BME280 ( a GATT server) , then transfers values up to mbed Device Connector (cloud).

Please refer details about BLEClient_mbedDevConn below. https://github.com/soramame21/BLEClient_mbedDevConn

The location of required BLE GATT server, BLE_Server_BME280, is at here. https://developer.mbed.org/users/edamame22/code/BLE_Server_BME280/

Committer:
Ren Boting
Date:
Tue Sep 05 11:56:13 2017 +0900
Revision:
2:b894b3508057
Parent:
0:29983394c6b6
Update all libraries and reform main.cpp

Who changed what in which revision?

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