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.
Fork of mbed-client by
source/m2mreporthandler.cpp
- Committer:
- Christopher Haster
- Date:
- 2016-01-22
- Revision:
- 1:79b6cc67d8b4
- Child:
- 4:ae5178938864
File content as of revision 1:79b6cc67d8b4:
/* * Copyright (c) 2015 ARM Limited. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mbed-client/m2mreportobserver.h" #include "mbed-client/m2mconstants.h" #include "mbed-client/m2mtimer.h" #include "include/m2mreporthandler.h" #include "ns_trace.h" #include <stdio.h> #include <string.h> M2MReportHandler::M2MReportHandler(M2MReportObserver &observer) : _observer(observer), _pmax(-1.0f), _pmin(1.0f), _gt(0.0f), _lt(0.0f), _st(0.0f), _pmin_exceeded(false), _pmax_exceeded(false), _pmin_timer(NULL), _pmax_timer(NULL), _high_step(0.0f), _low_step(0.0f), _current_value(0.0f), _last_value(0.0f), _attribute_state(0), _notify(false) { tr_debug("M2MReportHandler::M2MReportHandler()"); } M2MReportHandler::~M2MReportHandler() { tr_debug("M2MReportHandler::~M2MReportHandler()"); if(_pmax_timer) { delete _pmax_timer; } if(_pmin_timer) { delete _pmin_timer; } } void M2MReportHandler::set_under_observation(bool observed) { tr_debug("M2MReportHandler::set_under_observation(observed %d)", (int)observed); stop_timers(); if(observed) { handle_timers(); } else { set_default_values(); } } void M2MReportHandler::set_value(float value) { tr_debug("M2MReportHandler::set_value()"); _current_value = value; if(_current_value != _last_value) { tr_debug("M2MReportHandler::set_value() - UNDER OBSERVATION"); if (check_threshold_values()) { schedule_report(); } else { tr_debug("M2MReportHandler::set_value - value not in range"); _notify = false; _last_value = _current_value; if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || (_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt || (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) { tr_debug("M2MReportHandler::set_value - stop pmin timer"); if (_pmin_timer) { _pmin_timer->stop_timer(); _pmin_exceeded = true; } } } _high_step = _current_value + _st; _low_step = _current_value - _st; } } void M2MReportHandler::set_notification_trigger() { tr_debug("M2MReportHandler::set_notification_trigger()"); _current_value = 0.0f; _last_value = 1.0f; schedule_report(); } bool M2MReportHandler::parse_notification_attribute(char *&query, M2MBase::BaseType type, M2MResourceInstance::ResourceType resource_type) { tr_debug("M2MReportHandler::parse_notification_attribute(Query %s, Base type %d)", query, (int)type); bool success = false; char* sep_pos = strchr(query, '&'); char* rest = query; if( sep_pos != NULL ){ char query_options[5][20]; float pmin = _pmin; float pmax = _pmax; float lt = _lt; float gt = _gt; float st = _st; float high = _high_step; float low = _low_step; uint8_t attr = _attribute_state; memset(query_options, 0, sizeof(query_options[0][0]) * 5 * 20); uint8_t num_options = 0; while( sep_pos != NULL && num_options < 5){ size_t len = (size_t)(sep_pos-rest); if( len > 19 ){ len = 19; } memcpy(query_options[num_options], rest, len); sep_pos++; rest = sep_pos; sep_pos = strchr(rest, '&'); num_options++; } if( num_options < 5 && strlen(rest) > 0){ size_t len = (size_t)strlen(rest); if( len > 19 ){ len = 19; } memcpy(query_options[num_options++], rest, len); } for (int option = 0; option < num_options; option++) { success = set_notification_attribute(query_options[option],type, resource_type); if (!success) { tr_debug("M2MReportHandler::parse_notification_attribute - break"); break; } } if(success) { success = check_attribute_validity(); } else { tr_debug("M2MReportHandler::parse_notification_attribute - not valid query"); _pmin = pmin; _pmax = pmax; _st = st; _lt = lt; _gt = gt; _high_step = high; _low_step = low; _attribute_state = attr; } } else { if(set_notification_attribute(query, type, resource_type)) { success = check_attribute_validity(); } } return success; } void M2MReportHandler::timer_expired(M2MTimerObserver::Type type) { switch(type) { case M2MTimerObserver::PMinTimer: { tr_debug("M2MReportHandler::timer_expired - PMIN"); if (_notify || (_pmin > 0 && (_attribute_state & M2MReportHandler::Pmax) != M2MReportHandler::Pmax)){ report(); } else{ _pmin_exceeded = true; } } break; case M2MTimerObserver::PMaxTimer: { tr_debug("M2MReportHandler::timer_expired - PMAX"); _pmax_exceeded = true; if (_pmin_exceeded || (_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin ) { report(); } } break; default: break; } } bool M2MReportHandler::set_notification_attribute(char* option, M2MBase::BaseType type, M2MResourceInstance::ResourceType resource_type) { tr_debug("M2MReportHandler::set_notification_attribute()"); bool success = false; char attribute[20]; char value[20]; memset(&attribute, 0, 20); memset(&value, 0, 20); char* pos = strstr(option, EQUAL.c_str()); if( pos != NULL ){ memcpy(attribute, option, (size_t)(pos-option)); pos++; memcpy(value, pos, 20); }else{ memcpy(attribute, option, (size_t)strlen(option) + 1); } if (strcmp(attribute, PMIN.c_str()) == 0) { sscanf(value, "%f", &_pmin); success = true; _attribute_state |= M2MReportHandler::Pmin; tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _pmin); } else if(strcmp(attribute, PMAX.c_str()) == 0) { sscanf(value, "%f", &_pmax); success = true; _attribute_state |= M2MReportHandler::Pmax; tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _pmax); } else if(strcmp(attribute, GT.c_str()) == 0 && (M2MBase::Resource == type)){ sscanf(value, "%f", &_gt); success = true; _attribute_state |= M2MReportHandler::Gt; tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _gt); } else if(strcmp(attribute, LT.c_str()) == 0 && (M2MBase::Resource == type)){ sscanf(value, "%f", &_lt); success = true; _attribute_state |= M2MReportHandler::Lt; tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _lt); } else if(strcmp(attribute, ST.c_str()) == 0 && (M2MBase::Resource == type)){ sscanf(value, "%f", &_st); success = true; _high_step = _current_value + _st; _low_step = _current_value - _st; _attribute_state |= M2MReportHandler::St; tr_debug("M2MReportHandler::set_notification_attribute %s to %f", attribute, _st); } else if(strcmp(attribute, CANCEL.c_str()) == 0) { success = true; _attribute_state |= M2MReportHandler::Cancel; tr_debug("M2MReportHandler::set_notification_attribute cancel"); } // Return false if try to set gt,lt or st when the resource type is something else than numerical if ((resource_type != M2MResourceInstance::INTEGER && resource_type != M2MResourceInstance::FLOAT) && ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt || (_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || (_attribute_state & M2MReportHandler::St) == M2MReportHandler::St)) { tr_debug("M2MReportHandler::set_notification_attribute - not numerical resource"); success = false; } return success; } void M2MReportHandler::schedule_report() { tr_debug("M2MReportHandler::schedule_report()"); _notify = true; if ((_attribute_state & M2MReportHandler::Pmin) != M2MReportHandler::Pmin || _pmin_exceeded) { report(); } } void M2MReportHandler::report() { tr_debug("M2MReportHandler::report()"); if(_current_value != _last_value && _notify) { tr_debug("M2MReportHandler::report()- send with PMIN"); _pmin_exceeded = false; _pmax_exceeded = false; _notify = false; _observer.observation_to_be_sent(); if (_pmax_timer) { _pmax_timer->stop_timer(); } } else { if (_pmax_exceeded) { tr_debug("M2MReportHandler::report()- send with PMAX"); _observer.observation_to_be_sent(); } else { tr_debug("M2MReportHandler::report()- no need to send"); } } handle_timers(); _last_value = _current_value; } void M2MReportHandler::handle_timers() { tr_debug("M2MReportHandler::handle_timers()"); uint64_t time_interval = 0; if ((_attribute_state & M2MReportHandler::Pmin) == M2MReportHandler::Pmin) { if (_pmin == _pmax) { _pmin_exceeded = true; } else { _pmin_exceeded = false; time_interval = (uint64_t)(_pmin * 1000); tr_debug("M2MReportHandler::handle_timers() - Start PMIN interval: %d", (int)time_interval); if (!_pmin_timer) { _pmin_timer = new M2MTimer(*this); } _pmin_timer->start_timer(time_interval, M2MTimerObserver::PMinTimer, true); } } if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax) { if (_pmax > 0) { if (!_pmax_timer) { _pmax_timer = new M2MTimer(*this); } time_interval = (uint64_t)(_pmax * 1000); tr_debug("M2MReportHandler::handle_timers() - Start PMAX interval: %d", (int)time_interval); _pmax_timer->start_timer(time_interval, M2MTimerObserver::PMaxTimer, true); } } } bool M2MReportHandler::check_attribute_validity() { bool success = true; if ((_attribute_state & M2MReportHandler::Pmax) == M2MReportHandler::Pmax && ((_pmax >= -1.0f) && (_pmin > _pmax))) { success = false; } float low = _lt + 2 * _st; if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt && (low >= _gt)) { success = false; } return success; } void M2MReportHandler::stop_timers() { tr_debug("M2MReportHandler::stop_timers()"); if (_pmin_timer) { _pmin_exceeded = false; _pmin_timer->stop_timer(); delete _pmin_timer; _pmin_timer = NULL; } if (_pmax_timer) { _pmax_exceeded = false; _pmax_timer->stop_timer(); delete _pmax_timer; _pmax_timer = NULL; } tr_debug("M2MReportHandler::stop_timers() - out"); } void M2MReportHandler::set_default_values() { tr_debug("M2MReportHandler::set_default_values"); _pmax = -1.0f; _pmin = 1.0f; _gt = 0.0f; _lt = 0.0f; _st = 0.0f; _high_step = 0.0f; _low_step = 0.0f; _pmin_exceeded = false; _pmax_exceeded = false; _last_value = 0.0f; _attribute_state = 0; } bool M2MReportHandler::check_threshold_values() { tr_debug("M2MReportHandler::check_threshold_values"); tr_debug("Current value: %f", _current_value); tr_debug("High step: %f", _high_step); tr_debug("Low step: %f", _low_step); tr_debug("Less than: %f", _lt); tr_debug("Greater than: %f", _gt); tr_debug("Step: %f", _st); bool can_send = false; // Check step condition if ((_attribute_state & M2MReportHandler::St) == M2MReportHandler::St) { if ((_current_value >= _high_step || _current_value <= _low_step)) { can_send = true; } else { if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt || (_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt ) { can_send = check_gt_lt_params(); } else { can_send = false; } } } else { can_send = check_gt_lt_params(); } tr_debug("M2MReportHandler::check_threshold_values - value in range = %d", (int)can_send); return can_send; } bool M2MReportHandler::check_gt_lt_params() { tr_debug("M2MReportHandler::check_gt_lt_params"); bool can_send = false; // GT & LT set. if ((_attribute_state & (M2MReportHandler::Lt | M2MReportHandler::Gt)) == (M2MReportHandler::Lt | M2MReportHandler::Gt)) { if (_current_value > _gt || _current_value < _lt) { can_send = true; } else { can_send = false; } } // Only LT else if ((_attribute_state & M2MReportHandler::Lt) == M2MReportHandler::Lt && (_attribute_state & M2MReportHandler::Gt) == 0 ) { if (_current_value < _lt) { can_send = true; } else { can_send = false; } } // Only GT else if ((_attribute_state & M2MReportHandler::Gt) == M2MReportHandler::Gt && (_attribute_state & M2MReportHandler::Lt) == 0 ) { if (_current_value > _gt) { can_send = true; } else { can_send = false; } } // GT & LT not set. else { can_send = true; } tr_debug("M2MReportHandler::check_gt_lt_params - value in range = %d", (int)can_send); return can_send; } uint8_t M2MReportHandler::attribute_flags() { return _attribute_state; }