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-2016 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
edamame22 0:29983394c6b6 17 #include <assert.h>
edamame22 0:29983394c6b6 18 #include <time.h>
edamame22 0:29983394c6b6 19
edamame22 0:29983394c6b6 20 #include "mbed-client-classic/m2mtimerpimpl.h"
edamame22 0:29983394c6b6 21 #include "mbed-client/m2mtimerobserver.h"
edamame22 0:29983394c6b6 22 #include "mbed-client/m2mvector.h"
edamame22 0:29983394c6b6 23
edamame22 0:29983394c6b6 24 #include "eventOS_event.h"
edamame22 0:29983394c6b6 25 #include "eventOS_event_timer.h"
edamame22 0:29983394c6b6 26 #include "eventOS_scheduler.h"
edamame22 0:29983394c6b6 27 #include "ns_hal_init.h"
edamame22 0:29983394c6b6 28
edamame22 0:29983394c6b6 29 #define MBED_CLIENT_TIMER_TASKLET_INIT_EVENT 0 // Tasklet init occurs always when generating a tasklet
edamame22 0:29983394c6b6 30 #define MBED_CLIENT_TIMER_EVENT 10
edamame22 0:29983394c6b6 31
edamame22 0:29983394c6b6 32 #ifdef MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
edamame22 0:29983394c6b6 33 #define MBED_CLIENT_EVENT_LOOP_SIZE MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE
edamame22 0:29983394c6b6 34 #else
edamame22 0:29983394c6b6 35 #define MBED_CLIENT_EVENT_LOOP_SIZE 1024
edamame22 0:29983394c6b6 36 #endif
edamame22 0:29983394c6b6 37
edamame22 0:29983394c6b6 38 int8_t M2MTimerPimpl::_tasklet_id = -1;
edamame22 0:29983394c6b6 39
edamame22 0:29983394c6b6 40 int8_t M2MTimerPimpl::_next_timer_id = 1;
edamame22 0:29983394c6b6 41
edamame22 0:29983394c6b6 42 static m2m::Vector<M2MTimerPimpl*> timer_impl_list;
edamame22 0:29983394c6b6 43
edamame22 0:29983394c6b6 44 extern "C" void tasklet_func(arm_event_s *event)
edamame22 0:29983394c6b6 45 {
edamame22 0:29983394c6b6 46 // skip the init event as there will be a timer event after
edamame22 0:29983394c6b6 47 if (event->event_type == MBED_CLIENT_TIMER_EVENT) {
edamame22 0:29983394c6b6 48 bool timer_found = false;
edamame22 0:29983394c6b6 49 eventOS_scheduler_mutex_wait();
edamame22 0:29983394c6b6 50 int timer_count = timer_impl_list.size();
edamame22 0:29983394c6b6 51 for (int index = 0; index < timer_count; index++) {
edamame22 0:29983394c6b6 52 M2MTimerPimpl* timer = timer_impl_list[index];
edamame22 0:29983394c6b6 53 if (timer->get_timer_id() == event->event_id) {
edamame22 0:29983394c6b6 54 eventOS_scheduler_mutex_release();
edamame22 0:29983394c6b6 55 timer_found = true;
edamame22 0:29983394c6b6 56 if (timer->get_still_left_time() > 0) {
edamame22 0:29983394c6b6 57 timer->start_still_left_timer();
edamame22 0:29983394c6b6 58 }else {
edamame22 0:29983394c6b6 59 timer->timer_expired();
edamame22 0:29983394c6b6 60 }
edamame22 0:29983394c6b6 61 break;
edamame22 0:29983394c6b6 62 }
edamame22 0:29983394c6b6 63 }
edamame22 0:29983394c6b6 64 if(!timer_found) {
edamame22 0:29983394c6b6 65 eventOS_scheduler_mutex_release();
edamame22 0:29983394c6b6 66 }
edamame22 0:29983394c6b6 67 }
edamame22 0:29983394c6b6 68 }
edamame22 0:29983394c6b6 69
edamame22 0:29983394c6b6 70 M2MTimerPimpl::M2MTimerPimpl(M2MTimerObserver& observer)
edamame22 0:29983394c6b6 71 : _observer(observer),
edamame22 0:29983394c6b6 72 _single_shot(true),
edamame22 0:29983394c6b6 73 _interval(0),
edamame22 0:29983394c6b6 74 _type(M2MTimerObserver::Notdefined),
edamame22 0:29983394c6b6 75 _intermediate_interval(0),
edamame22 0:29983394c6b6 76 _total_interval(0),
edamame22 0:29983394c6b6 77 _still_left(0),
edamame22 0:29983394c6b6 78 _status(0),
edamame22 0:29983394c6b6 79 _dtls_type(false)
edamame22 0:29983394c6b6 80 {
edamame22 0:29983394c6b6 81 ns_hal_init(NULL, MBED_CLIENT_EVENT_LOOP_SIZE, NULL, NULL);
edamame22 0:29983394c6b6 82 eventOS_scheduler_mutex_wait();
edamame22 0:29983394c6b6 83 if (_tasklet_id < 0) {
edamame22 0:29983394c6b6 84 _tasklet_id = eventOS_event_handler_create(tasklet_func, MBED_CLIENT_TIMER_TASKLET_INIT_EVENT);
edamame22 0:29983394c6b6 85 assert(_tasklet_id >= 0);
edamame22 0:29983394c6b6 86 }
edamame22 0:29983394c6b6 87
edamame22 0:29983394c6b6 88 // XXX: this wraps over quite soon
edamame22 0:29983394c6b6 89 _timer_id = M2MTimerPimpl::_next_timer_id++;
edamame22 0:29983394c6b6 90 timer_impl_list.push_back(this);
edamame22 0:29983394c6b6 91 eventOS_scheduler_mutex_release();
edamame22 0:29983394c6b6 92 }
edamame22 0:29983394c6b6 93
edamame22 0:29983394c6b6 94 M2MTimerPimpl::~M2MTimerPimpl()
edamame22 0:29983394c6b6 95 {
edamame22 0:29983394c6b6 96 // cancel the timer request, if any is pending
edamame22 0:29983394c6b6 97 cancel();
edamame22 0:29983394c6b6 98
edamame22 0:29983394c6b6 99 // there is no turning back, event os does not have eventOS_event_handler_delete() or similar,
edamame22 0:29983394c6b6 100 // so the tasklet is lost forever. Same goes with timer_impl_list, which leaks now memory.
edamame22 0:29983394c6b6 101
edamame22 0:29983394c6b6 102 // remove the timer from object list
edamame22 0:29983394c6b6 103 eventOS_scheduler_mutex_wait();
edamame22 0:29983394c6b6 104 int timer_count = timer_impl_list.size();
edamame22 0:29983394c6b6 105 for (int index = 0; index < timer_count; index++) {
edamame22 0:29983394c6b6 106 const M2MTimerPimpl* timer = timer_impl_list[index];
edamame22 0:29983394c6b6 107 if (timer->get_timer_id() == _timer_id) {
edamame22 0:29983394c6b6 108 timer_impl_list.erase(index);
edamame22 0:29983394c6b6 109 break;
edamame22 0:29983394c6b6 110 }
edamame22 0:29983394c6b6 111 }
edamame22 0:29983394c6b6 112 eventOS_scheduler_mutex_release();
edamame22 0:29983394c6b6 113 }
edamame22 0:29983394c6b6 114
edamame22 0:29983394c6b6 115 void M2MTimerPimpl::start_timer( uint64_t interval,
edamame22 0:29983394c6b6 116 M2MTimerObserver::Type type,
edamame22 0:29983394c6b6 117 bool single_shot)
edamame22 0:29983394c6b6 118 {
edamame22 0:29983394c6b6 119 _dtls_type = false;
edamame22 0:29983394c6b6 120 _intermediate_interval = 0;
edamame22 0:29983394c6b6 121 _total_interval = 0;
edamame22 0:29983394c6b6 122 _status = 0;
edamame22 0:29983394c6b6 123 _single_shot = single_shot;
edamame22 0:29983394c6b6 124 _interval = interval;
edamame22 0:29983394c6b6 125 _type = type;
edamame22 0:29983394c6b6 126 _still_left = 0;
edamame22 0:29983394c6b6 127 start();
edamame22 0:29983394c6b6 128 }
edamame22 0:29983394c6b6 129
edamame22 0:29983394c6b6 130 void M2MTimerPimpl::start_dtls_timer(uint64_t intermediate_interval, uint64_t total_interval, M2MTimerObserver::Type type)
edamame22 0:29983394c6b6 131 {
edamame22 0:29983394c6b6 132 _dtls_type = true;
edamame22 0:29983394c6b6 133 _intermediate_interval = intermediate_interval;
edamame22 0:29983394c6b6 134 _total_interval = total_interval;
edamame22 0:29983394c6b6 135 _interval = _intermediate_interval;
edamame22 0:29983394c6b6 136 _status = 0;
edamame22 0:29983394c6b6 137 _single_shot = false;
edamame22 0:29983394c6b6 138 _type = type;
edamame22 0:29983394c6b6 139 start();
edamame22 0:29983394c6b6 140 }
edamame22 0:29983394c6b6 141
edamame22 0:29983394c6b6 142 void M2MTimerPimpl::start()
edamame22 0:29983394c6b6 143 {
edamame22 0:29983394c6b6 144 int status;
edamame22 0:29983394c6b6 145 if(_interval > INT32_MAX) {
edamame22 0:29983394c6b6 146 _still_left = _interval - INT32_MAX;
edamame22 0:29983394c6b6 147 status = eventOS_event_timer_request(_timer_id, MBED_CLIENT_TIMER_EVENT,
edamame22 0:29983394c6b6 148 M2MTimerPimpl::_tasklet_id,
edamame22 0:29983394c6b6 149 INT32_MAX);
edamame22 0:29983394c6b6 150 }
edamame22 0:29983394c6b6 151 else {
edamame22 0:29983394c6b6 152 status = eventOS_event_timer_request(_timer_id, MBED_CLIENT_TIMER_EVENT,
edamame22 0:29983394c6b6 153 M2MTimerPimpl::_tasklet_id,
edamame22 0:29983394c6b6 154 _interval);
edamame22 0:29983394c6b6 155 }
edamame22 0:29983394c6b6 156 assert(status == 0);
edamame22 0:29983394c6b6 157 }
edamame22 0:29983394c6b6 158
edamame22 0:29983394c6b6 159 void M2MTimerPimpl::cancel()
edamame22 0:29983394c6b6 160 {
edamame22 0:29983394c6b6 161 eventOS_event_timer_cancel(_timer_id, M2MTimerPimpl::_tasklet_id);
edamame22 0:29983394c6b6 162 }
edamame22 0:29983394c6b6 163
edamame22 0:29983394c6b6 164 void M2MTimerPimpl::stop_timer()
edamame22 0:29983394c6b6 165 {
edamame22 0:29983394c6b6 166 _interval = 0;
edamame22 0:29983394c6b6 167 _single_shot = true;
edamame22 0:29983394c6b6 168 _still_left = 0;
edamame22 0:29983394c6b6 169 cancel();
edamame22 0:29983394c6b6 170 }
edamame22 0:29983394c6b6 171
edamame22 0:29983394c6b6 172 void M2MTimerPimpl::timer_expired()
edamame22 0:29983394c6b6 173 {
edamame22 0:29983394c6b6 174 _status++;
edamame22 0:29983394c6b6 175 _observer.timer_expired(_type);
edamame22 0:29983394c6b6 176
edamame22 0:29983394c6b6 177 if ((!_dtls_type) && (!_single_shot)) {
edamame22 0:29983394c6b6 178 // start next round of periodic timer
edamame22 0:29983394c6b6 179 start();
edamame22 0:29983394c6b6 180 } else if ((_dtls_type) && (!is_total_interval_passed())) {
edamame22 0:29983394c6b6 181 // if only the intermediate time has passed, we need still wait up to total time
edamame22 0:29983394c6b6 182 _interval = _total_interval - _intermediate_interval;
edamame22 0:29983394c6b6 183 start();
edamame22 0:29983394c6b6 184 }
edamame22 0:29983394c6b6 185 }
edamame22 0:29983394c6b6 186
edamame22 0:29983394c6b6 187 bool M2MTimerPimpl::is_intermediate_interval_passed()
edamame22 0:29983394c6b6 188 {
edamame22 0:29983394c6b6 189 if (_status > 0) {
edamame22 0:29983394c6b6 190 return true;
edamame22 0:29983394c6b6 191 }
edamame22 0:29983394c6b6 192 return false;
edamame22 0:29983394c6b6 193 }
edamame22 0:29983394c6b6 194
edamame22 0:29983394c6b6 195 bool M2MTimerPimpl::is_total_interval_passed()
edamame22 0:29983394c6b6 196 {
edamame22 0:29983394c6b6 197 if (_status > 1) {
edamame22 0:29983394c6b6 198 return true;
edamame22 0:29983394c6b6 199 }
edamame22 0:29983394c6b6 200 return false;
edamame22 0:29983394c6b6 201 }
edamame22 0:29983394c6b6 202
edamame22 0:29983394c6b6 203 uint64_t M2MTimerPimpl::get_still_left_time() const
edamame22 0:29983394c6b6 204 {
edamame22 0:29983394c6b6 205 return _still_left;
edamame22 0:29983394c6b6 206 }
edamame22 0:29983394c6b6 207
edamame22 0:29983394c6b6 208 void M2MTimerPimpl::start_still_left_timer()
edamame22 0:29983394c6b6 209 {
edamame22 0:29983394c6b6 210 if (_still_left > 0) {
edamame22 0:29983394c6b6 211 int status;
edamame22 0:29983394c6b6 212 if( _still_left > INT32_MAX) {
edamame22 0:29983394c6b6 213 _still_left = _still_left - INT32_MAX;
edamame22 0:29983394c6b6 214 status = eventOS_event_timer_request(_timer_id, MBED_CLIENT_TIMER_EVENT,
edamame22 0:29983394c6b6 215 M2MTimerPimpl::_tasklet_id,
edamame22 0:29983394c6b6 216 INT32_MAX);
edamame22 0:29983394c6b6 217 }
edamame22 0:29983394c6b6 218 else {
edamame22 0:29983394c6b6 219 status = eventOS_event_timer_request(_timer_id, MBED_CLIENT_TIMER_EVENT,
edamame22 0:29983394c6b6 220 M2MTimerPimpl::_tasklet_id,
edamame22 0:29983394c6b6 221 _still_left);
edamame22 0:29983394c6b6 222 _still_left = 0;
edamame22 0:29983394c6b6 223 }
edamame22 0:29983394c6b6 224 assert(status == 0);
edamame22 0:29983394c6b6 225 } else {
edamame22 0:29983394c6b6 226 _observer.timer_expired(_type);
edamame22 0:29983394c6b6 227 if(!_single_shot) {
edamame22 0:29983394c6b6 228 start_timer(_interval, _type, _single_shot);
edamame22 0:29983394c6b6 229 }
edamame22 0:29983394c6b6 230 }
edamame22 0:29983394c6b6 231 }