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 Alvaro Luis Bustamante

Committer:
alvarolb
Date:
Thu Dec 24 13:18:08 2015 +0000
Revision:
0:b75d784c7c1a
Child:
4:de51256455f7
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
alvarolb 0:b75d784c7c1a 1 // The MIT License (MIT)
alvarolb 0:b75d784c7c1a 2 //
alvarolb 0:b75d784c7c1a 3 // Copyright (c) 2015 THINGER LTD
alvarolb 0:b75d784c7c1a 4 // Author: alvarolb@gmail.com (Alvaro Luis Bustamante)
alvarolb 0:b75d784c7c1a 5 //
alvarolb 0:b75d784c7c1a 6 // Permission is hereby granted, free of charge, to any person obtaining a copy
alvarolb 0:b75d784c7c1a 7 // of this software and associated documentation files (the "Software"), to deal
alvarolb 0:b75d784c7c1a 8 // in the Software without restriction, including without limitation the rights
alvarolb 0:b75d784c7c1a 9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
alvarolb 0:b75d784c7c1a 10 // copies of the Software, and to permit persons to whom the Software is
alvarolb 0:b75d784c7c1a 11 // furnished to do so, subject to the following conditions:
alvarolb 0:b75d784c7c1a 12 //
alvarolb 0:b75d784c7c1a 13 // The above copyright notice and this permission notice shall be included in
alvarolb 0:b75d784c7c1a 14 // all copies or substantial portions of the Software.
alvarolb 0:b75d784c7c1a 15 //
alvarolb 0:b75d784c7c1a 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
alvarolb 0:b75d784c7c1a 17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
alvarolb 0:b75d784c7c1a 18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
alvarolb 0:b75d784c7c1a 19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
alvarolb 0:b75d784c7c1a 20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
alvarolb 0:b75d784c7c1a 21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
alvarolb 0:b75d784c7c1a 22 // THE SOFTWARE.
alvarolb 0:b75d784c7c1a 23
alvarolb 0:b75d784c7c1a 24 #ifndef THINGER_RESOURCE_HPP
alvarolb 0:b75d784c7c1a 25 #define THINGER_RESOURCE_HPP
alvarolb 0:b75d784c7c1a 26
alvarolb 0:b75d784c7c1a 27 #include "thinger_map.hpp"
alvarolb 0:b75d784c7c1a 28 #include "pson.h"
alvarolb 0:b75d784c7c1a 29 #include "thinger_message.hpp"
alvarolb 0:b75d784c7c1a 30
alvarolb 0:b75d784c7c1a 31 namespace thinger{
alvarolb 0:b75d784c7c1a 32
alvarolb 0:b75d784c7c1a 33
alvarolb 0:b75d784c7c1a 34 class thinger_resource {
alvarolb 0:b75d784c7c1a 35
alvarolb 0:b75d784c7c1a 36 public:
alvarolb 0:b75d784c7c1a 37 enum io_type {
alvarolb 0:b75d784c7c1a 38 none = 0,
alvarolb 0:b75d784c7c1a 39 run = 1,
alvarolb 0:b75d784c7c1a 40 pson_in = 2,
alvarolb 0:b75d784c7c1a 41 pson_out = 3,
alvarolb 0:b75d784c7c1a 42 pson_in_pson_out = 4
alvarolb 0:b75d784c7c1a 43 };
alvarolb 0:b75d784c7c1a 44
alvarolb 0:b75d784c7c1a 45 enum access_type{
alvarolb 0:b75d784c7c1a 46 PRIVATE = 0,
alvarolb 0:b75d784c7c1a 47 PROTECTED = 1,
alvarolb 0:b75d784c7c1a 48 PUBLIC = 2,
alvarolb 0:b75d784c7c1a 49 NONE = 3
alvarolb 0:b75d784c7c1a 50 };
alvarolb 0:b75d784c7c1a 51
alvarolb 0:b75d784c7c1a 52 static int get_streaming_counter(){
alvarolb 0:b75d784c7c1a 53 return streaming_count_;
alvarolb 0:b75d784c7c1a 54 }
alvarolb 0:b75d784c7c1a 55
alvarolb 0:b75d784c7c1a 56 private:
alvarolb 0:b75d784c7c1a 57
alvarolb 0:b75d784c7c1a 58 // calback for function, input, output, or input/output
alvarolb 0:b75d784c7c1a 59 union callback{
alvarolb 0:b75d784c7c1a 60 void (*run)();
alvarolb 0:b75d784c7c1a 61 void (*pson_in)(protoson::pson& in);
alvarolb 0:b75d784c7c1a 62 void (*pson_out)(protoson::pson& out);
alvarolb 0:b75d784c7c1a 63 void (*pson_in_pson_out)(protoson::pson& in, protoson::pson& out);
alvarolb 0:b75d784c7c1a 64 };
alvarolb 0:b75d784c7c1a 65
alvarolb 0:b75d784c7c1a 66 // used for defining the resource
alvarolb 0:b75d784c7c1a 67 io_type io_type_;
alvarolb 0:b75d784c7c1a 68 access_type access_type_;
alvarolb 0:b75d784c7c1a 69 callback callback_;
alvarolb 0:b75d784c7c1a 70
alvarolb 0:b75d784c7c1a 71 // used for allowing resource streaming (both periodically or by events)
alvarolb 0:b75d784c7c1a 72 uint16_t stream_id_;
alvarolb 0:b75d784c7c1a 73
alvarolb 0:b75d784c7c1a 74 // used for periodic stream events
alvarolb 0:b75d784c7c1a 75 unsigned long streaming_freq_;
alvarolb 0:b75d784c7c1a 76 unsigned long last_streaming_;
alvarolb 0:b75d784c7c1a 77
alvarolb 0:b75d784c7c1a 78 // used to know the total number of streams
alvarolb 0:b75d784c7c1a 79 static unsigned int streaming_count_;
alvarolb 0:b75d784c7c1a 80
alvarolb 0:b75d784c7c1a 81 // TODO change to pointer so it is not using more than a pointer size if not used?
alvarolb 0:b75d784c7c1a 82 thinger_map<thinger_resource> sub_resources_;
alvarolb 0:b75d784c7c1a 83
alvarolb 0:b75d784c7c1a 84 void enable_streaming(uint16_t stream_id, unsigned long streaming_freq){
alvarolb 0:b75d784c7c1a 85 stream_id_ = stream_id;
alvarolb 0:b75d784c7c1a 86 streaming_freq_ = streaming_freq;
alvarolb 0:b75d784c7c1a 87 last_streaming_ = 0;
alvarolb 0:b75d784c7c1a 88 streaming_count_++;
alvarolb 0:b75d784c7c1a 89 }
alvarolb 0:b75d784c7c1a 90
alvarolb 0:b75d784c7c1a 91 public:
alvarolb 0:b75d784c7c1a 92 thinger_resource() : io_type_(none), access_type_(PRIVATE), stream_id_(0), streaming_freq_(0), last_streaming_(0)
alvarolb 0:b75d784c7c1a 93 {}
alvarolb 0:b75d784c7c1a 94
alvarolb 0:b75d784c7c1a 95 void disable_streaming(){
alvarolb 0:b75d784c7c1a 96 stream_id_ = 0;
alvarolb 0:b75d784c7c1a 97 streaming_freq_ = 0;
alvarolb 0:b75d784c7c1a 98 streaming_count_--;
alvarolb 0:b75d784c7c1a 99 }
alvarolb 0:b75d784c7c1a 100
alvarolb 0:b75d784c7c1a 101 bool stream_enabled(){
alvarolb 0:b75d784c7c1a 102 return stream_id_ > 0;
alvarolb 0:b75d784c7c1a 103 }
alvarolb 0:b75d784c7c1a 104
alvarolb 0:b75d784c7c1a 105 uint32_t get_stream_id(){
alvarolb 0:b75d784c7c1a 106 return stream_id_;
alvarolb 0:b75d784c7c1a 107 }
alvarolb 0:b75d784c7c1a 108
alvarolb 0:b75d784c7c1a 109 bool stream_required(unsigned long timestamp){
alvarolb 0:b75d784c7c1a 110 // sample interval is activated
alvarolb 0:b75d784c7c1a 111 if(streaming_freq_>0){
alvarolb 0:b75d784c7c1a 112 if(timestamp-last_streaming_>=streaming_freq_){
alvarolb 0:b75d784c7c1a 113 last_streaming_ = timestamp;
alvarolb 0:b75d784c7c1a 114 return true;
alvarolb 0:b75d784c7c1a 115 }
alvarolb 0:b75d784c7c1a 116 }
alvarolb 0:b75d784c7c1a 117 return false;
alvarolb 0:b75d784c7c1a 118 }
alvarolb 0:b75d784c7c1a 119
alvarolb 0:b75d784c7c1a 120 thinger_resource * find(const char* res)
alvarolb 0:b75d784c7c1a 121 {
alvarolb 0:b75d784c7c1a 122 return sub_resources_.find(res);
alvarolb 0:b75d784c7c1a 123 }
alvarolb 0:b75d784c7c1a 124
alvarolb 0:b75d784c7c1a 125 thinger_resource & operator[](const char* res){
alvarolb 0:b75d784c7c1a 126 return sub_resources_[res];
alvarolb 0:b75d784c7c1a 127 }
alvarolb 0:b75d784c7c1a 128
alvarolb 0:b75d784c7c1a 129 thinger_resource & operator()(access_type type){
alvarolb 0:b75d784c7c1a 130 access_type_ = type;
alvarolb 0:b75d784c7c1a 131 return *this;
alvarolb 0:b75d784c7c1a 132 }
alvarolb 0:b75d784c7c1a 133
alvarolb 0:b75d784c7c1a 134 io_type get_io_type(){
alvarolb 0:b75d784c7c1a 135 return io_type_;
alvarolb 0:b75d784c7c1a 136 }
alvarolb 0:b75d784c7c1a 137
alvarolb 0:b75d784c7c1a 138 access_type get_access_type(){
alvarolb 0:b75d784c7c1a 139 return access_type_;
alvarolb 0:b75d784c7c1a 140 }
alvarolb 0:b75d784c7c1a 141
alvarolb 0:b75d784c7c1a 142 void fill_api(protoson::pson_object& content){
alvarolb 0:b75d784c7c1a 143 if(io_type_!=none){
alvarolb 0:b75d784c7c1a 144 content["al"] = access_type_;
alvarolb 0:b75d784c7c1a 145 content["fn"] = io_type_;
alvarolb 0:b75d784c7c1a 146 }
alvarolb 0:b75d784c7c1a 147 thinger_map<thinger_resource>::entry* current = sub_resources_.begin();
alvarolb 0:b75d784c7c1a 148 if(current!=NULL){
alvarolb 0:b75d784c7c1a 149 protoson::pson_object& actions = content["/"];
alvarolb 0:b75d784c7c1a 150 do{
alvarolb 0:b75d784c7c1a 151 current->value_.fill_api(actions[current->key_]);
alvarolb 0:b75d784c7c1a 152 current = current->next_;
alvarolb 0:b75d784c7c1a 153 }while(current!=NULL);
alvarolb 0:b75d784c7c1a 154 }
alvarolb 0:b75d784c7c1a 155 }
alvarolb 0:b75d784c7c1a 156
alvarolb 0:b75d784c7c1a 157 void fill_api_io(protoson::pson_object& content){
alvarolb 0:b75d784c7c1a 158 if(io_type_ == pson_in){
alvarolb 0:b75d784c7c1a 159 callback_.pson_in(content["in"]);
alvarolb 0:b75d784c7c1a 160 }else if(io_type_ == pson_out){
alvarolb 0:b75d784c7c1a 161 callback_.pson_out(content["out"]);
alvarolb 0:b75d784c7c1a 162 }else if(io_type_ == pson_in_pson_out){
alvarolb 0:b75d784c7c1a 163 callback_.pson_in_pson_out(content["in"], content["out"]);
alvarolb 0:b75d784c7c1a 164 }
alvarolb 0:b75d784c7c1a 165 }
alvarolb 0:b75d784c7c1a 166
alvarolb 0:b75d784c7c1a 167 public:
alvarolb 0:b75d784c7c1a 168
alvarolb 0:b75d784c7c1a 169 /**
alvarolb 0:b75d784c7c1a 170 * Establish a function without input or output parameters
alvarolb 0:b75d784c7c1a 171 */
alvarolb 0:b75d784c7c1a 172 void operator=(void (*run_function)()){
alvarolb 0:b75d784c7c1a 173 io_type_ = run;
alvarolb 0:b75d784c7c1a 174 callback_.run = run_function;
alvarolb 0:b75d784c7c1a 175 }
alvarolb 0:b75d784c7c1a 176
alvarolb 0:b75d784c7c1a 177 /**
alvarolb 0:b75d784c7c1a 178 * Establish a function without input or output parameters
alvarolb 0:b75d784c7c1a 179 */
alvarolb 0:b75d784c7c1a 180 void set_function(void (*run_function)()){
alvarolb 0:b75d784c7c1a 181 io_type_ = run;
alvarolb 0:b75d784c7c1a 182 callback_.run = run_function;
alvarolb 0:b75d784c7c1a 183 }
alvarolb 0:b75d784c7c1a 184
alvarolb 0:b75d784c7c1a 185 /**
alvarolb 0:b75d784c7c1a 186 * Establish a function with input parameters
alvarolb 0:b75d784c7c1a 187 */
alvarolb 0:b75d784c7c1a 188 void operator<<(void (*in_function)(protoson::pson& in)){
alvarolb 0:b75d784c7c1a 189 io_type_ = pson_in;
alvarolb 0:b75d784c7c1a 190 callback_.pson_in = in_function;
alvarolb 0:b75d784c7c1a 191 }
alvarolb 0:b75d784c7c1a 192
alvarolb 0:b75d784c7c1a 193 /**
alvarolb 0:b75d784c7c1a 194 * Establish a function with input parameters
alvarolb 0:b75d784c7c1a 195 */
alvarolb 0:b75d784c7c1a 196 void set_input(void (*in_function)(protoson::pson& in)){
alvarolb 0:b75d784c7c1a 197 io_type_ = pson_in;
alvarolb 0:b75d784c7c1a 198 callback_.pson_in = in_function;
alvarolb 0:b75d784c7c1a 199 }
alvarolb 0:b75d784c7c1a 200
alvarolb 0:b75d784c7c1a 201 /**
alvarolb 0:b75d784c7c1a 202 * Establish a function that only generates an output
alvarolb 0:b75d784c7c1a 203 */
alvarolb 0:b75d784c7c1a 204 void operator>>(void (*out_function)(protoson::pson& out)){
alvarolb 0:b75d784c7c1a 205 io_type_ = pson_out;
alvarolb 0:b75d784c7c1a 206 callback_.pson_out = out_function;
alvarolb 0:b75d784c7c1a 207 }
alvarolb 0:b75d784c7c1a 208
alvarolb 0:b75d784c7c1a 209 /**
alvarolb 0:b75d784c7c1a 210 * Establish a function that only generates an output
alvarolb 0:b75d784c7c1a 211 */
alvarolb 0:b75d784c7c1a 212 void set_output(void (*out_function)(protoson::pson& out)){
alvarolb 0:b75d784c7c1a 213 io_type_ = pson_out;
alvarolb 0:b75d784c7c1a 214 callback_.pson_out = out_function;
alvarolb 0:b75d784c7c1a 215 }
alvarolb 0:b75d784c7c1a 216
alvarolb 0:b75d784c7c1a 217 /**
alvarolb 0:b75d784c7c1a 218 * Establish a function that can receive input parameters and generate an output
alvarolb 0:b75d784c7c1a 219 */
alvarolb 0:b75d784c7c1a 220 void operator=(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){
alvarolb 0:b75d784c7c1a 221 io_type_ = pson_in_pson_out;
alvarolb 0:b75d784c7c1a 222 callback_.pson_in_pson_out = pson_in_pson_out_function;
alvarolb 0:b75d784c7c1a 223 }
alvarolb 0:b75d784c7c1a 224
alvarolb 0:b75d784c7c1a 225 /**
alvarolb 0:b75d784c7c1a 226 * Establish a function that can receive input parameters and generate an output
alvarolb 0:b75d784c7c1a 227 */
alvarolb 0:b75d784c7c1a 228 void set_input_output(void (*pson_in_pson_out_function)(protoson::pson& in, protoson::pson& out)){
alvarolb 0:b75d784c7c1a 229 io_type_ = pson_in_pson_out;
alvarolb 0:b75d784c7c1a 230 callback_.pson_in_pson_out = pson_in_pson_out_function;
alvarolb 0:b75d784c7c1a 231 }
alvarolb 0:b75d784c7c1a 232
alvarolb 0:b75d784c7c1a 233 /**
alvarolb 0:b75d784c7c1a 234 * Handle a request and fill a possible response
alvarolb 0:b75d784c7c1a 235 */
alvarolb 0:b75d784c7c1a 236 void handle_request(thinger_message& request, thinger_message& response){
alvarolb 0:b75d784c7c1a 237 switch(request.get_signal_flag()){
alvarolb 0:b75d784c7c1a 238 // default action over the stream (run the resource)
alvarolb 0:b75d784c7c1a 239 case thinger_message::NONE:
alvarolb 0:b75d784c7c1a 240 switch (io_type_){
alvarolb 0:b75d784c7c1a 241 case run:
alvarolb 0:b75d784c7c1a 242 callback_.run();
alvarolb 0:b75d784c7c1a 243 break;
alvarolb 0:b75d784c7c1a 244 case pson_in:
alvarolb 0:b75d784c7c1a 245 callback_.pson_in(request);
alvarolb 0:b75d784c7c1a 246 break;
alvarolb 0:b75d784c7c1a 247 case pson_out:
alvarolb 0:b75d784c7c1a 248 callback_.pson_out(response);
alvarolb 0:b75d784c7c1a 249 break;
alvarolb 0:b75d784c7c1a 250 case pson_in_pson_out:
alvarolb 0:b75d784c7c1a 251 callback_.pson_in_pson_out(request, response);
alvarolb 0:b75d784c7c1a 252 break;
alvarolb 0:b75d784c7c1a 253 case none:
alvarolb 0:b75d784c7c1a 254 break;
alvarolb 0:b75d784c7c1a 255 }
alvarolb 0:b75d784c7c1a 256 break;
alvarolb 0:b75d784c7c1a 257 // flag for starting a resource stream
alvarolb 0:b75d784c7c1a 258 case thinger_message::START_STREAM:
alvarolb 0:b75d784c7c1a 259 enable_streaming(request.get_stream_id(), request.get_data());
alvarolb 0:b75d784c7c1a 260 break;
alvarolb 0:b75d784c7c1a 261 // flat for stopping a resource stream
alvarolb 0:b75d784c7c1a 262 case thinger_message::STOP_STREAM:
alvarolb 0:b75d784c7c1a 263 disable_streaming();
alvarolb 0:b75d784c7c1a 264 break;
alvarolb 0:b75d784c7c1a 265 default:
alvarolb 0:b75d784c7c1a 266 break;
alvarolb 0:b75d784c7c1a 267 }
alvarolb 0:b75d784c7c1a 268 }
alvarolb 0:b75d784c7c1a 269 };
alvarolb 0:b75d784c7c1a 270
alvarolb 0:b75d784c7c1a 271 unsigned int thinger_resource::streaming_count_ = 0;
alvarolb 0:b75d784c7c1a 272
alvarolb 0:b75d784c7c1a 273 }
alvarolb 0:b75d784c7c1a 274
alvarolb 0:b75d784c7c1a 275 #endif