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