Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SocketStats.cpp Source File

SocketStats.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may 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,
00012  * WITHOUT 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 
00017 #include "SocketStats.h"
00018 #include "platform/mbed_error.h"
00019 #include "platform/mbed_assert.h"
00020 #ifdef MBED_CONF_RTOS_PRESENT
00021 #include "rtos/Kernel.h"
00022 #endif
00023 
00024 #include <string.h>
00025 #include <stdlib.h>
00026 
00027 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00028 SingletonPtr<PlatformMutex>  SocketStats::_mutex;
00029 mbed_stats_socket_t SocketStats::_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
00030 uint32_t SocketStats::_size = 0;
00031 
00032 int SocketStats::get_entry_position(const Socket *const reference_id)
00033 {
00034     for (uint32_t j = 0; j < _size; j++) {
00035         if (_stats[j].reference_id == reference_id) {
00036             return j;
00037         }
00038     }
00039     return -1;
00040 }
00041 #endif
00042 
00043 size_t SocketStats::mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count)
00044 {
00045     MBED_ASSERT(stats != NULL);
00046     size_t i = 0;
00047 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00048     memset(stats, 0, count * sizeof(mbed_stats_socket_t));
00049     _mutex->lock();
00050     for (uint32_t j = 0; j < count; j++) {
00051         if (_stats[j].reference_id) {
00052             memcpy(&stats[i], &_stats[j], sizeof(mbed_stats_socket_t));
00053             i++;
00054         }
00055     }
00056     _mutex->unlock();
00057 #endif
00058     return i;
00059 }
00060 
00061 SocketStats::SocketStats()
00062 {
00063 }
00064 
00065 void SocketStats::stats_new_socket_entry(const Socket *const reference_id)
00066 {
00067 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00068     _mutex->lock();
00069     if (get_entry_position(reference_id) >= 0) {
00070         // Duplicate entry
00071         MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_INVALID_INDEX), "Duplicate socket Reference ID ", reference_id);
00072     } else if (_size < MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT) {
00073         // Add new entry
00074         _stats[_size].reference_id = (Socket *)reference_id;
00075         _size++;
00076     } else {
00077         int position = -1;
00078         uint64_t oldest_time = 0;
00079         // Determine which entry in the list shall be over-written
00080         for (uint32_t j = 0; j < MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT; j++) {
00081             if (SOCK_CLOSED == _stats[j].state) {
00082                 if ((0 == oldest_time) || (oldest_time < _stats[j].last_change_tick)) {
00083                     oldest_time = _stats[j].last_change_tick;
00084                     position = j;
00085                 }
00086             }
00087         }
00088         if (-1 == position) {
00089             MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_OUT_OF_RESOURCES), "List full with all open sockets");
00090         }
00091         memset(&_stats[position], 0, sizeof(mbed_stats_socket_t));
00092         _stats[position].reference_id = (Socket *)reference_id;
00093     }
00094     _mutex->unlock();
00095 #endif
00096     return;
00097 }
00098 
00099 void SocketStats::stats_update_socket_state(const Socket *const reference_id, socket_state state)
00100 {
00101 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00102     _mutex->lock();
00103     int position = get_entry_position(reference_id);
00104     if (position >= 0) {
00105         _stats[position].state = state;
00106 #ifdef MBED_CONF_RTOS_PRESENT
00107         _stats[position].last_change_tick = rtos::Kernel::get_ms_count();
00108 #endif
00109     }
00110     _mutex->unlock();
00111 #endif
00112 }
00113 
00114 void SocketStats::stats_update_peer(const Socket *const reference_id, const SocketAddress &peer)
00115 {
00116 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00117     _mutex->lock();
00118     int position = get_entry_position(reference_id);
00119     if ((position >= 0) && (!_stats[position].peer)) {
00120         _stats[position].peer = peer;
00121     }
00122     _mutex->unlock();
00123 #endif
00124 }
00125 
00126 void SocketStats::stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto)
00127 {
00128 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00129     _mutex->lock();
00130     int position = get_entry_position(reference_id);
00131     if (position >= 0) {
00132         _stats[position].proto = proto;
00133     }
00134     _mutex->unlock();
00135 #endif
00136 }
00137 
00138 void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes)
00139 {
00140 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00141     _mutex->lock();
00142     int position = get_entry_position(reference_id);
00143     if ((position >= 0) && ((int32_t)sent_bytes > 0)) {
00144         _stats[position].sent_bytes += sent_bytes;
00145     }
00146     _mutex->unlock();
00147 #endif
00148 }
00149 
00150 void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes)
00151 {
00152 #if MBED_CONF_NSAPI_SOCKET_STATS_ENABLED
00153     _mutex->lock();
00154     int position = get_entry_position(reference_id);
00155     if ((position >= 0) && ((int32_t)recv_bytes > 0)) {
00156         _stats[position].recv_bytes += recv_bytes;
00157     }
00158     _mutex->unlock();
00159 #endif
00160 }