Thinger.io Client Library for ARM mbed platform. This is a generic library that provides a base class that can be used to other develop hardware specific libraries.
Fork of ThingerClient by
Diff: thinger/thinger_resource.hpp
- Revision:
- 4:de51256455f7
- Parent:
- 0:b75d784c7c1a
diff -r 58e0153dbb37 -r de51256455f7 thinger/thinger_resource.hpp --- a/thinger/thinger_resource.hpp Fri Dec 25 18:21:02 2015 +0000 +++ b/thinger/thinger_resource.hpp Sat Dec 26 13:18:01 2015 +0000 @@ -1,275 +1,281 @@ -// The MIT License (MIT) -// -// Copyright (c) 2015 THINGER LTD -// Author: alvarolb@gmail.com (Alvaro Luis Bustamante) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef THINGER_RESOURCE_HPP -#define THINGER_RESOURCE_HPP - -#include "thinger_map.hpp" -#include "pson.h" -#include "thinger_message.hpp" - -namespace thinger{ - - -class thinger_resource { - -public: - enum io_type { - none = 0, - run = 1, - pson_in = 2, - pson_out = 3, - pson_in_pson_out = 4 - }; - - enum access_type{ - PRIVATE = 0, - PROTECTED = 1, - PUBLIC = 2, - NONE = 3 - }; - - static int get_streaming_counter(){ - return streaming_count_; - } - -private: - - // calback for function, input, output, or input/output - union callback{ - void (*run)(); - void (*pson_in)(protoson::pson& in); - void (*pson_out)(protoson::pson& out); - void (*pson_in_pson_out)(protoson::pson& in, protoson::pson& out); - }; - - // used for defining the resource - io_type io_type_; - access_type access_type_; - callback callback_; - - // used for allowing resource streaming (both periodically or by events) - uint16_t stream_id_; - - // used for periodic stream events - unsigned long streaming_freq_; - unsigned long last_streaming_; - - // used to know the total number of streams - static unsigned int streaming_count_; - - // TODO change to pointer so it is not using more than a pointer size if not used? - thinger_map<thinger_resource> sub_resources_; - - void enable_streaming(uint16_t stream_id, unsigned long streaming_freq){ - stream_id_ = stream_id; - streaming_freq_ = streaming_freq; - last_streaming_ = 0; - streaming_count_++; - } - -public: - thinger_resource() : io_type_(none), access_type_(PRIVATE), stream_id_(0), streaming_freq_(0), last_streaming_(0) - {} - - void disable_streaming(){ - stream_id_ = 0; - streaming_freq_ = 0; - streaming_count_--; - } - - bool stream_enabled(){ - return stream_id_ > 0; - } - - uint32_t get_stream_id(){ - return stream_id_; - } - - bool stream_required(unsigned long timestamp){ - // sample interval is activated - if(streaming_freq_>0){ - if(timestamp-last_streaming_>=streaming_freq_){ - last_streaming_ = timestamp; - return true; - } - } - return false; - } - - thinger_resource * find(const char* res) - { - return sub_resources_.find(res); - } - - thinger_resource & operator[](const char* res){ - return sub_resources_[res]; - } - - thinger_resource & operator()(access_type type){ - access_type_ = type; - return *this; - } - - io_type get_io_type(){ - return io_type_; - } - - access_type get_access_type(){ - return access_type_; - } - - void fill_api(protoson::pson_object& content){ - if(io_type_!=none){ - content["al"] = access_type_; - content["fn"] = io_type_; - } - thinger_map<thinger_resource>::entry* current = sub_resources_.begin(); - if(current!=NULL){ - protoson::pson_object& actions = content["/"]; - do{ - current->value_.fill_api(actions[current->key_]); - current = current->next_; - }while(current!=NULL); - } - } - - void fill_api_io(protoson::pson_object& content){ - if(io_type_ == pson_in){ - callback_.pson_in(content["in"]); - }else if(io_type_ == pson_out){ - callback_.pson_out(content["out"]); - }else if(io_type_ == pson_in_pson_out){ - callback_.pson_in_pson_out(content["in"], content["out"]); - } - } - -public: - - /** - * Establish a function without input or output parameters - */ - void operator=(void (*run_function)()){ - io_type_ = run; - callback_.run = run_function; - } - - /** - * Establish a function without input or output parameters - */ - void set_function(void (*run_function)()){ - io_type_ = run; - callback_.run = run_function; - } - - /** - * Establish a function with input parameters - */ - void operator<<(void (*in_function)(protoson::pson& in)){ - io_type_ = pson_in; - callback_.pson_in = in_function; - } - - /** - * Establish a function with input parameters - */ - void set_input(void (*in_function)(protoson::pson& in)){ - io_type_ = pson_in; - callback_.pson_in = in_function; - } - - /** - * Establish a function that only generates an output - */ - void operator>>(void (*out_function)(protoson::pson& out)){ - io_type_ = pson_out; - callback_.pson_out = out_function; - } - - /** - * Establish a function that only generates an output - */ - void set_output(void (*out_function)(protoson::pson& out)){ - io_type_ = pson_out; - callback_.pson_out = out_function; - } - - /** - * Establish a function that can receive input parameters and generate an output - */ - void operator=(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){ - io_type_ = pson_in_pson_out; - callback_.pson_in_pson_out = pson_in_pson_out_function; - } - - /** - * Establish a function that can receive input parameters and generate an output - */ - void set_input_output(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){ - io_type_ = pson_in_pson_out; - callback_.pson_in_pson_out = pson_in_pson_out_function; - } - - /** - * Handle a request and fill a possible response - */ - void handle_request(thinger_message& request, thinger_message& response){ - switch(request.get_signal_flag()){ - // default action over the stream (run the resource) - case thinger_message::NONE: - switch (io_type_){ - case run: - callback_.run(); - break; - case pson_in: - callback_.pson_in(request); - break; - case pson_out: - callback_.pson_out(response); - break; - case pson_in_pson_out: - callback_.pson_in_pson_out(request, response); - break; - case none: - break; - } - break; - // flag for starting a resource stream - case thinger_message::START_STREAM: - enable_streaming(request.get_stream_id(), request.get_data()); - break; - // flat for stopping a resource stream - case thinger_message::STOP_STREAM: - disable_streaming(); - break; - default: - break; - } - } -}; - - unsigned int thinger_resource::streaming_count_ = 0; - -} - -#endif +// The MIT License (MIT) +// +// Copyright (c) 2015 THINGER LTD +// Author: alvarolb@gmail.com (Alvaro Luis Bustamante) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef THINGER_RESOURCE_HPP +#define THINGER_RESOURCE_HPP + +#include "thinger_map.hpp" +#include "pson.h" +#include "thinger_message.hpp" + +namespace thinger{ + + + class thinger_resource { + + public: + enum io_type { + none = 0, + run = 1, + pson_in = 2, + pson_out = 3, + pson_in_pson_out = 4 + }; + + enum access_type{ + PRIVATE = 0, + PROTECTED = 1, + PUBLIC = 2, + NONE = 3 + }; + + static int get_streaming_counter(){ + return streaming_count_; + } + + private: + + // calback for function, input, output, or input/output + union callback{ + void (*run)(); + void (*pson_in)(protoson::pson& in); + void (*pson_out)(protoson::pson& out); + void (*pson_in_pson_out)(protoson::pson& in, protoson::pson& out); + }; + + // used for defining the resource + io_type io_type_; + access_type access_type_; + callback callback_; + + // used for allowing resource streaming (both periodically or by events) + uint16_t stream_id_; + + // used for periodic stream events + unsigned long streaming_freq_; + unsigned long last_streaming_; + + // used to know the total number of streams + static unsigned int streaming_count_; + + // TODO change to pointer so it is not using more than a pointer size if not used? + thinger_map<thinger_resource> sub_resources_; + + void enable_streaming(uint16_t stream_id, unsigned long streaming_freq){ + stream_id_ = stream_id; + if(streaming_freq_==0 && streaming_freq>0){ + streaming_count_++; + }else if(streaming_freq_>0 && streaming_freq==0){ + streaming_count_--; + } + streaming_freq_ = streaming_freq; + last_streaming_ = 0; + } + + public: + thinger_resource() : io_type_(none), access_type_(PRIVATE), stream_id_(0), streaming_freq_(0), last_streaming_(0) + {} + + void disable_streaming(){ + stream_id_ = 0; + if(streaming_freq_>0){ + streaming_count_--; + } + streaming_freq_ = 0; + } + + bool stream_enabled(){ + return stream_id_ > 0; + } + + uint32_t get_stream_id(){ + return stream_id_; + } + + bool stream_required(unsigned long timestamp){ + // sample interval is activated + if(streaming_freq_>0){ + if(timestamp-last_streaming_>=streaming_freq_){ + last_streaming_ = timestamp; + return true; + } + } + return false; + } + + thinger_resource * find(const char* res) + { + return sub_resources_.find(res); + } + + thinger_resource & operator[](const char* res){ + return sub_resources_[res]; + } + + thinger_resource & operator()(access_type type){ + access_type_ = type; + return *this; + } + + io_type get_io_type(){ + return io_type_; + } + + access_type get_access_type(){ + return access_type_; + } + + void fill_api(protoson::pson_object& content){ + if(io_type_!=none){ + content["al"] = access_type_; + content["fn"] = io_type_; + } + thinger_map<thinger_resource>::entry* current = sub_resources_.begin(); + if(current!=NULL){ + protoson::pson_object& actions = content["/"]; + do{ + current->value_.fill_api(actions[current->key_]); + current = current->next_; + }while(current!=NULL); + } + } + + void fill_api_io(protoson::pson_object& content){ + if(io_type_ == pson_in){ + callback_.pson_in(content["in"]); + }else if(io_type_ == pson_out){ + callback_.pson_out(content["out"]); + }else if(io_type_ == pson_in_pson_out){ + callback_.pson_in_pson_out(content["in"], content["out"]); + } + } + + public: + + /** + * Establish a function without input or output parameters + */ + void operator=(void (*run_function)()){ + io_type_ = run; + callback_.run = run_function; + } + + /** + * Establish a function without input or output parameters + */ + void set_function(void (*run_function)()){ + io_type_ = run; + callback_.run = run_function; + } + + /** + * Establish a function with input parameters + */ + void operator<<(void (*in_function)(protoson::pson& in)){ + io_type_ = pson_in; + callback_.pson_in = in_function; + } + + /** + * Establish a function with input parameters + */ + void set_input(void (*in_function)(protoson::pson& in)){ + io_type_ = pson_in; + callback_.pson_in = in_function; + } + + /** + * Establish a function that only generates an output + */ + void operator>>(void (*out_function)(protoson::pson& out)){ + io_type_ = pson_out; + callback_.pson_out = out_function; + } + + /** + * Establish a function that only generates an output + */ + void set_output(void (*out_function)(protoson::pson& out)){ + io_type_ = pson_out; + callback_.pson_out = out_function; + } + + /** + * Establish a function that can receive input parameters and generate an output + */ + void operator=(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){ + io_type_ = pson_in_pson_out; + callback_.pson_in_pson_out = pson_in_pson_out_function; + } + + /** + * Establish a function that can receive input parameters and generate an output + */ + void set_input_output(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){ + io_type_ = pson_in_pson_out; + callback_.pson_in_pson_out = pson_in_pson_out_function; + } + + /** + * Handle a request and fill a possible response + */ + void handle_request(thinger_message& request, thinger_message& response){ + switch(request.get_signal_flag()){ + // default action over the stream (run the resource) + case thinger_message::NONE: + switch (io_type_){ + case run: + callback_.run(); + break; + case pson_in: + callback_.pson_in(request); + break; + case pson_out: + callback_.pson_out(response); + break; + case pson_in_pson_out: + callback_.pson_in_pson_out(request, response); + break; + case none: + break; + } + break; + // flag for starting a resource stream + case thinger_message::START_STREAM: + enable_streaming(request.get_stream_id(), request.get_data()); + break; + // flat for stopping a resource stream + case thinger_message::STOP_STREAM: + disable_streaming(); + break; + default: + break; + } + } + }; + + unsigned int thinger_resource::streaming_count_ = 0; + +} + +#endif \ No newline at end of file