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:
Sat Dec 26 13:18:01 2015 +0000
Revision:
4:de51256455f7
Parent:
0:b75d784c7c1a
Adapter pson to properly work in ARM Mbed old compiler

Who changed what in which revision?

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