dhgdh
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
m2mconnectionhandlerpimpl.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed-client-classic/m2mconnectionhandlerpimpl.h" 00017 #include "mbed-client/m2mconnectionobserver.h" 00018 #include "mbed-client/m2mconstants.h" 00019 #include "mbed-client/m2msecurity.h" 00020 #include "mbed-client/m2mconnectionhandler.h" 00021 00022 #include "NetworkInterface.h" 00023 #include "UDPSocket.h" 00024 #include "TCPSocket.h" 00025 00026 #include "eventOS_event.h" 00027 #include "eventOS_scheduler.h" 00028 00029 #include "mbed-trace/mbed_trace.h" 00030 #include "mbed.h" 00031 00032 #define TRACE_GROUP "mClt" 00033 00034 #ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE 00035 #define MBED_CLIENT_EVENT_LOOP_SIZE MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE 00036 #else 00037 #define MBED_CLIENT_EVENT_LOOP_SIZE 1024 00038 #endif 00039 00040 int8_t M2MConnectionHandlerPimpl::_tasklet_id = -1; 00041 00042 static MemoryPool<M2MConnectionHandlerPimpl::TaskIdentifier, MBED_CLIENT_EVENT_LOOP_SIZE/64> memory_pool; 00043 00044 extern "C" void connection_tasklet_event_handler(arm_event_s *event) 00045 { 00046 tr_debug("M2MConnectionHandlerPimpl::connection_tasklet_event_handler"); 00047 M2MConnectionHandlerPimpl::TaskIdentifier *task_id = (M2MConnectionHandlerPimpl::TaskIdentifier*)event->data_ptr; 00048 M2MConnectionHandlerPimpl* pimpl = (M2MConnectionHandlerPimpl*)task_id->pimpl; 00049 if(pimpl) { 00050 eventOS_scheduler_set_active_tasklet(pimpl->connection_tasklet_handler()); 00051 } 00052 switch (event->event_type) { 00053 case M2MConnectionHandlerPimpl::ESocketIdle: 00054 tr_debug("Connection Tasklet Generated"); 00055 break; 00056 case M2MConnectionHandlerPimpl::ESocketReadytoRead: 00057 tr_debug("connection_tasklet_event_handler - ESocketReadytoRead"); 00058 if(pimpl) { 00059 if(pimpl->is_handshake_ongoing()) { 00060 pimpl->receive_handshake_handler(); 00061 } else { 00062 pimpl->receive_handler(); 00063 } 00064 } 00065 break; 00066 case M2MConnectionHandlerPimpl::ESocketDnsHandler: 00067 tr_debug("connection_tasklet_event_handler - ESocketDnsHandler"); 00068 if(pimpl) { 00069 pimpl->dns_handler(); 00070 } 00071 break; 00072 case M2MConnectionHandlerPimpl::ESocketSend: 00073 tr_debug("connection_tasklet_event_handler - ESocketSend"); 00074 if(pimpl) { 00075 pimpl->send_socket_data((uint8_t*)task_id->data_ptr,(uint16_t)event->event_data); 00076 if (task_id->data_ptr) { 00077 free(task_id->data_ptr); 00078 } 00079 } 00080 break; 00081 default: 00082 break; 00083 } 00084 if (task_id) { 00085 memory_pool.free(task_id); 00086 } 00087 } 00088 00089 M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl(M2MConnectionHandler* base, M2MConnectionObserver &observer, 00090 M2MConnectionSecurity* sec, 00091 M2MInterface::BindingMode mode, 00092 M2MInterface::NetworkStack stack) 00093 :_base(base), 00094 _observer(observer), 00095 _security_impl(sec), 00096 _use_secure_connection(false), 00097 _binding_mode(mode), 00098 _network_stack(stack), 00099 _socket(0), 00100 _is_handshaking(false), 00101 _listening(true), 00102 _server_type(M2MConnectionObserver::LWM2MServer), 00103 _server_port(0), 00104 _listen_port(0), 00105 _running(false), 00106 _net_iface(0), 00107 _socket_address(0) 00108 { 00109 memset(&_address_buffer, 0, sizeof _address_buffer); 00110 memset(&_address, 0, sizeof _address); 00111 _address._address = _address_buffer; 00112 00113 if (_network_stack != M2MInterface::LwIP_IPv4) { 00114 tr_error("ConnectionHandler: Unsupported network stack, only IPv4 is currently supported"); 00115 } 00116 _running = true; 00117 tr_debug("M2MConnectionHandlerPimpl::M2MConnectionHandlerPimpl() - Initializing thread"); 00118 eventOS_scheduler_mutex_wait(); 00119 if (M2MConnectionHandlerPimpl::_tasklet_id == -1) { 00120 M2MConnectionHandlerPimpl::_tasklet_id = eventOS_event_handler_create(&connection_tasklet_event_handler, ESocketIdle); 00121 } 00122 eventOS_scheduler_mutex_release(); 00123 } 00124 00125 M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl() 00126 { 00127 tr_debug("M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl()"); 00128 if(_socket_address) { 00129 delete _socket_address; 00130 _socket_address = NULL; 00131 } 00132 if (_socket) { 00133 delete _socket; 00134 _socket = 0; 00135 } 00136 _net_iface = 0; 00137 delete _security_impl; 00138 tr_debug("M2MConnectionHandlerPimpl::~M2MConnectionHandlerPimpl() - OUT"); 00139 } 00140 00141 bool M2MConnectionHandlerPimpl::bind_connection(const uint16_t listen_port) 00142 { 00143 _listen_port = listen_port; 00144 return true; 00145 } 00146 00147 bool M2MConnectionHandlerPimpl::resolve_server_address(const String& server_address, 00148 const uint16_t server_port, 00149 M2MConnectionObserver::ServerType server_type, 00150 const M2MSecurity* security) 00151 { 00152 tr_debug("M2MConnectionHandlerPimpl::resolve_server_address()"); 00153 if (!_net_iface) { 00154 return false; 00155 } 00156 _security = security; 00157 _server_port = server_port; 00158 _server_type = server_type; 00159 _server_address = server_address; 00160 TaskIdentifier* task = memory_pool.alloc(); 00161 if (!task) { 00162 return false; 00163 } 00164 task->pimpl = this; 00165 00166 arm_event_s event; 00167 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id; 00168 event.sender = 0; 00169 event.event_type = ESocketDnsHandler; 00170 event.data_ptr = task; 00171 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; 00172 return eventOS_event_send(&event) == 0 ? true : false; 00173 } 00174 00175 void M2MConnectionHandlerPimpl::dns_handler() 00176 { 00177 tr_debug("M2MConnectionHandlerPimpl::dns_handler()"); 00178 if(_socket_address) { 00179 delete _socket_address; 00180 _socket_address = NULL; 00181 } 00182 _socket_address = new SocketAddress(_net_iface,_server_address.c_str(), _server_port); 00183 if(*_socket_address) { 00184 _address._address = (void*)_socket_address->get_ip_address(); 00185 tr_debug("IP Address %s",_socket_address->get_ip_address()); 00186 tr_debug("Port %d",_socket_address->get_port()); 00187 _address._length = strlen((char*)_address._address); 00188 _address._port = _socket_address->get_port(); 00189 _address._stack = _network_stack; 00190 } else { 00191 _observer.socket_error(M2MConnectionHandler::DNS_RESOLVING_ERROR, true); 00192 close_socket(); 00193 return; 00194 } 00195 00196 close_socket(); 00197 init_socket(); 00198 00199 if(is_tcp_connection()) { 00200 tr_debug("M2MConnectionHandlerPimpl::resolve_server_address - Using TCP"); 00201 if (((TCPSocket*)_socket)->connect(*_socket_address) < 0) { 00202 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT); 00203 return; 00204 } 00205 } 00206 00207 _running = true; 00208 00209 if (_security) { 00210 if (_security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Certificate || 00211 _security->resource_value_int(M2MSecurity::SecurityMode) == M2MSecurity::Psk) { 00212 00213 if( _security_impl != NULL ){ 00214 _security_impl->reset(); 00215 if (_security_impl->init(_security) == 0) { 00216 _is_handshaking = true; 00217 tr_debug("M2MConnectionHandlerPimpl::resolve_server_address - connect DTLS"); 00218 if(_security_impl->start_connecting_non_blocking(_base) < 0 ){ 00219 tr_debug("M2MConnectionHandlerPimpl::dns_handler - handshake failed"); 00220 _is_handshaking = false; 00221 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR); 00222 close_socket(); 00223 return; 00224 } 00225 } else { 00226 tr_error("M2MConnectionHandlerPimpl::resolve_server_address - init failed"); 00227 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, false); 00228 close_socket(); 00229 return; 00230 } 00231 } else { 00232 tr_error("M2MConnectionHandlerPimpl::dns_handler - sec is null"); 00233 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, false); 00234 close_socket(); 00235 return; 00236 } 00237 } 00238 } 00239 if(!_is_handshaking) { 00240 enable_keepalive(); 00241 _observer.address_ready(_address, 00242 _server_type, 00243 _address._port); 00244 } 00245 } 00246 00247 void M2MConnectionHandlerPimpl::send_handler() 00248 { 00249 tr_debug("M2MConnectionHandlerPimpl::send_handler()"); 00250 _observer.data_sent(); 00251 } 00252 00253 bool M2MConnectionHandlerPimpl::send_data(uint8_t *data, 00254 uint16_t data_len, 00255 sn_nsdl_addr_s *address) 00256 { 00257 tr_debug("M2MConnectionHandlerPimpl::send_data()"); 00258 if (address == NULL || data == NULL) { 00259 return false; 00260 } 00261 00262 uint8_t *buffer = (uint8_t*)malloc(data_len); 00263 if(!buffer) { 00264 return false; 00265 } 00266 00267 TaskIdentifier* task = memory_pool.alloc(); 00268 if (!task) { 00269 free(buffer); 00270 return false; 00271 } 00272 task->pimpl = this; 00273 memcpy(buffer, data, data_len); 00274 task->data_ptr = buffer; 00275 arm_event_s event; 00276 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id; 00277 event.sender = 0; 00278 event.event_type = ESocketSend; 00279 event.data_ptr = task; 00280 event.event_data = data_len; 00281 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; 00282 00283 return eventOS_event_send(&event) == 0 ? true : false; 00284 } 00285 00286 void M2MConnectionHandlerPimpl::send_socket_data(uint8_t *data, 00287 uint16_t data_len) 00288 { 00289 bool success = false; 00290 if( _use_secure_connection ){ 00291 if( _security_impl->send_message(data, data_len) > 0){ 00292 success = true; 00293 } 00294 } else { 00295 int32_t ret = -1; 00296 if(is_tcp_connection()){ 00297 //We need to "shim" the length in front 00298 uint16_t d_len = data_len+4; 00299 uint8_t* d = (uint8_t*)malloc(data_len+4); 00300 00301 d[0] = (data_len >> 24 )& 0xff; 00302 d[1] = (data_len >> 16 )& 0xff; 00303 d[2] = (data_len >> 8 )& 0xff; 00304 d[3] = data_len & 0xff; 00305 memmove(d+4, data, data_len); 00306 ret = ((TCPSocket*)_socket)->send(d,d_len); 00307 free(d); 00308 }else { 00309 ret = ((UDPSocket*)_socket)->sendto(*_socket_address,data, data_len); 00310 } 00311 if (ret > 0) { 00312 success = true; 00313 } 00314 } 00315 00316 if (!success) { 00317 _observer.socket_error(M2MConnectionHandler::SOCKET_SEND_ERROR, true); 00318 close_socket(); 00319 } 00320 } 00321 00322 int8_t M2MConnectionHandlerPimpl::connection_tasklet_handler() 00323 { 00324 return M2MConnectionHandlerPimpl::_tasklet_id; 00325 } 00326 00327 void M2MConnectionHandlerPimpl::socket_event() 00328 { 00329 TaskIdentifier* task = memory_pool.alloc(); 00330 if (!task) { 00331 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); 00332 return; 00333 } 00334 task->pimpl = this; 00335 00336 arm_event_s event; 00337 event.receiver = M2MConnectionHandlerPimpl::_tasklet_id; 00338 event.sender = 0; 00339 event.event_type = ESocketReadytoRead; 00340 event.data_ptr = task; 00341 event.priority = ARM_LIB_HIGH_PRIORITY_EVENT; 00342 int8_t error = eventOS_event_send(&event); 00343 if(error != 0) { 00344 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); 00345 } 00346 } 00347 00348 bool M2MConnectionHandlerPimpl::start_listening_for_data() 00349 { 00350 tr_debug("M2MConnectionHandlerPimpl::start_listening_for_data()"); 00351 // Boolean return required for other platforms, 00352 // not needed in mbed OS Socket. 00353 _listening = true; 00354 _running = true; 00355 return _listening; 00356 } 00357 00358 void M2MConnectionHandlerPimpl::stop_listening() 00359 { 00360 tr_debug("M2MConnectionHandlerPimpl::stop_listening()"); 00361 _listening = false; 00362 if(_security_impl) { 00363 _security_impl->reset(); 00364 } 00365 } 00366 00367 int M2MConnectionHandlerPimpl::send_to_socket(const unsigned char *buf, size_t len) 00368 { 00369 tr_debug("M2MConnectionHandlerPimpl::send_to_socket len - %d", len); 00370 int size = -1; 00371 if(is_tcp_connection()) { 00372 size = ((TCPSocket*)_socket)->send(buf,len); 00373 } else { 00374 size = ((UDPSocket*)_socket)->sendto(*_socket_address,buf,len); 00375 } 00376 tr_debug("M2MConnectionHandlerPimpl::send_to_socket size - %d", size); 00377 if(NSAPI_ERROR_WOULD_BLOCK == size){ 00378 if(_is_handshaking) { 00379 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_WRITE; 00380 } else { 00381 return len; 00382 } 00383 }else if(size < 0){ 00384 return -1; 00385 }else{ 00386 if(!_is_handshaking) { 00387 _observer.data_sent(); 00388 } 00389 return size; 00390 } 00391 } 00392 00393 int M2MConnectionHandlerPimpl::receive_from_socket(unsigned char *buf, size_t len) 00394 { 00395 tr_debug("M2MConnectionHandlerPimpl::receive_from_socket"); 00396 int recv = -1; 00397 if(is_tcp_connection()) { 00398 recv = ((TCPSocket*)_socket)->recv(buf, len); 00399 } else { 00400 recv = ((UDPSocket*)_socket)->recvfrom(NULL,buf, len); 00401 } 00402 tr_debug("M2MConnectionHandlerPimpl::receive_from_socket recv size %d", recv); 00403 if(NSAPI_ERROR_WOULD_BLOCK == recv){ 00404 return M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ; 00405 }else if(recv < 0){ 00406 return -1; 00407 }else{ 00408 return recv; 00409 } 00410 } 00411 00412 void M2MConnectionHandlerPimpl::handle_connection_error(int error) 00413 { 00414 tr_debug("M2MConnectionHandlerPimpl::handle_connection_error"); 00415 _observer.socket_error(error); 00416 } 00417 00418 void M2MConnectionHandlerPimpl::set_platform_network_handler(void *handler) 00419 { 00420 tr_debug("M2MConnectionHandlerPimpl::set_platform_network_handler"); 00421 _net_iface = (NetworkInterface*)handler; 00422 } 00423 00424 void M2MConnectionHandlerPimpl::receive_handshake_handler() 00425 { 00426 tr_debug("M2MConnectionHandlerPimpl::receive_handshake_handler()"); 00427 if( _is_handshaking ){ 00428 int ret = _security_impl->continue_connecting(); 00429 tr_debug("M2MConnectionHandlerPimpl::receive_handshake_handler() - ret %d", ret); 00430 if( ret == M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ ){ //We wait for next readable event 00431 tr_debug("M2MConnectionHandlerPimpl::receive_handshake_handler() - We wait for next readable event"); 00432 return; 00433 } else if( ret == 0 ){ 00434 _is_handshaking = false; 00435 _use_secure_connection = true; 00436 enable_keepalive(); 00437 _observer.address_ready(_address, 00438 _server_type, 00439 _server_port); 00440 }else if( ret < 0 ){ 00441 _is_handshaking = false; 00442 _observer.socket_error(M2MConnectionHandler::SSL_CONNECTION_ERROR, true); 00443 close_socket(); 00444 } 00445 } 00446 } 00447 00448 bool M2MConnectionHandlerPimpl::is_handshake_ongoing() 00449 { 00450 return _is_handshaking; 00451 } 00452 00453 void M2MConnectionHandlerPimpl::receive_handler() 00454 { 00455 tr_debug("M2MConnectionHandlerPimpl::receive_handler()"); 00456 memset(_recv_buffer, 0, 1024); 00457 size_t receive_length = sizeof(_recv_buffer); 00458 00459 if(_listening) { 00460 if( _use_secure_connection ){ 00461 int rcv_size = _security_impl->read(_recv_buffer, receive_length); 00462 00463 if(rcv_size >= 0){ 00464 _observer.data_available((uint8_t*)_recv_buffer, 00465 rcv_size, _address); 00466 } else if (M2MConnectionHandler::CONNECTION_ERROR_WANTS_READ != rcv_size) { 00467 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); 00468 close_socket(); 00469 return; 00470 } 00471 }else{ 00472 int recv = -1; 00473 if(is_tcp_connection()){ 00474 recv = ((TCPSocket*)_socket)->recv(_recv_buffer, receive_length); 00475 00476 }else{ 00477 recv = ((UDPSocket*)_socket)->recvfrom(NULL,_recv_buffer, receive_length); 00478 } 00479 if (recv > 0) { 00480 // Send data for processing. 00481 if(is_tcp_connection()){ 00482 //We need to "shim" out the length from the front 00483 if( receive_length > 4 ){ 00484 uint64_t len = (_recv_buffer[0] << 24 & 0xFF000000) + (_recv_buffer[1] << 16 & 0xFF0000); 00485 len += (_recv_buffer[2] << 8 & 0xFF00) + (_recv_buffer[3] & 0xFF); 00486 if(len > 0) { 00487 uint8_t* buf = (uint8_t*)malloc(len); 00488 if(buf) { 00489 memmove(buf, _recv_buffer+4, len); 00490 // Observer for TCP plain mode 00491 _observer.data_available(buf,len,_address); 00492 free(buf); 00493 } 00494 } 00495 }else{ 00496 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); 00497 close_socket(); 00498 } 00499 } else { // Observer for UDP plain mode 00500 tr_debug("M2MConnectionHandlerPimpl::receive_handler - data received %d", recv); 00501 _observer.data_available((uint8_t*)_recv_buffer, 00502 recv, _address); 00503 } 00504 } else if(NSAPI_ERROR_WOULD_BLOCK != recv) { 00505 // Socket error in receiving 00506 _observer.socket_error(M2MConnectionHandler::SOCKET_READ_ERROR, true); 00507 close_socket(); 00508 } 00509 } 00510 } 00511 } 00512 00513 void M2MConnectionHandlerPimpl::claim_mutex() 00514 { 00515 eventOS_scheduler_mutex_wait(); 00516 } 00517 00518 void M2MConnectionHandlerPimpl::release_mutex() 00519 { 00520 eventOS_scheduler_mutex_release(); 00521 } 00522 00523 void M2MConnectionHandlerPimpl::init_socket() 00524 { 00525 tr_debug("M2MConnectionHandlerPimpl::init_socket - IN"); 00526 _is_handshaking = false; 00527 _running = true; 00528 00529 if(is_tcp_connection()) { 00530 tr_debug("M2MConnectionHandlerPimpl::init_socket - Using TCP"); 00531 _socket = new TCPSocket(_net_iface); 00532 if(_socket) { 00533 _socket->attach(this, &M2MConnectionHandlerPimpl::socket_event); 00534 } else { 00535 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT); 00536 return; 00537 } 00538 } else { 00539 tr_debug("M2MConnectionHandlerPimpl::init_socket - Using UDP - port %d", _listen_port); 00540 _socket = new UDPSocket(_net_iface); 00541 if(_socket) { 00542 _socket->bind(_listen_port); 00543 _socket->attach(this, &M2MConnectionHandlerPimpl::socket_event); 00544 } else { 00545 _observer.socket_error(M2MConnectionHandler::SOCKET_ABORT); 00546 return; 00547 } 00548 } 00549 _socket->set_blocking(false); 00550 tr_debug("M2MConnectionHandlerPimpl::init_socket - OUT"); 00551 } 00552 00553 bool M2MConnectionHandlerPimpl::is_tcp_connection() 00554 { 00555 return _binding_mode == M2MInterface::TCP || 00556 _binding_mode == M2MInterface::TCP_QUEUE ? true : false; 00557 } 00558 00559 void M2MConnectionHandlerPimpl::close_socket() 00560 { 00561 tr_debug("M2MConnectionHandlerPimpl::close_socket() - IN"); 00562 if(_socket) { 00563 _running = false; 00564 _socket->close(); 00565 delete _socket; 00566 _socket = NULL; 00567 } 00568 tr_debug("M2MConnectionHandlerPimpl::close_socket() - OUT"); 00569 } 00570 00571 void M2MConnectionHandlerPimpl::enable_keepalive() 00572 { 00573 #if MBED_CLIENT_TCP_KEEPALIVE_TIME 00574 if(is_tcp_connection()) { 00575 int keepalive = MBED_CLIENT_TCP_KEEPALIVE_TIME; 00576 int enable = 1; 00577 tr_debug("M2MConnectionHandlerPimpl::resolve_hostname - keepalive %d s\n", keepalive); 00578 if(_socket->setsockopt(1,NSAPI_KEEPALIVE,&enable,sizeof(enable)) != 0) { 00579 tr_error("M2MConnectionHandlerPimpl::enable_keepalive - setsockopt fail to Set Keepalive\n"); 00580 } 00581 if(_socket->setsockopt(1,NSAPI_KEEPINTVL,&keepalive,sizeof(keepalive)) != 0) { 00582 tr_error("M2MConnectionHandlerPimpl::enable_keepalive - setsockopt fail to Set Keepalive TimeInterval\n"); 00583 } 00584 if(_socket->setsockopt(1,NSAPI_KEEPIDLE,&keepalive,sizeof(keepalive)) != 0) { 00585 tr_error("M2MConnectionHandlerPimpl::enable_keepalive - setsockopt fail to Set Keepalive Time\n"); 00586 } 00587 } 00588 #endif 00589 }
Generated on Tue Jul 12 2022 11:01:51 by
1.7.2
