Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

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 // Needed for PRIu64 on FreeRTOS
00017 #include <stdio.h>
00018 // Note: this macro is needed on armcc to get the the limit macros like UINT16_MAX
00019 #ifndef __STDC_LIMIT_MACROS
00020 #define __STDC_LIMIT_MACROS
00021 #endif
00022 
00023 // Note: this macro is needed on armcc to get the the PRI*32 macros
00024 // from inttypes.h in a C++ code.
00025 #ifndef __STDC_FORMAT_MACROS
00026 #define __STDC_FORMAT_MACROS
00027 #endif
00028 
00029 #include "mbed-client/m2mreportobserver.h"
00030 #include "mbed-client/m2mconstants.h"
00031 #include "mbed-client/m2mtimer.h"
00032 #include "include/m2mreporthandler.h"
00033 #include "mbed-trace/mbed_trace.h"
00034 #include <string.h>
00035 #include <stdlib.h>
00036 
00037 #define TRACE_GROUP "mClt"
00038 
00039 M2MReportHandler::M2MReportHandler(M2MReportObserver &observer, M2MBase::DataType type)
00040 : _observer(observer),
00041   _is_under_observation(false),
00042   _observation_level(M2MBase::None),
00043   _attribute_state(0),
00044   _token_length(0),
00045   _resource_type(type),
00046   _notify(false),
00047   _pmin_exceeded(false),
00048   _pmax_exceeded(false),
00049   _observation_number(0),
00050   _pmin_timer(*this),
00051   _pmax_timer(*this),
00052   _token(NULL),
00053   _pmax(-1.0f),
00054   _pmin(1.0f),
00055   _gt(0.0f),
00056   _lt(0.0f),
00057   _st(0.0f),
00058   _notification_send_in_progress(false),
00059   _notification_in_queue(false),
00060   _blockwise_notify(false),
00061   _pmin_quiet_period(false)
00062 {
00063     tr_debug("M2MReportHandler::M2MReportHandler()");
00064     if (_resource_type == M2MBase::FLOAT) {
00065         _high_step.float_value = 0;
00066         _low_step.float_value = 0;
00067         _last_value.float_value = -1;
00068         _current_value.float_value = 0;
00069     } else {
00070         _high_step.int_value = 0;
00071         _low_step.int_value = 0;
00072         _last_value.int_value = -1;
00073         _current_value.int_value = 0;
00074     }
00075 }
00076 
00077 M2MReportHandler::~M2MReportHandler()
00078 {
00079     tr_debug("M2MReportHandler::~M2MReportHandler()");
00080     free(_token);
00081 }
00082 
00083 void M2MReportHandler::set_under_observation(bool observed)
00084 {
00085     tr_debug("M2MReportHandler::set_under_observation(observed %d)", (int)observed);
00086 
00087     _is_under_observation = observed;
00088 
00089     stop_timers();
00090     if (observed) {
00091         handle_timers();
00092     }
00093     else {
00094         set_default_values();
00095     }
00096 }
00097 
00098 void M2MReportHandler::set_value_float(float value)
00099 {
00100     tr_debug("M2MReportHandler::set_value_float() - current %f, last %f", value, _last_value.float_value);
00101     _current_value.float_value = value;
00102 
00103     if (_current_value.float_value != _last_value.float_value) {
00104         send_value();
00105         _high_step.float_value = _last_value.float_value + _st;
00106         _low_step.float_value = _last_value.float_value - _st;
00107     }
00108 }
00109 
00110 void M2MReportHandler::set_value_int(int64_t value)
00111 {
00112     tr_debug("M2MReportHandler::set_value_int() - current %" PRId64 ", last % " PRId64, value, _last_value.int_value);
00113     _current_value.int_value = value;
00114 
00115     if (_current_value.int_value != _last_value.int_value) {
00116         send_value();
00117         _high_step.int_value = _last_value.int_value + _st;
00118         _low_step.int_value = _last_value.int_value - _st;
00119     }
00120 }
00121 
00122 void M2MReportHandler::set_notification_trigger(uint16_t obj_instance_id)
00123 {
00124     tr_debug("M2MReportHandler::set_notification_trigger(): %d", obj_instance_id);
00125     // Add to array if not there yet
00126     m2m::Vector<uint16_t>::const_iterator it;
00127     it = _changed_instance_ids.begin();
00128     bool found = false;
00129     for ( ; it != _changed_instance_ids.end(); it++) {
00130         if ((*it) == obj_instance_id) {
00131             found = true;
00132             break;
00133         }
00134     }
00135     if (!found) {
00136         _changed_instance_ids.push_back(obj_instance_id);
00137     }
00138 
00139     if (_resource_type == M2MBase::FLOAT) {
00140         _current_value.float_value = 0;
00141         _last_value.float_value = 1;
00142     } else {
00143         _current_value.int_value = 0;
00144         _last_value.int_value = 1;
00145     }
00146     set_notification_in_queue(true);
00147     schedule_report();
00148 }
00149 
00150 bool M2MReportHandler::parse_notification_attribute(const char *query,
00151                                                     M2MBase::BaseType type,
00152                                                     M2MResourceInstance::ResourceType resource_type)
00153 {
00154     tr_debug("M2MReportHandler::parse_notification_attribute(Query %s, Base type %d)", query, (int)type);
00155     bool success = false;
00156     const char* sep_pos = strchr(query, '&');
00157     const char* rest = query;
00158     if( sep_pos != NULL ){
00159         char query_options[5][20];
00160         float pmin = _pmin;
00161         float pmax = _pmax;
00162         float lt = _lt;
00163         float gt = _gt;
00164         float st = _st;
00165         high_step_t high = _high_step;
00166         low_step_t low = _low_step;
00167         uint8_t attr = _attribute_state;
00168 
00169         memset(query_options, 0, sizeof(query_options[0][0]) * 5 * 20);
00170         uint8_t num_options = 0;
00171         while( sep_pos != NULL && num_options < 5){
00172             size_t len = (size_t)(sep_pos-rest);
00173             if( len > 19 ){
00174                 len = 19;
00175             }
00176             memcpy(query_options[num_options], rest, len);
00177             sep_pos++;
00178             rest = sep_pos;
00179             sep_pos = strchr(rest, '&');
00180             num_options++;
00181         }
00182         if( num_options < 5 && strlen(rest) > 0){
00183             size_t len = (size_t)strlen(rest);
00184             if( len > 19 ){
00185                 len = 19;
00186             }
00187             memcpy(query_options[num_options++], rest, len);
00188         }
00189 
00190         for (int option = 0; option < num_options; option++) {
00191             success = set_notification_attribute(query_options[option],type, resource_type);
00192             if (!success) {
00193                 tr_error("M2MReportHandler::parse_notification_attribute - break");
00194                 break;
00195             }
00196         }
00197 
00198         if(success) {
00199              success = check_attribute_validity();
00200         }
00201         else {
00202             tr_debug("M2MReportHandler::parse_notification_attribute - not valid query");
00203             _pmin = pmin;
00204             _pmax = pmax;
00205             _st = st;
00206             _lt = lt;
00207             _gt = gt;
00208             _high_step = high;
00209             _low_step = low;
00210             _attribute_state = attr;
00211         }
00212     }
00213     else {
00214         if(set_notification_attribute(query, type, resource_type)) {
00215             success = check_attribute_validity();
00216         }
00217     }
00218 
00219     return success;
00220 }
00221 
00222 void M2MReportHandler::timer_expired(M2MTimerObserver::Type type)
00223 {
00224     switch(type) {
00225         case M2MTimerObserver::PMinTimer: {
00226             tr_debug("M2MReportHandler::timer_expired - PMIN");
00227 
00228             _pmin_exceeded = true;
00229             if (_notify ||
00230                 (_pmin > 0 && (_attribute_state & M2MReportHandler::Pmax) != M2MReportHandler::Pmax)){
00231                 report();
00232             }
00233 
00234             // If value hasn't changed since last expiration, next value change should send notification immediately
00235             if (_resource_type == M2MBase::FLOAT) {
00236                 if (_current_value.float_value == _last_value.float_value) {
00237                     _pmin_quiet_period = true;
00238                 }
00239             } else {
00240                 if (_current_value.int_value == _last_value.int_value) {
00241                     _pmin_quiet_period = true;
00242                 }
00243             }
00244         }
00245         break;
00246         case M2MTimerObserver::PMaxTimer: {
00247             tr_debug("M2MReportHandler::timer_expired - PMAX");
00248             _pmax_exceeded = true;
00249             if (_pmin_exceeded ||
00250                     (_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin ) {
00251                 report();
00252             }
00253         }
00254         break;
00255         default:
00256             break;
00257     }
00258 }
00259 
00260 bool M2MReportHandler::set_notification_attribute(const char* option,
00261                                                   M2MBase::BaseType type,
00262                                                   M2MResourceInstance::ResourceType resource_type)
00263 {
00264     tr_debug("M2MReportHandler::set_notification_attribute()");
00265     bool success = false;
00266     const int max_size = 20;
00267     char attribute[max_size];
00268     char value[max_size];
00269 
00270     const char* pos = strstr(option, EQUAL);
00271     if (pos) {
00272         size_t attr_len = pos - option;
00273         // Skip the "=" mark
00274         pos++;
00275         size_t value_len = strlen(pos);
00276         if (value_len && value_len < max_size && attr_len < max_size) {
00277             memcpy(attribute, option, attr_len);
00278             attribute[attr_len] = '\0';
00279             memcpy(value, pos, value_len);
00280             value[value_len] = '\0';
00281             success = true;
00282         }
00283     }
00284 
00285     if (success) {
00286         if (strcmp(attribute, PMIN) == 0) {
00287            _pmin = atoi(value);
00288             success = true;
00289             _attribute_state |= M2MReportHandler::Pmin;
00290             tr_info("M2MReportHandler::set_notification_attribute %s to %" PRId32, attribute, _pmin);
00291         }
00292         else if(strcmp(attribute, PMAX) == 0) {
00293             _pmax = atoi(value);
00294             success = true;
00295             _attribute_state |= M2MReportHandler::Pmax;
00296             tr_info("M2MReportHandler::set_notification_attribute %s to %" PRId32, attribute, _pmax);
00297         }
00298         else if(strcmp(attribute, GT) == 0 &&
00299                 (M2MBase::Resource == type)){
00300             success = true;
00301             _gt = atof(value);
00302             _attribute_state |= M2MReportHandler::Gt;
00303             tr_info("M2MReportHandler::set_notification_attribute %s to %f", attribute, _gt);
00304         }
00305         else if(strcmp(attribute, LT) == 0 &&
00306                 (M2MBase::Resource == type)){
00307             success = true;
00308             _lt = atof(value);
00309             _attribute_state |= M2MReportHandler::Lt;
00310             tr_info("M2MReportHandler::set_notification_attribute %s to %f", attribute, _lt);
00311         }
00312         else if((strcmp(attribute, ST_SIZE) == 0 || (strcmp(attribute, STP) == 0))
00313                 && (M2MBase::Resource == type)){
00314             success = true;
00315             _st = atof(value);
00316             if (_resource_type == M2MBase::FLOAT) {
00317                 _high_step.float_value = _current_value.float_value + _st;
00318                 _low_step.float_value = _current_value.float_value - _st;
00319             } else {
00320                 _high_step.int_value = _current_value.int_value + _st;
00321                 _low_step.int_value = _current_value.int_value - _st;
00322             }
00323 
00324             _attribute_state |= M2MReportHandler::St;
00325             tr_info("M2MReportHandler::set_notification_attribute %s to %f", attribute, _st);
00326         } else {
00327             tr_error("M2MReportHandler::set_notification_attribute - unknown write attribute!");
00328             success = false;
00329         }
00330 
00331         // Return false if try to set gt,lt or st when the resource type is something else than numerical
00332         if (success &&
00333             (resource_type != M2MResourceInstance::INTEGER && resource_type != M2MResourceInstance::FLOAT) &&
00334             ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt ||
00335             (_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt ||
00336             (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St)) {
00337             tr_debug("M2MReportHandler::set_notification_attribute - not numerical resource");
00338             success = false;
00339         }
00340     } else {
00341         tr_error("M2MReportHandler::set_notification_attribute - failed to parse query!");
00342     }
00343     return success;
00344 }
00345 
00346 void M2MReportHandler::schedule_report(bool in_queue)
00347 {
00348     tr_debug("M2MReportHandler::schedule_report()");
00349     _notify = true;
00350 
00351     if ((_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin ||
00352          _pmin_exceeded ||
00353          _pmin_quiet_period) {
00354         report(in_queue);
00355     }
00356 }
00357 
00358 void M2MReportHandler::report(bool in_queue)
00359 {
00360     if (_resource_type == M2MBase::FLOAT) {
00361         tr_debug("M2MReportHandler::report() - current %2f, last %2f, notify %d, queued %d", _current_value.float_value, _last_value.float_value, _notify, in_queue);
00362     } else {
00363         tr_debug("M2MReportHandler::report() - current %" PRId64 ", last % " PRId64 ", notify %d, queued %d", _current_value.int_value, _last_value.int_value, _notify, in_queue);
00364     }
00365 
00366     bool value_changed = false;
00367 
00368     if (_resource_type == M2MBase::FLOAT) {
00369         if (_current_value.float_value != _last_value.float_value) {
00370             value_changed = true;
00371         }
00372     } else {
00373         if (_current_value.int_value != _last_value.int_value) {
00374             value_changed = true;
00375         }
00376     }
00377 
00378     if((value_changed && _notify) || in_queue) {
00379         if (_pmin_exceeded) {
00380             tr_debug("M2MReportHandler::report()- send with PMIN expiration");
00381         } else {
00382             tr_debug("M2MReportHandler::report()- send with VALUE change");
00383         }
00384 
00385         _pmin_exceeded = false;
00386         _pmax_exceeded = false;
00387         _notify = false;
00388         _pmin_quiet_period = false;
00389         _observation_number++;
00390 
00391         if (_observation_number == 1) {
00392             // Increment the observation number by 1 if it is already 1 because CoAP specification has reserved 1 for DEREGISTER notification
00393             _observation_number++;
00394         }
00395 
00396         if (_observer.observation_to_be_sent(_changed_instance_ids, observation_number())) {
00397             _changed_instance_ids.clear();
00398             set_notification_send_in_progress(true);
00399             if (_resource_type == M2MBase::FLOAT) {
00400                 _last_value.float_value = _current_value.float_value;
00401             } else {
00402                 _last_value.int_value = _current_value.int_value;
00403             }
00404         }
00405 
00406         _pmax_timer.stop_timer();
00407     }
00408     else {
00409         if (_pmax_exceeded) {
00410             tr_debug("M2MReportHandler::report()- send with PMAX expiration");
00411             _observation_number++;
00412 
00413             if (_observation_number == 1) {
00414                 // Increment the observation number by 1 if it is already 1 because CoAP specification has reserved 1 for DEREGISTER notification
00415                 _observation_number++;
00416             }
00417 
00418             if (_observer.observation_to_be_sent(_changed_instance_ids, observation_number(), true)) {
00419                 _changed_instance_ids.clear();
00420                 set_notification_send_in_progress(true);
00421             } else {
00422                 set_notification_in_queue(true);
00423             }
00424             if (_resource_type == M2MBase::FLOAT) {
00425                 _last_value.float_value = _current_value.float_value;
00426             } else {
00427                 _last_value.int_value = _current_value.int_value;
00428             }
00429         }
00430         else {
00431             tr_debug("M2MReportHandler::report()- no need to send");
00432         }
00433     }
00434     handle_timers();
00435 }
00436 
00437 void M2MReportHandler::handle_timers()
00438 {
00439     tr_debug("M2MReportHandler::handle_timers()");
00440     uint64_t time_interval = 0;
00441     if ((_attribute_state & M2MReportHandler::Pmin) == M2MReportHandler::Pmin) {
00442         if (_pmin == _pmax) {
00443             _pmin_exceeded = true;
00444         } else {
00445             _pmin_exceeded = false;
00446             time_interval = (uint64_t) ((uint64_t)_pmin * 1000);
00447             tr_debug("M2MReportHandler::handle_timers() - Start PMIN interval: %d", (int)time_interval);
00448             _pmin_timer.start_timer(time_interval,
00449                                      M2MTimerObserver::PMinTimer,
00450                                      true);
00451         }
00452     }
00453     if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax) {
00454         if (_pmax > 0) {
00455             time_interval = (uint64_t) ((uint64_t)_pmax * 1000);
00456             tr_debug("M2MReportHandler::handle_timers() - Start PMAX interval: %d", (int)time_interval);
00457             _pmax_timer.start_timer(time_interval,
00458                                      M2MTimerObserver::PMaxTimer,
00459                                      true);
00460         }
00461     }
00462 }
00463 
00464 bool M2MReportHandler::check_attribute_validity() const
00465 {
00466     bool success = true;
00467     if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax &&
00468         ((_pmax >= -1.0) && (_pmin > _pmax))) {
00469         success = false;
00470     }
00471     float low = _lt + 2 * _st;
00472     if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt &&
00473         (low >= _gt)) {
00474         success = false;
00475     }
00476     return success;
00477 }
00478 
00479 void M2MReportHandler::stop_timers()
00480 {
00481     tr_debug("M2MReportHandler::stop_timers()");
00482 
00483     _pmin_exceeded = false;
00484     _pmin_timer.stop_timer();
00485 
00486     _pmax_exceeded = false;
00487     _pmax_timer.stop_timer();
00488 
00489     tr_debug("M2MReportHandler::stop_timers() - out");
00490 }
00491 
00492 void M2MReportHandler::set_default_values()
00493 {
00494     tr_debug("M2MReportHandler::set_default_values");
00495     _pmax = -1.0;
00496     _pmin = 1.0;
00497     _gt = 0.0f;
00498     _lt = 0.0f;
00499     _st = 0.0f;
00500     _pmin_exceeded = false;
00501     _pmax_exceeded = false;
00502     _attribute_state = 0;
00503     _changed_instance_ids.clear();
00504     _notification_in_queue = false;
00505     _notification_send_in_progress = false;
00506     _pmin_quiet_period = false;
00507     if (_resource_type == M2MBase::FLOAT) {
00508         _high_step.float_value = 0.0f;
00509         _low_step.float_value = 0.0f;
00510         _last_value.float_value = -1.0f;
00511     } else {
00512         _high_step.int_value = 0;
00513         _low_step.int_value = 0;
00514         _last_value.int_value = -1;
00515     }
00516 }
00517 
00518 bool M2MReportHandler::check_threshold_values() const
00519 {
00520     tr_debug("M2MReportHandler::check_threshold_values");
00521     if (_resource_type == M2MBase::FLOAT) {
00522         tr_debug("Current value: %f", _current_value.float_value);
00523         tr_debug("Last value: %f", _last_value.float_value);
00524         tr_debug("High step: %f", _high_step.float_value);
00525         tr_debug("Low step: %f", _low_step.float_value);
00526     } else {
00527         tr_debug("Current value: %" PRId64, _current_value.int_value);
00528         tr_debug("Last value: %" PRId64, _last_value.int_value);
00529         tr_debug("High step: %" PRId64, _high_step.int_value);
00530         tr_debug("Low step: %" PRId64, _low_step.int_value);
00531     }
00532 
00533     tr_debug("Less than: %f", _lt);
00534     tr_debug("Greater than: %f", _gt);
00535     tr_debug("Step: %f", _st);
00536 
00537     bool can_send = check_gt_lt_params();
00538     if (can_send) {
00539         if ((_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) {
00540             can_send = false;
00541 
00542             if (_resource_type == M2MBase::FLOAT) {
00543                 if (_current_value.float_value >= _high_step.float_value ||
00544                     _current_value.float_value <= _low_step.float_value) {
00545                     can_send = true;
00546                 }
00547             } else {
00548                 if ((_current_value.int_value >= _high_step.int_value ||
00549                     _current_value.int_value <= _low_step.int_value)) {
00550                     can_send = true;
00551                 }
00552             }
00553         }
00554     }
00555 
00556     tr_debug("M2MReportHandler::check_threshold_values - value can be sent = %d", (int)can_send);
00557     return can_send;
00558 }
00559 
00560 bool M2MReportHandler::check_gt_lt_params() const
00561 {
00562     tr_debug("M2MReportHandler::check_gt_lt_params");
00563     bool can_send = false;
00564     // GT & LT set.
00565     if ((_attribute_state & (M2MReportHandler::Lt | M2MReportHandler::Gt)) ==
00566         (M2MReportHandler::Lt | M2MReportHandler::Gt)) {
00567         if (_resource_type == M2MBase::FLOAT) {
00568             if (_current_value.float_value > _gt || _current_value.float_value < _lt) {
00569                 can_send = true;
00570             }
00571         } else {
00572             if (_current_value.int_value > _gt || _current_value.int_value < _lt) {
00573                 can_send = true;
00574             }
00575         }
00576     }
00577     // Only LT
00578     else if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt &&
00579              (_attribute_state & M2MReportHandler::Gt) == 0 ) {
00580         if (_resource_type == M2MBase::FLOAT) {
00581             if (_current_value.float_value < _lt) {
00582                 can_send = true;
00583             }
00584         } else {
00585             if (_current_value.int_value < _lt) {
00586                 can_send = true;
00587             }
00588         }
00589 
00590     }
00591     // Only GT
00592     else if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt &&
00593              (_attribute_state & M2MReportHandler::Lt) == 0 ) {
00594         if (_resource_type == M2MBase::FLOAT) {
00595             if (_current_value.float_value > _gt) {
00596                 can_send = true;
00597             }
00598         } else {
00599             if (_current_value.int_value > _gt) {
00600                 can_send = true;
00601             }
00602         }
00603 
00604     }
00605     // GT & LT not set.
00606     else {
00607         can_send = true;
00608     }
00609     tr_debug("M2MReportHandler::check_gt_lt_params - value in range = %d", (int)can_send);
00610     return can_send;
00611 }
00612 
00613 uint8_t M2MReportHandler::attribute_flags() const
00614 {
00615     return _attribute_state;
00616 }
00617 
00618 void M2MReportHandler::set_observation_token(const uint8_t *token, const uint8_t length)
00619 {
00620      free(_token);
00621      _token = NULL;
00622      _token_length = 0;
00623 
00624     if( token != NULL && length > 0 ) {
00625         _token = alloc_copy((uint8_t *)token, length);
00626         if(_token) {
00627             _token_length = length;
00628         }
00629     }
00630 }
00631 
00632 void M2MReportHandler::get_observation_token(uint8_t *token, uint8_t &token_length) const
00633 {
00634     memcpy(token, _token, _token_length);
00635     token_length = _token_length;
00636 }
00637 
00638 uint16_t M2MReportHandler::observation_number() const
00639 {
00640     return _observation_number;
00641 }
00642 
00643 void M2MReportHandler::add_observation_level(M2MBase::Observation obs_level)
00644 {
00645     _observation_level = (M2MBase::Observation)(_observation_level | obs_level);
00646 }
00647 
00648 void M2MReportHandler::remove_observation_level(M2MBase::Observation obs_level)
00649 {
00650     _observation_level = (M2MBase::Observation)(_observation_level & ~obs_level);
00651 }
00652 
00653 M2MBase::Observation M2MReportHandler::observation_level() const
00654 {
00655     return _observation_level;
00656 }
00657 
00658 bool M2MReportHandler::is_under_observation() const
00659 {
00660     return _is_under_observation;
00661 }
00662 
00663 uint8_t* M2MReportHandler::alloc_copy(const uint8_t* source, uint32_t size)
00664 {
00665     assert(source != NULL);
00666 
00667     uint8_t* result = (uint8_t*)malloc(size);
00668     if (result) {
00669         memcpy(result, source, size);
00670     }
00671     return result;
00672 }
00673 
00674 void M2MReportHandler::set_notification_in_queue(bool to_queue)
00675 {
00676     _notification_in_queue = to_queue;
00677 }
00678 
00679 bool M2MReportHandler::notification_in_queue() const
00680 {
00681     return _notification_in_queue;
00682 }
00683 
00684 void M2MReportHandler::set_notification_send_in_progress(bool progress)
00685 {
00686     _notification_send_in_progress = progress;
00687 }
00688 
00689 bool M2MReportHandler::notification_send_in_progress() const
00690 {
00691     return _notification_send_in_progress;
00692 }
00693 
00694 void M2MReportHandler::set_blockwise_notify(bool blockwise_notify)
00695 {
00696     _blockwise_notify = blockwise_notify;
00697 }
00698 
00699 bool M2MReportHandler::blockwise_notify() const
00700 {
00701     return _blockwise_notify;
00702 }
00703 
00704 void M2MReportHandler::send_value()
00705 {
00706     tr_debug("M2MReportHandler::send_value() - new value");
00707     set_notification_in_queue(true);
00708     if (check_threshold_values()) {
00709         schedule_report();
00710     } else {
00711         tr_debug("M2MReportHandler::send_value - value not in range");
00712         _notify = false;
00713         if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt ||
00714             (_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt ||
00715             (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) {
00716             tr_debug("M2MReportHandler::send_value - stop pmin timer");
00717             _pmin_timer.stop_timer();
00718             _pmin_exceeded = true;
00719         }
00720     }
00721 }