sandbox / mbed-client-classic

Fork of mbed-client-classic by Christopher Haster

Committer:
Yogesh Pande
Date:
Sat Apr 02 00:40:01 2016 +0300
Revision:
8:bdd418027540
Parent:
7:774e507fc261
Child:
9:17cb48fbeb85
Implementation for using NetworkSocketAPI and mbedClient Timer API fix.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 1:2dc916e504c9 1 /*
Christopher Haster 1:2dc916e504c9 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
Christopher Haster 1:2dc916e504c9 3 * SPDX-License-Identifier: Apache-2.0
Christopher Haster 1:2dc916e504c9 4 * Licensed under the Apache License, Version 2.0 (the License); you may
Christopher Haster 1:2dc916e504c9 5 * not use this file except in compliance with the License.
Christopher Haster 1:2dc916e504c9 6 * You may obtain a copy of the License at
Christopher Haster 1:2dc916e504c9 7 *
Christopher Haster 1:2dc916e504c9 8 * http://www.apache.org/licenses/LICENSE-2.0
Christopher Haster 1:2dc916e504c9 9 *
Christopher Haster 1:2dc916e504c9 10 * Unless required by applicable law or agreed to in writing, software
Christopher Haster 1:2dc916e504c9 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
Christopher Haster 1:2dc916e504c9 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Christopher Haster 1:2dc916e504c9 13 * See the License for the specific language governing permissions and
Christopher Haster 1:2dc916e504c9 14 * limitations under the License.
Christopher Haster 1:2dc916e504c9 15 */
Christopher Haster 1:2dc916e504c9 16 #include "mbed-client-classic/m2mconnectionhandlerpimpl.h"
Christopher Haster 1:2dc916e504c9 17 #include "mbed-client/m2mconnectionobserver.h"
Christopher Haster 1:2dc916e504c9 18 #include "mbed-client/m2mconstants.h"
Christopher Haster 1:2dc916e504c9 19 #include "mbed-client/m2msecurity.h"
Christopher Haster 1:2dc916e504c9 20 #include "mbed-client/m2mconnectionhandler.h"
Christopher Haster 1:2dc916e504c9 21
geky 4:0c58f5786538 22 #include "m2mnetwork.h"
Christopher Haster 1:2dc916e504c9 23 #include "threadwrapper.h"
Christopher Haster 1:2dc916e504c9 24 #include "mbed_error.h"
Christopher Haster 1:2dc916e504c9 25
geky 4:0c58f5786538 26 #include "NetworkInterface.h"
geky 4:0c58f5786538 27 #include "UDPSocket.h"
Yogesh Pande 8:bdd418027540 28 #include "mbed-trace/mbed_trace.h"
geky 4:0c58f5786538 29
Yogesh Pande 8:bdd418027540 30 #define TRACE_GROUP "mClt"
Christopher Haster 1:2dc916e504c9 31
Christopher Haster 1:2dc916e504c9 32 M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer,
Christopher Haster 1:2dc916e504c9 33 M2MConnectionSecurity* sec,
Christopher Haster 1:2dc916e504c9 34 M2MInterface::BindingMode mode,
Christopher Haster 1:2dc916e504c9 35 M2MInterface::NetworkStack stack)
Christopher Haster 1:2dc916e504c9 36 :_base(base),
Christopher Haster 1:2dc916e504c9 37 _observer(observer),
Christopher Haster 1:2dc916e504c9 38 _security_impl(sec),
Christopher Haster 1:2dc916e504c9 39 _use_secure_connection(false),
Christopher Haster 1:2dc916e504c9 40 _binding_mode(mode),
Christopher Haster 1:2dc916e504c9 41 _network_stack(stack),
geky 4:0c58f5786538 42 _socket(0),
Christopher Haster 1:2dc916e504c9 43 _listening(false),
Yogesh Pande 8:bdd418027540 44 _listen_thread(0)
Christopher Haster 1:2dc916e504c9 45 {
Christopher Haster 1:2dc916e504c9 46 memset(&_address_buffer, 0, sizeof _address_buffer);
Christopher Haster 1:2dc916e504c9 47 memset(&_address, 0, sizeof _address);
Christopher Haster 1:2dc916e504c9 48 _address._address = _address_buffer;
Christopher Haster 1:2dc916e504c9 49
Christopher Haster 1:2dc916e504c9 50 if (_network_stack != M2MInterface::LwIP_IPv4) {
Christopher Haster 1:2dc916e504c9 51 error("ConnectionHandler: Unsupported network stack, only IPv4 is currently supported");
Christopher Haster 1:2dc916e504c9 52 }
Christopher Haster 1:2dc916e504c9 53 }
Christopher Haster 1:2dc916e504c9 54
Christopher Haster 1:2dc916e504c9 55 M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl()
Christopher Haster 1:2dc916e504c9 56 {
geky 2:c3434146c3d2 57 _listening = false;
Yogesh Pande 8:bdd418027540 58
geky 2:c3434146c3d2 59 if (_listen_thread) {
geky 2:c3434146c3d2 60 delete _listen_thread;
geky 2:c3434146c3d2 61 _listen_thread = 0;
geky 2:c3434146c3d2 62 }
geky 4:0c58f5786538 63 if (_socket) {
geky 4:0c58f5786538 64 delete _socket;
geky 4:0c58f5786538 65 _socket = 0;
geky 4:0c58f5786538 66 }
Yogesh Pande 8:bdd418027540 67
Christopher Haster 1:2dc916e504c9 68 delete _security_impl;
Christopher Haster 1:2dc916e504c9 69 }
Christopher Haster 1:2dc916e504c9 70
Yogesh Pande 8:bdd418027540 71 bool M2MConnectionHandlerPimpl::bind_connection(const uint16_t /*listen_port*/)
Christopher Haster 1:2dc916e504c9 72 {
geky 4:0c58f5786538 73 return true;
Christopher Haster 1:2dc916e504c9 74 }
Christopher Haster 1:2dc916e504c9 75
Christopher Haster 1:2dc916e504c9 76 bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_address,
Christopher Haster 1:2dc916e504c9 77 const uint16_t server_port,
Christopher Haster 1:2dc916e504c9 78 M2MConnectionObserver::ServerType server_type,
Christopher Haster 1:2dc916e504c9 79 const M2MSecurity* security)
Christopher Haster 1:2dc916e504c9 80 {
Yogesh Pande 8:bdd418027540 81 bool success = false;
geky 4:0c58f5786538 82 NetworkInterface *iface = M2MNetwork::getInterface();
geky 4:0c58f5786538 83 if (!iface) {
Christopher Haster 1:2dc916e504c9 84 return false;
Christopher Haster 1:2dc916e504c9 85 }
Yogesh Pande 8:bdd418027540 86
geky 4:0c58f5786538 87 if (_socket) {
geky 4:0c58f5786538 88 delete _socket;
geky 4:0c58f5786538 89 }
Yogesh Pande 8:bdd418027540 90
geky 4:0c58f5786538 91 _socket = new UDPSocket(iface);
geky 4:0c58f5786538 92 if (_socket->open(server_address.c_str(), server_port) < 0) {
geky 4:0c58f5786538 93 return false;
Yogesh Pande 8:bdd418027540 94 } else {
Yogesh Pande 8:bdd418027540 95 success = true;
geky 4:0c58f5786538 96 }
Christopher Haster 1:2dc916e504c9 97
Christopher Haster 1:2dc916e504c9 98 if (security) {
Christopher Haster 1:2dc916e504c9 99 if (security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Certificate ||
Christopher Haster 1:2dc916e504c9 100 security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Psk) {
Yogesh Pande 8:bdd418027540 101 if( _security_impl != NULL ){
Christopher Haster 1:2dc916e504c9 102 _security_impl->reset();
Christopher Haster 1:2dc916e504c9 103 _security_impl->init(security);
Yogesh Pande 8:bdd418027540 104 tr_debug("M2MConnectionHandlerPimpl::resolve_server_address - connect DTLS");
Yogesh Pande 8:bdd418027540 105 success = 0 == _security_impl->connect(_base);
Yogesh Pande 8:bdd418027540 106 if( success ) {
Yogesh Pande 8:bdd418027540 107 _use_secure_connection = true;
Christopher Haster 1:2dc916e504c9 108 }
Christopher Haster 1:2dc916e504c9 109 }
Christopher Haster 1:2dc916e504c9 110 }
Christopher Haster 1:2dc916e504c9 111 }
Yogesh Pande 8:bdd418027540 112 if(success) {
Yogesh Pande 8:bdd418027540 113 _address._address = (void*)_socket->getIPAddress();
Yogesh Pande 8:bdd418027540 114 _address._length = strlen((char*)_address._address);
Yogesh Pande 8:bdd418027540 115 _address._port = _socket->getPort();
Yogesh Pande 8:bdd418027540 116 _address._stack = _network_stack;
geky 2:c3434146c3d2 117
Yogesh Pande 8:bdd418027540 118 _observer.address_ready(_address,
Yogesh Pande 8:bdd418027540 119 server_type,
Yogesh Pande 8:bdd418027540 120 _address._port);
geky 2:c3434146c3d2 121 }
Yogesh Pande 8:bdd418027540 122 return success;
geky 2:c3434146c3d2 123 }
geky 2:c3434146c3d2 124
Christopher Haster 1:2dc916e504c9 125 bool M2MConnectionHandlerPimpl::send_data(uint8_t *data,
Christopher Haster 1:2dc916e504c9 126 uint16_t data_len,
Christopher Haster 1:2dc916e504c9 127 sn_nsdl_addr_s *address)
Christopher Haster 1:2dc916e504c9 128 {
Yogesh Pande 8:bdd418027540 129 tr_debug("M2MConnectionHandlerPimpl::send_data");
Christopher Haster 1:2dc916e504c9 130 if (address == NULL || data == NULL) {
Christopher Haster 1:2dc916e504c9 131 return false;
Christopher Haster 1:2dc916e504c9 132 }
Yogesh Pande 8:bdd418027540 133
Yogesh Pande 8:bdd418027540 134 bool success = false;
Yogesh Pande 8:bdd418027540 135 if(data){
Yogesh Pande 8:bdd418027540 136 if( _use_secure_connection ){
Yogesh Pande 8:bdd418027540 137 if( _security_impl->send_message(data, data_len) > 0){
Yogesh Pande 8:bdd418027540 138 success = true;
Yogesh Pande 8:bdd418027540 139 _observer.data_sent();
Yogesh Pande 8:bdd418027540 140 }else{
Yogesh Pande 8:bdd418027540 141 _observer.socket_error(1);
Yogesh Pande 8:bdd418027540 142 }
Yogesh Pande 8:bdd418027540 143 } else {
Yogesh Pande 8:bdd418027540 144 if(address) {
Yogesh Pande 8:bdd418027540 145 ssize_t ret = -1;
Yogesh Pande 8:bdd418027540 146
Yogesh Pande 8:bdd418027540 147 ret = _socket->send(data, data_len);
Yogesh Pande 8:bdd418027540 148
Yogesh Pande 8:bdd418027540 149 if (ret==-1) {
Yogesh Pande 8:bdd418027540 150 //tr_debug("M2MConnectionHandlerPimpl::send_data - Error Code is %d\n",errno);
Yogesh Pande 8:bdd418027540 151 _observer.socket_error(1);
Yogesh Pande 8:bdd418027540 152 } else {
Yogesh Pande 8:bdd418027540 153 success = true;
Yogesh Pande 8:bdd418027540 154 _observer.data_sent();
Yogesh Pande 8:bdd418027540 155 }
Yogesh Pande 8:bdd418027540 156 } else {
Yogesh Pande 8:bdd418027540 157 //TODO: Define memory fail error code
Yogesh Pande 8:bdd418027540 158 _observer.socket_error(3);
Yogesh Pande 8:bdd418027540 159 }
Christopher Haster 1:2dc916e504c9 160 }
Christopher Haster 1:2dc916e504c9 161 }
Yogesh Pande 8:bdd418027540 162 return success;
Christopher Haster 1:2dc916e504c9 163 }
Christopher Haster 1:2dc916e504c9 164
Christopher Haster 1:2dc916e504c9 165 bool M2MConnectionHandlerPimpl::start_listening_for_data()
Christopher Haster 1:2dc916e504c9 166 {
Christopher Haster 1:2dc916e504c9 167 _listening = true;
Yogesh Pande 8:bdd418027540 168 _listen_thread = rtos::create_thread<
Yogesh Pande 8:bdd418027540 169 M2MConnectionHandlerPimpl,
Yogesh Pande 8:bdd418027540 170 &M2MConnectionHandlerPimpl::listen_handler>(this);
Christopher Haster 1:2dc916e504c9 171 return true;
Christopher Haster 1:2dc916e504c9 172 }
Christopher Haster 1:2dc916e504c9 173
Christopher Haster 1:2dc916e504c9 174 void M2MConnectionHandlerPimpl::stop_listening()
Christopher Haster 1:2dc916e504c9 175 {
geky 2:c3434146c3d2 176 _listening = false;
Christopher Haster 1:2dc916e504c9 177 }
Christopher Haster 1:2dc916e504c9 178
geky 2:c3434146c3d2 179 void M2MConnectionHandlerPimpl::listen_handler()
Christopher Haster 1:2dc916e504c9 180 {
Yogesh Pande 8:bdd418027540 181 tr_debug("M2MConnectionHandlerPimpl::listen_handler");
Yogesh Pande 8:bdd418027540 182 memset(_recv_buffer, 0, sizeof(_recv_buffer));
Yogesh Pande 8:bdd418027540 183 int rcv_size = -1;
Yogesh Pande 8:bdd418027540 184
Yogesh Pande 8:bdd418027540 185 if (_use_secure_connection) {
Yogesh Pande 8:bdd418027540 186 while(_listening){
Yogesh Pande 8:bdd418027540 187 rcv_size = _security_impl->read(_recv_buffer, sizeof(_recv_buffer));
Yogesh Pande 8:bdd418027540 188 if(rcv_size > 0) {
Yogesh Pande 8:bdd418027540 189 _observer.data_available(_recv_buffer, rcv_size, _address);
Yogesh Pande 8:bdd418027540 190 }
Yogesh Pande 8:bdd418027540 191 else if(rcv_size == 0){
Yogesh Pande 8:bdd418027540 192 //We are in initializing phase, so do nothing
Yogesh Pande 8:bdd418027540 193 }
Yogesh Pande 8:bdd418027540 194 else{
Yogesh Pande 8:bdd418027540 195 _listening = false;
Yogesh Pande 8:bdd418027540 196 _observer.socket_error(1);
Yogesh Pande 8:bdd418027540 197 }
Yogesh Pande 8:bdd418027540 198 memset(_recv_buffer, 0, sizeof(_recv_buffer));
geky 4:0c58f5786538 199 }
Yogesh Pande 8:bdd418027540 200 } else {
Yogesh Pande 8:bdd418027540 201 while(_listening) {
Yogesh Pande 8:bdd418027540 202 int rcv_size = _socket->recv((char*)_recv_buffer, sizeof _recv_buffer, true);
Yogesh Pande 8:bdd418027540 203 if (rcv_size == -1) {
Yogesh Pande 8:bdd418027540 204 //TODO: Define receive error code
Yogesh Pande 8:bdd418027540 205 _observer.socket_error(2);
Yogesh Pande 8:bdd418027540 206 _listening = false;
Yogesh Pande 8:bdd418027540 207 }
Yogesh Pande 8:bdd418027540 208
Yogesh Pande 8:bdd418027540 209 /* If message received.. */
Yogesh Pande 8:bdd418027540 210 if(rcv_size > 0) {
Yogesh Pande 8:bdd418027540 211 _observer.data_available(_recv_buffer,rcv_size,_address);
Yogesh Pande 8:bdd418027540 212 }
Yogesh Pande 8:bdd418027540 213 memset(_recv_buffer, 0, sizeof(_recv_buffer));
Christopher Haster 1:2dc916e504c9 214 }
Christopher Haster 1:2dc916e504c9 215 }
Christopher Haster 1:2dc916e504c9 216 }
Christopher Haster 1:2dc916e504c9 217
Christopher Haster 1:2dc916e504c9 218 int M2MConnectionHandlerPimpl::send_to_socket(const unsigned char *buf, size_t len)
Christopher Haster 1:2dc916e504c9 219 {
Yogesh Pande 8:bdd418027540 220 tr_debug("M2MConnectionHandlerPimpl::send_to_socket len - %d", len);
Yogesh Pande 8:bdd418027540 221 int size = _socket->send(buf,len);
Yogesh Pande 8:bdd418027540 222 tr_debug("M2MConnectionHandlerPimpl::send_to_socket size - %d", size);
Yogesh Pande 8:bdd418027540 223 return size;
Christopher Haster 1:2dc916e504c9 224 }
Christopher Haster 1:2dc916e504c9 225
Christopher Haster 1:2dc916e504c9 226 int M2MConnectionHandlerPimpl::receive_from_socket(unsigned char *buf, size_t len)
Christopher Haster 1:2dc916e504c9 227 {
Yogesh Pande 8:bdd418027540 228 tr_debug("M2MConnectionHandlerPimpl::receive_from_socket - blocking call");
Yogesh Pande 8:bdd418027540 229 return _socket->recv(buf, len);
Christopher Haster 1:2dc916e504c9 230 }
Christopher Haster 1:2dc916e504c9 231
Christopher Haster 1:2dc916e504c9 232 void M2MConnectionHandlerPimpl::handle_connection_error(int /*error*/)
Christopher Haster 1:2dc916e504c9 233 {
Yogesh Pande 8:bdd418027540 234 tr_debug("M2MConnectionHandlerPimpl::handle_connection_error");
Christopher Haster 1:2dc916e504c9 235 _observer.socket_error(4);
Christopher Haster 1:2dc916e504c9 236 }