Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
m2mreporthandler.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/m2mreportobserver.h" 00017 #include "mbed-client/m2mconstants.h" 00018 #include "mbed-client/m2mtimer.h" 00019 #include "include/m2mreporthandler.h" 00020 #include "mbed-trace/mbed_trace.h" 00021 #include <stdio.h> 00022 #include <string.h> 00023 00024 #define TRACE_GROUP "mClt" 00025 00026 M2MReportHandler::M2MReportHandler(M2MReportObserver &observer) 00027 : _observer(observer), 00028 _pmax(-1.0f), 00029 _pmin(1.0f), 00030 _gt(0.0f), 00031 _lt(0.0f), 00032 _st(0.0f), 00033 _pmin_exceeded(false), 00034 _pmax_exceeded(false), 00035 _pmin_timer(NULL), 00036 _pmax_timer(NULL), 00037 _high_step(0.0f), 00038 _low_step(0.0f), 00039 _current_value(0.0f), 00040 _last_value(-1.0f), 00041 _attribute_state(0), 00042 _notify(false) 00043 { 00044 tr_debug("M2MReportHandler::M2MReportHandler()"); 00045 } 00046 00047 M2MReportHandler::~M2MReportHandler() 00048 { 00049 tr_debug("M2MReportHandler::~M2MReportHandler()"); 00050 00051 delete _pmax_timer; 00052 delete _pmin_timer; 00053 } 00054 00055 void M2MReportHandler::set_under_observation(bool observed) 00056 { 00057 tr_debug("M2MReportHandler::set_under_observation(observed %d)", (int)observed); 00058 stop_timers(); 00059 if(observed) { 00060 handle_timers(); 00061 } 00062 else { 00063 set_default_values(); 00064 } 00065 } 00066 00067 void M2MReportHandler::set_value(float value) 00068 { 00069 tr_debug("M2MReportHandler::set_value() - current %f, last %f", value, _last_value); 00070 _current_value = value; 00071 if(_current_value != _last_value) { 00072 tr_debug("M2MReportHandler::set_value() - UNDER OBSERVATION"); 00073 if (check_threshold_values()) { 00074 schedule_report(); 00075 } 00076 else { 00077 tr_debug("M2MReportHandler::set_value - value not in range"); 00078 _notify = false; 00079 _last_value = _current_value; 00080 if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || 00081 (_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt || 00082 (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) { 00083 tr_debug("M2MReportHandler::set_value - stop pmin timer"); 00084 if (_pmin_timer) { 00085 _pmin_timer->stop_timer(); 00086 _pmin_exceeded = true; 00087 } 00088 } 00089 } 00090 _high_step = _current_value + _st; 00091 _low_step = _current_value - _st; 00092 } 00093 } 00094 00095 void M2MReportHandler::set_notification_trigger(uint16_t obj_instance_id) 00096 { 00097 tr_debug("M2MReportHandler::set_notification_trigger(): %d", obj_instance_id); 00098 // Add to array if not there yet 00099 m2m::Vector<uint16_t>::const_iterator it; 00100 it = _changed_instance_ids.begin(); 00101 bool found = false; 00102 for ( ; it != _changed_instance_ids.end(); it++) { 00103 if ((*it) == obj_instance_id) { 00104 found = true; 00105 break; 00106 } 00107 } 00108 if (!found) { 00109 _changed_instance_ids.push_back(obj_instance_id); 00110 } 00111 00112 _current_value = 0.0f; 00113 _last_value = 1.0f; 00114 schedule_report(); 00115 } 00116 00117 bool M2MReportHandler::parse_notification_attribute(char *&query, 00118 M2MBase::BaseType type, 00119 M2MResourceInstance::ResourceType resource_type) 00120 { 00121 tr_debug("M2MReportHandler::parse_notification_attribute(Query %s, Base type %d)", query, (int)type); 00122 bool success = false; 00123 char* sep_pos = strchr(query, '&'); 00124 char* rest = query; 00125 if( sep_pos != NULL ){ 00126 char query_options[5][20]; 00127 float pmin = _pmin; 00128 float pmax = _pmax; 00129 float lt = _lt; 00130 float gt = _gt; 00131 float st = _st; 00132 float high = _high_step; 00133 float low = _low_step; 00134 uint8_t attr = _attribute_state; 00135 00136 memset(query_options, 0, sizeof(query_options[0][0]) * 5 * 20); 00137 uint8_t num_options = 0; 00138 while( sep_pos != NULL && num_options < 5){ 00139 size_t len = (size_t)(sep_pos-rest); 00140 if( len > 19 ){ 00141 len = 19; 00142 } 00143 memcpy(query_options[num_options], rest, len); 00144 sep_pos++; 00145 rest = sep_pos; 00146 sep_pos = strchr(rest, '&'); 00147 num_options++; 00148 } 00149 if( num_options < 5 && strlen(rest) > 0){ 00150 size_t len = (size_t)strlen(rest); 00151 if( len > 19 ){ 00152 len = 19; 00153 } 00154 memcpy(query_options[num_options++], rest, len); 00155 } 00156 00157 for (int option = 0; option < num_options; option++) { 00158 success = set_notification_attribute(query_options[option],type, resource_type); 00159 if (!success) { 00160 tr_debug("M2MReportHandler::parse_notification_attribute - break"); 00161 break; 00162 } 00163 } 00164 00165 if(success) { 00166 success = check_attribute_validity(); 00167 } 00168 else { 00169 tr_debug("M2MReportHandler::parse_notification_attribute - not valid query"); 00170 _pmin = pmin; 00171 _pmax = pmax; 00172 _st = st; 00173 _lt = lt; 00174 _gt = gt; 00175 _high_step = high; 00176 _low_step = low; 00177 _attribute_state = attr; 00178 } 00179 } 00180 else { 00181 if(set_notification_attribute(query, type, resource_type)) { 00182 success = check_attribute_validity(); 00183 } 00184 } 00185 00186 return success; 00187 } 00188 00189 void M2MReportHandler::timer_expired(M2MTimerObserver::Type type) 00190 { 00191 switch(type) { 00192 case M2MTimerObserver::PMinTimer: { 00193 tr_debug("M2MReportHandler::timer_expired - PMIN"); 00194 if (_notify || 00195 (_pmin > 0 && 00196 (_attribute_state & M2MReportHandler::Pmax) != M2MReportHandler::Pmax)){ 00197 report(); 00198 } 00199 else{ 00200 _pmin_exceeded = true; 00201 } 00202 } 00203 break; 00204 case M2MTimerObserver::PMaxTimer: { 00205 tr_debug("M2MReportHandler::timer_expired - PMAX"); 00206 _pmax_exceeded = true; 00207 if (_pmin_exceeded || 00208 (_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin ) { 00209 report(); 00210 } 00211 } 00212 break; 00213 default: 00214 break; 00215 } 00216 } 00217 00218 bool M2MReportHandler::set_notification_attribute(char* option, 00219 M2MBase::BaseType type, 00220 M2MResourceInstance::ResourceType resource_type) 00221 { 00222 tr_debug("M2MReportHandler::set_notification_attribute()"); 00223 bool success = false; 00224 char attribute[20]; 00225 char value[20]; 00226 memset(&attribute, 0, 20); 00227 memset(&value, 0, 20); 00228 00229 char* pos = strstr(option, EQUAL); 00230 if( pos != NULL ){ 00231 memcpy(attribute, option, (size_t)(pos-option)); 00232 pos++; 00233 memcpy(value, pos, strlen(pos)); 00234 }else{ 00235 memcpy(attribute, option, (size_t)strlen(option) + 1); 00236 } 00237 00238 if (strlen(value)) { 00239 if (strcmp(attribute, PMIN) == 0) { 00240 _pmin = atoi(value); 00241 success = true; 00242 _attribute_state |= M2MReportHandler::Pmin; 00243 tr_debug("M2MReportHandler::set_notification_attribute %s to %d", attribute, _pmin); 00244 } 00245 else if(strcmp(attribute, PMAX) == 0) { 00246 _pmax = atoi(value); 00247 success = true; 00248 _attribute_state |= M2MReportHandler::Pmax; 00249 tr_debug("M2MReportHandler::set_notification_attribute %s to %d", attribute, _pmax); 00250 } 00251 else if(strcmp(attribute, GT) == 0 && 00252 (M2MBase::Resource == type)){ 00253 _gt = atof(value); 00254 success = true; 00255 _attribute_state |= M2MReportHandler::Gt; 00256 tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _gt); 00257 } 00258 else if(strcmp(attribute, LT) == 0 && 00259 (M2MBase::Resource == type)){ 00260 _lt = atof(value); 00261 success = true; 00262 _attribute_state |= M2MReportHandler::Lt; 00263 tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _lt); 00264 } 00265 else if((strcmp(attribute, ST_SIZE) == 0 || (strcmp(attribute, STP) == 0)) 00266 && (M2MBase::Resource == type)){ 00267 _st = atof(value); 00268 success = true; 00269 _high_step = _current_value + _st; 00270 _low_step = _current_value - _st; 00271 _attribute_state |= M2MReportHandler::St; 00272 tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _st); 00273 } 00274 // Return false if try to set gt,lt or st when the resource type is something else than numerical 00275 if ((resource_type != M2MResourceInstance::INTEGER && 00276 resource_type != M2MResourceInstance::FLOAT) && 00277 ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt || 00278 (_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || 00279 (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St)) { 00280 tr_debug("M2MReportHandler::set_notification_attribute - not numerical resource"); 00281 success = false; 00282 } 00283 } 00284 return success; 00285 } 00286 00287 void M2MReportHandler::schedule_report() 00288 { 00289 tr_debug("M2MReportHandler::schedule_report()"); 00290 _notify = true; 00291 if ((_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin || 00292 _pmin_exceeded) { 00293 report(); 00294 } 00295 } 00296 00297 void M2MReportHandler::report() 00298 { 00299 tr_debug("M2MReportHandler::report()"); 00300 if(_current_value != _last_value && _notify) { 00301 tr_debug("M2MReportHandler::report()- send with PMIN"); 00302 _pmin_exceeded = false; 00303 _pmax_exceeded = false; 00304 _notify = false; 00305 _observer.observation_to_be_sent(_changed_instance_ids); 00306 _changed_instance_ids.clear(); 00307 if (_pmax_timer) { 00308 _pmax_timer->stop_timer(); 00309 } 00310 } 00311 else { 00312 if (_pmax_exceeded) { 00313 tr_debug("M2MReportHandler::report()- send with PMAX"); 00314 _observer.observation_to_be_sent(_changed_instance_ids, true); 00315 _changed_instance_ids.clear(); 00316 } 00317 else { 00318 tr_debug("M2MReportHandler::report()- no need to send"); 00319 } 00320 } 00321 handle_timers(); 00322 _last_value = _current_value; 00323 } 00324 00325 void M2MReportHandler::handle_timers() 00326 { 00327 tr_debug("M2MReportHandler::handle_timers()"); 00328 uint64_t time_interval = 0; 00329 if ((_attribute_state & M2MReportHandler::Pmin) == M2MReportHandler::Pmin) { 00330 if (_pmin == _pmax) { 00331 _pmin_exceeded = true; 00332 } else { 00333 _pmin_exceeded = false; 00334 time_interval = (uint64_t)(_pmin * 1000); 00335 tr_debug("M2MReportHandler::handle_timers() - Start PMIN interval: %d", (int)time_interval); 00336 if (!_pmin_timer) { 00337 _pmin_timer = new M2MTimer(*this); 00338 } 00339 _pmin_timer->start_timer(time_interval, 00340 M2MTimerObserver::PMinTimer, 00341 true); 00342 } 00343 } 00344 if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax) { 00345 if (_pmax > 0) { 00346 if (!_pmax_timer) { 00347 _pmax_timer = new M2MTimer(*this); 00348 } 00349 time_interval = (uint64_t)(_pmax * 1000); 00350 tr_debug("M2MReportHandler::handle_timers() - Start PMAX interval: %d", (int)time_interval); 00351 _pmax_timer->start_timer(time_interval, 00352 M2MTimerObserver::PMaxTimer, 00353 true); 00354 } 00355 } 00356 } 00357 00358 bool M2MReportHandler::check_attribute_validity() 00359 { 00360 bool success = true; 00361 if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax && 00362 ((_pmax >= -1.0f) && (_pmin > _pmax))) { 00363 success = false; 00364 } 00365 float low = _lt + 2 * _st; 00366 if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt && 00367 (low >= _gt)) { 00368 success = false; 00369 } 00370 return success; 00371 } 00372 00373 void M2MReportHandler::stop_timers() 00374 { 00375 tr_debug("M2MReportHandler::stop_timers()"); 00376 if (_pmin_timer) { 00377 _pmin_exceeded = false; 00378 _pmin_timer->stop_timer(); 00379 00380 delete _pmin_timer; 00381 _pmin_timer = NULL; 00382 } 00383 if (_pmax_timer) { 00384 _pmax_exceeded = false; 00385 _pmax_timer->stop_timer(); 00386 delete _pmax_timer; 00387 _pmax_timer = NULL; 00388 } 00389 tr_debug("M2MReportHandler::stop_timers() - out"); 00390 } 00391 00392 void M2MReportHandler::set_default_values() 00393 { 00394 tr_debug("M2MReportHandler::set_default_values"); 00395 _pmax = -1.0f; 00396 _pmin = 1.0f; 00397 _gt = 0.0f; 00398 _lt = 0.0f; 00399 _st = 0.0f; 00400 _high_step = 0.0f; 00401 _low_step = 0.0f; 00402 _pmin_exceeded = false; 00403 _pmax_exceeded = false; 00404 _last_value = -1.0f; 00405 _attribute_state = 0; 00406 _changed_instance_ids.clear(); 00407 } 00408 00409 bool M2MReportHandler::check_threshold_values() 00410 { 00411 tr_debug("M2MReportHandler::check_threshold_values"); 00412 tr_debug("Current value: %f", _current_value); 00413 tr_debug("High step: %f", _high_step); 00414 tr_debug("Low step: %f", _low_step); 00415 tr_debug("Less than: %f", _lt); 00416 tr_debug("Greater than: %f", _gt); 00417 tr_debug("Step: %f", _st); 00418 bool can_send = false; 00419 // Check step condition 00420 if ((_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) { 00421 if ((_current_value >= _high_step || 00422 _current_value <= _low_step)) { 00423 can_send = true; 00424 } 00425 else { 00426 if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || 00427 (_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt ) { 00428 can_send = check_gt_lt_params(); 00429 } 00430 else { 00431 can_send = false; 00432 } 00433 } 00434 } 00435 else { 00436 can_send = check_gt_lt_params(); 00437 } 00438 tr_debug("M2MReportHandler::check_threshold_values - value in range = %d", (int)can_send); 00439 return can_send; 00440 } 00441 00442 bool M2MReportHandler::check_gt_lt_params() 00443 { 00444 tr_debug("M2MReportHandler::check_gt_lt_params"); 00445 bool can_send = false; 00446 // GT & LT set. 00447 if ((_attribute_state & (M2MReportHandler::Lt | M2MReportHandler::Gt)) 00448 == (M2MReportHandler::Lt | M2MReportHandler::Gt)) { 00449 if (_current_value > _gt || _current_value < _lt) { 00450 can_send = true; 00451 } 00452 else { 00453 can_send = false; 00454 } 00455 } 00456 // Only LT 00457 else if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt && 00458 (_attribute_state & M2MReportHandler::Gt) == 0 ) { 00459 if (_current_value < _lt) { 00460 can_send = true; 00461 } 00462 else { 00463 can_send = false; 00464 } 00465 } 00466 // Only GT 00467 else if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt && 00468 (_attribute_state & M2MReportHandler::Lt) == 0 ) { 00469 if (_current_value > _gt) { 00470 can_send = true; 00471 } 00472 else { 00473 can_send = false; 00474 } 00475 } 00476 // GT & LT not set. 00477 else { 00478 can_send = true; 00479 } 00480 tr_debug("M2MReportHandler::check_gt_lt_params - value in range = %d", (int)can_send); 00481 return can_send; 00482 } 00483 00484 uint8_t M2MReportHandler::attribute_flags() 00485 { 00486 return _attribute_state; 00487 }
Generated on Tue Jul 12 2022 12:28:38 by
1.7.2
