Austin Blackstone / Mbed 2 deprecated mbed-client-classic-example-lwip

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by sandbox

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mreporthandler.cpp Source File

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 }