custom for >5 resources

Fork of mbedConnectorInterface by Doug Anson

Committer:
michaeljkoster
Date:
Wed May 20 00:46:01 2015 +0000
Revision:
57:ef0fdadde9eb
Parent:
56:aaf84e56c422
10 resources

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:b438482ebbfc 1 /**
ansond 0:b438482ebbfc 2 * @file DynamicResource.cpp
ansond 0:b438482ebbfc 3 * @brief mbed CoAP Endpoint Dynamic Resource class
ansond 0:b438482ebbfc 4 * @author Doug Anson/Chris Paola
ansond 0:b438482ebbfc 5 * @version 1.0
sam_grove 2:853f9ecc12df 6 * @see
ansond 0:b438482ebbfc 7 *
ansond 0:b438482ebbfc 8 * Copyright (c) 2014
ansond 0:b438482ebbfc 9 *
ansond 0:b438482ebbfc 10 * Licensed under the Apache License, Version 2.0 (the "License");
ansond 0:b438482ebbfc 11 * you may not use this file except in compliance with the License.
ansond 0:b438482ebbfc 12 * You may obtain a copy of the License at
ansond 0:b438482ebbfc 13 *
ansond 0:b438482ebbfc 14 * http://www.apache.org/licenses/LICENSE-2.0
ansond 0:b438482ebbfc 15 *
ansond 0:b438482ebbfc 16 * Unless required by applicable law or agreed to in writing, software
ansond 0:b438482ebbfc 17 * distributed under the License is distributed on an "AS IS" BASIS,
ansond 0:b438482ebbfc 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ansond 0:b438482ebbfc 19 * See the License for the specific language governing permissions and
ansond 0:b438482ebbfc 20 * limitations under the License.
ansond 0:b438482ebbfc 21 */
sam_grove 2:853f9ecc12df 22
sam_grove 2:853f9ecc12df 23 #include "DynamicResource.h"
sam_grove 2:853f9ecc12df 24
sam_grove 2:853f9ecc12df 25 // InstancePointerTable Helper
sam_grove 2:853f9ecc12df 26 #include "InstancePointerTableHelper.h"
sam_grove 2:853f9ecc12df 27
ansond 31:bacc63106754 28 // ResourceObserver help
ansond 31:bacc63106754 29 #include "ResourceObserver.h"
ansond 31:bacc63106754 30
ansond 48:4b9ee3e32f93 31 // Options enablement
ansond 48:4b9ee3e32f93 32 #include "Options.h"
ansond 48:4b9ee3e32f93 33
ansond 54:6963bb4d0399 34 // GET option that can be used to Start/Stop Observations...
ansond 48:4b9ee3e32f93 35 #define START_OBS 0
ansond 48:4b9ee3e32f93 36 #define STOP_OBS 1
ansond 54:6963bb4d0399 37
ansond 54:6963bb4d0399 38 // MaxAge support for each DynamicResource
michaeljkoster 50:1a9e2184945e 39 #define DEFAULT_MAXAGE 60
ansond 54:6963bb4d0399 40
ansond 54:6963bb4d0399 41 // ContentFormat defaults for each DynamicResource
michaeljkoster 51:b308658817e5 42 #define DEFAULT_CONTENT_FORMAT 0
ansond 31:bacc63106754 43
sam_grove 2:853f9ecc12df 44 // default constructor
sam_grove 2:853f9ecc12df 45 DynamicResource::DynamicResource(const Logger *logger,const char *name,const char *res_type,uint8_t res_mask,const bool observable) : Resource<string>(logger,string(name),string(""))
sam_grove 2:853f9ecc12df 46 {
ansond 0:b438482ebbfc 47 this->m_res_type = string(res_type);
ansond 0:b438482ebbfc 48 this->m_observable = observable;
sam_grove 2:853f9ecc12df 49 this->m_res_mask = res_mask;
ansond 21:8487990a3baa 50 this->m_obs_number = 0;
ansond 21:8487990a3baa 51 this->m_obs_token_ptr = NULL;
ansond 21:8487990a3baa 52 this->m_obs_token_len = 0;
ansond 24:a6915e19814e 53 this->m_data_wrapper = NULL;
ansond 31:bacc63106754 54 this->m_observer = NULL;
michaeljkoster 51:b308658817e5 55 this->m_maxage = DEFAULT_MAXAGE;
michaeljkoster 51:b308658817e5 56 this->m_content_format = DEFAULT_CONTENT_FORMAT;
sam_grove 2:853f9ecc12df 57 }
sam_grove 2:853f9ecc12df 58
sam_grove 2:853f9ecc12df 59 // constructor (input initial value)
sam_grove 2:853f9ecc12df 60 DynamicResource::DynamicResource(const Logger *logger,const char *name,const char *res_type,const string value,uint8_t res_mask,const bool observable) : Resource<string>(logger,string(name),value)
sam_grove 2:853f9ecc12df 61 {
ansond 0:b438482ebbfc 62 this->m_res_type = string(res_type);
ansond 0:b438482ebbfc 63 this->m_observable = observable;
sam_grove 2:853f9ecc12df 64 this->m_res_mask = res_mask;
ansond 21:8487990a3baa 65 this->m_obs_number = 0;
ansond 21:8487990a3baa 66 this->m_obs_token_ptr = NULL;
ansond 21:8487990a3baa 67 this->m_obs_token_len = 0;
ansond 24:a6915e19814e 68 this->m_data_wrapper = NULL;
ansond 36:1c6c45584c13 69 this->m_observer = NULL;
michaeljkoster 50:1a9e2184945e 70 this->m_maxage = DEFAULT_MAXAGE;
michaeljkoster 51:b308658817e5 71 this->m_content_format = DEFAULT_CONTENT_FORMAT;
sam_grove 2:853f9ecc12df 72 }
sam_grove 2:853f9ecc12df 73
sam_grove 2:853f9ecc12df 74 // constructor (strings)
sam_grove 2:853f9ecc12df 75 DynamicResource::DynamicResource(const Logger *logger,const string name,const string res_type,const string value,uint8_t res_mask,const bool observable) : Resource<string>(logger,name,value)
sam_grove 2:853f9ecc12df 76 {
ansond 0:b438482ebbfc 77 this->m_res_type = res_type;
ansond 0:b438482ebbfc 78 this->m_observable = observable;
sam_grove 2:853f9ecc12df 79 this->m_res_mask = res_mask;
ansond 21:8487990a3baa 80 this->m_obs_number = 0;
ansond 21:8487990a3baa 81 this->m_obs_token_ptr = NULL;
ansond 21:8487990a3baa 82 this->m_obs_token_len = 0;
ansond 24:a6915e19814e 83 this->m_data_wrapper = NULL;
ansond 36:1c6c45584c13 84 this->m_observer = NULL;
michaeljkoster 50:1a9e2184945e 85 this->m_maxage = DEFAULT_MAXAGE;
michaeljkoster 51:b308658817e5 86 this->m_content_format = DEFAULT_CONTENT_FORMAT;
sam_grove 2:853f9ecc12df 87 }
sam_grove 2:853f9ecc12df 88
sam_grove 2:853f9ecc12df 89 // copy constructor
sam_grove 2:853f9ecc12df 90 DynamicResource::DynamicResource(const DynamicResource &resource) : Resource<string>((const Resource<string> &)resource)
sam_grove 2:853f9ecc12df 91 {
ansond 0:b438482ebbfc 92 this->m_res_type = resource.m_res_type;
ansond 0:b438482ebbfc 93 this->m_observable = resource.m_observable;
ansond 0:b438482ebbfc 94 this->m_res_mask = resource.m_res_mask;
ansond 21:8487990a3baa 95 this->m_obs_number = resource.m_obs_number;
ansond 21:8487990a3baa 96 this->m_obs_token_ptr = resource.m_obs_token_ptr;
ansond 21:8487990a3baa 97 this->m_obs_token_len = resource.m_obs_token_len;
ansond 24:a6915e19814e 98 this->m_data_wrapper = resource.m_data_wrapper;
ansond 36:1c6c45584c13 99 this->m_observer = resource.m_observer;
michaeljkoster 50:1a9e2184945e 100 this->m_maxage = resource.m_maxage;
michaeljkoster 51:b308658817e5 101 this->m_content_format = resource.m_content_format;
sam_grove 2:853f9ecc12df 102 }
sam_grove 2:853f9ecc12df 103
sam_grove 2:853f9ecc12df 104 // destructor
sam_grove 2:853f9ecc12df 105 DynamicResource::~DynamicResource()
sam_grove 2:853f9ecc12df 106 {
ansond 21:8487990a3baa 107 if(this->m_obs_token_ptr) free(this->m_obs_token_ptr);
sam_grove 2:853f9ecc12df 108 }
sam_grove 2:853f9ecc12df 109
sam_grove 2:853f9ecc12df 110 // bind resource to NSDL
sam_grove 2:853f9ecc12df 111 void DynamicResource::bind(void *p)
sam_grove 2:853f9ecc12df 112 {
ansond 0:b438482ebbfc 113 if (p != NULL) {
ansond 0:b438482ebbfc 114 sn_nsdl_resource_info_s *resource_ptr = (sn_nsdl_resource_info_s *)p;
ansond 0:b438482ebbfc 115 const uint8_t *name = (const uint8_t *)(this->getName().c_str());
ansond 0:b438482ebbfc 116 const uint8_t *res_type = (const uint8_t *)this->m_res_type.c_str();
ansond 0:b438482ebbfc 117 int name_length = this->getName().size();
ansond 0:b438482ebbfc 118 int res_type_length = this->m_res_type.size();
sam_grove 2:853f9ecc12df 119 int is_observable = 0;
sam_grove 2:853f9ecc12df 120 if (this->m_observable == true) is_observable = 1;
ansond 0:b438482ebbfc 121 const string *key = new string(this->getName());
ansond 0:b438482ebbfc 122 ipt_helper_add_instance_pointer(key,this);
ansond 0:b438482ebbfc 123 nsdl_create_dynamic_resource(resource_ptr,name_length,(uint8_t *)name,res_type_length,(uint8_t *)res_type,is_observable,&ipt_helper_nsdl_callback_stub,this->m_res_mask);
ansond 20:abfbaf524192 124 this->logger()->log("DynamicResource: [%s] type: [%s] bound (observable: %d)",name,res_type,is_observable);
sam_grove 2:853f9ecc12df 125 } else {
ansond 5:a929d65eb385 126 this->logger()->log("DynamicResource: NULL parameter in bind()");
ansond 0:b438482ebbfc 127 }
sam_grove 2:853f9ecc12df 128 }
ansond 0:b438482ebbfc 129
sam_grove 2:853f9ecc12df 130 // process NSDL message
sam_grove 2:853f9ecc12df 131 uint8_t DynamicResource::process(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s *proto)
sam_grove 2:853f9ecc12df 132 {
ansond 0:b438482ebbfc 133 sn_coap_hdr_s *coap_res_ptr = 0;
ansond 31:bacc63106754 134
ansond 0:b438482ebbfc 135 // create our key for debugging output...
ansond 25:1fc958ac14d1 136 DataWrapper *hold = this->getDataWrapper();
ansond 25:1fc958ac14d1 137 this->setDataWrapper(NULL);
ansond 0:b438482ebbfc 138 string key = this->coapDataToString(received_coap_ptr->uri_path_ptr,received_coap_ptr->uri_path_len);
ansond 25:1fc958ac14d1 139 this->setDataWrapper(hold);
sam_grove 2:853f9ecc12df 140
sam_grove 2:853f9ecc12df 141 if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) {
ansond 0:b438482ebbfc 142 coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT);
sam_grove 2:853f9ecc12df 143
sam_grove 2:853f9ecc12df 144 // process the GET if we have registered a callback for it...
ansond 0:b438482ebbfc 145 if ((this->m_res_mask&SN_GRS_GET_ALLOWED) != 0) {
ansond 0:b438482ebbfc 146 // call the resource get() to get the resource value
ansond 5:a929d65eb385 147 this->logger()->log("Calling resource(GET) for [%s]...",key.c_str());
ansond 0:b438482ebbfc 148 string value = this->get();
sam_grove 2:853f9ecc12df 149
ansond 24:a6915e19814e 150 // convert the string from the GET to something suitable for CoAP payloads
ansond 24:a6915e19814e 151 if (this->getDataWrapper() != NULL) {
ansond 24:a6915e19814e 152 // wrap the data...
ansond 24:a6915e19814e 153 this->getDataWrapper()->wrap((uint8_t *)value.c_str(),(int)value.size());
ansond 24:a6915e19814e 154
ansond 24:a6915e19814e 155 // announce (after wrap)
ansond 24:a6915e19814e 156 this->logger()->log("Building payload for [%s]=[%s]...",key.c_str(),this->getDataWrapper()->get());
ansond 24:a6915e19814e 157
ansond 24:a6915e19814e 158 // fill in the CoAP response payload
ansond 24:a6915e19814e 159 coap_res_ptr->payload_len = this->getDataWrapper()->length();
ansond 24:a6915e19814e 160 coap_res_ptr->payload_ptr = this->getDataWrapper()->get();
ansond 24:a6915e19814e 161 }
ansond 24:a6915e19814e 162 else {
ansond 24:a6915e19814e 163 // announce (no wrap)
ansond 24:a6915e19814e 164 this->logger()->log("Building payload for [%s]=[%s]...",key.c_str(),value.c_str());
ansond 24:a6915e19814e 165
ansond 24:a6915e19814e 166 // do not wrap the data...
ansond 24:a6915e19814e 167 coap_res_ptr->payload_len = value.size();
ansond 24:a6915e19814e 168 coap_res_ptr->payload_ptr = (uint8_t *)value.c_str();
ansond 24:a6915e19814e 169 }
ansond 21:8487990a3baa 170
michaeljkoster 51:b308658817e5 171 // CoAP Content-Format
ansond 54:6963bb4d0399 172 coap_res_ptr->content_type_ptr = &this->m_content_format;
michaeljkoster 51:b308658817e5 173 coap_res_ptr->content_type_len = sizeof(this->m_content_format);
michaeljkoster 51:b308658817e5 174
michaeljkoster 50:1a9e2184945e 175 // max-age cache control
michaeljkoster 50:1a9e2184945e 176 coap_res_ptr->options_list_ptr = (sn_coap_options_list_s*)nsdl_alloc(sizeof(sn_coap_options_list_s));
michaeljkoster 50:1a9e2184945e 177 if(!coap_res_ptr->options_list_ptr){
ansond 54:6963bb4d0399 178 this->logger()->log("Cant alloc options list");
michaeljkoster 50:1a9e2184945e 179 coap_res_ptr->options_list_ptr = NULL;
michaeljkoster 50:1a9e2184945e 180 }
michaeljkoster 50:1a9e2184945e 181 else{
michaeljkoster 50:1a9e2184945e 182 memset(coap_res_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
ansond 54:6963bb4d0399 183 coap_res_ptr->options_list_ptr->max_age_ptr = &this->m_maxage;
michaeljkoster 50:1a9e2184945e 184 coap_res_ptr->options_list_ptr->max_age_len = sizeof(this->m_maxage);
michaeljkoster 50:1a9e2184945e 185 }
michaeljkoster 50:1a9e2184945e 186
ansond 21:8487990a3baa 187 // Observation handling...
ansond 21:8487990a3baa 188 if(received_coap_ptr->token_ptr) {
ansond 21:8487990a3baa 189 if(this->m_obs_token_ptr) {
ansond 21:8487990a3baa 190 free(this->m_obs_token_ptr);
ansond 21:8487990a3baa 191 this->m_obs_token_ptr = NULL;
ansond 23:caa0260acc21 192 this->m_obs_token_len = 0;
ansond 21:8487990a3baa 193 }
ansond 22:192b598ba389 194
ansond 21:8487990a3baa 195 this->m_obs_token_ptr = (uint8_t*)malloc(received_coap_ptr->token_len);
ansond 21:8487990a3baa 196 if(this->m_obs_token_ptr) {
ansond 21:8487990a3baa 197 memcpy(this->m_obs_token_ptr, received_coap_ptr->token_ptr,received_coap_ptr->token_len);
ansond 21:8487990a3baa 198 this->m_obs_token_len = received_coap_ptr->token_len;
ansond 21:8487990a3baa 199 }
ansond 21:8487990a3baa 200 }
ansond 21:8487990a3baa 201
ansond 22:192b598ba389 202 // Observation handling...
ansond 36:1c6c45584c13 203 if(received_coap_ptr->options_list_ptr && received_coap_ptr->options_list_ptr->observe) {
ansond 31:bacc63106754 204 // create the options list pointer
ansond 21:8487990a3baa 205 coap_res_ptr->options_list_ptr = (sn_coap_options_list_s*)malloc(sizeof(sn_coap_options_list_s));
ansond 21:8487990a3baa 206 memset(coap_res_ptr->options_list_ptr, 0, sizeof(sn_coap_options_list_s));
ansond 36:1c6c45584c13 207
ansond 48:4b9ee3e32f93 208 // if GET controlled observation is enabled, perform it here...
ansond 48:4b9ee3e32f93 209 if (((Connector::Options *)this->getOptions())->enableGETObservationControl()) {
ansond 48:4b9ee3e32f93 210 // ResourceObserver
ansond 48:4b9ee3e32f93 211 ResourceObserver *observer = (ResourceObserver *)this->m_observer;
ansond 56:aaf84e56c422 212
ansond 56:aaf84e56c422 213 // I think we have to check for a NULl reference first... then process possibly..
ansond 56:aaf84e56c422 214 if (received_coap_ptr->options_list_ptr->observe_ptr != NULL) {
ansond 56:aaf84e56c422 215 // get observe start/stop value from received options list pointer
ansond 56:aaf84e56c422 216 uint8_t OBS_command = *received_coap_ptr->options_list_ptr->observe_ptr;
ansond 56:aaf84e56c422 217 if (OBS_command == START_OBS) {
ansond 56:aaf84e56c422 218 coap_res_ptr->options_list_ptr->observe_ptr = &this->m_obs_number; // see nullify note below...
ansond 56:aaf84e56c422 219 coap_res_ptr->options_list_ptr->observe_len = 1;
ansond 56:aaf84e56c422 220 this->m_obs_number++;
ansond 56:aaf84e56c422 221 if (observer != NULL) observer->beginObservation();
ansond 56:aaf84e56c422 222 }
ansond 56:aaf84e56c422 223 if (OBS_command == STOP_OBS) {
ansond 56:aaf84e56c422 224 if (observer != NULL) observer->stopObservation();
ansond 56:aaf84e56c422 225 }
ansond 56:aaf84e56c422 226 }
ansond 56:aaf84e56c422 227 else {
ansond 56:aaf84e56c422 228 // non-GET controlled observationing: simply fill in the observation requirements...
ansond 56:aaf84e56c422 229 coap_res_ptr->options_list_ptr->observe_ptr = &this->m_obs_number; // see nullify note below...
ansond 48:4b9ee3e32f93 230 coap_res_ptr->options_list_ptr->observe_len = 1;
ansond 48:4b9ee3e32f93 231 this->m_obs_number++;
ansond 48:4b9ee3e32f93 232 }
ansond 48:4b9ee3e32f93 233 }
ansond 48:4b9ee3e32f93 234 else {
ansond 48:4b9ee3e32f93 235 // non-GET controlled observationing: simply fill in the observation requirements...
ansond 48:4b9ee3e32f93 236 coap_res_ptr->options_list_ptr->observe_ptr = &this->m_obs_number; // see nullify note below...
ansond 31:bacc63106754 237 coap_res_ptr->options_list_ptr->observe_len = 1;
ansond 31:bacc63106754 238 this->m_obs_number++;
ansond 31:bacc63106754 239 }
ansond 21:8487990a3baa 240 }
sam_grove 2:853f9ecc12df 241
sam_grove 2:853f9ecc12df 242 // build out the response and send...
ansond 21:8487990a3baa 243 sn_nsdl_send_coap_message(address,coap_res_ptr);
ansond 54:6963bb4d0399 244
ansond 54:6963bb4d0399 245 // freeing up the options_list_ptr and clearing the content_type pointer
michaeljkoster 50:1a9e2184945e 246 nsdl_free(coap_res_ptr->options_list_ptr);
michaeljkoster 50:1a9e2184945e 247 coap_res_ptr->options_list_ptr = NULL;
michaeljkoster 51:b308658817e5 248 coap_res_ptr->content_type_ptr = NULL;
ansond 22:192b598ba389 249
ansond 22:192b598ba389 250 //
ansond 22:192b598ba389 251 // nullify note:
ansond 22:192b598ba389 252 //
ansond 22:192b598ba389 253 // because our obs_number (assigned to observe_ptr) is part of this object instance, we dont
ansond 22:192b598ba389 254 // want to have the underlying free() try to free it... to just nullify here
ansond 22:192b598ba389 255 //
ansond 54:6963bb4d0399 256 if (coap_res_ptr->options_list_ptr) coap_res_ptr->options_list_ptr->observe_ptr = 0;
ansond 21:8487990a3baa 257 }
ansond 21:8487990a3baa 258 else {
ansond 5:a929d65eb385 259 this->logger()->log("ERROR: resource(GET) mask is munged (mask: 0x%x)",this->m_res_mask);
ansond 0:b438482ebbfc 260 }
sam_grove 2:853f9ecc12df 261 } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) {
sam_grove 2:853f9ecc12df 262 if(received_coap_ptr->payload_len > 0) {
ansond 0:b438482ebbfc 263 // process the PUT if we have registered a callback for it...
ansond 0:b438482ebbfc 264 if ((this->m_res_mask&SN_GRS_PUT_ALLOWED) != 0) {
ansond 28:8fd9336edeb9 265 // put() delivers values as std::string
ansond 0:b438482ebbfc 266 string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len);
sam_grove 2:853f9ecc12df 267
ansond 0:b438482ebbfc 268 // call the resource put() to set the resource value
ansond 5:a929d65eb385 269 this->logger()->log("Calling resource(PUT) with [%s]=[%s]...",key.c_str(),value.c_str());
ansond 0:b438482ebbfc 270 this->put(value);
sam_grove 2:853f9ecc12df 271
ansond 0:b438482ebbfc 272 // build out the response and send...
ansond 5:a929d65eb385 273 this->logger()->log("resource(PUT) completed for [%s]...",key.c_str());
ansond 21:8487990a3baa 274 coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED);
ansond 21:8487990a3baa 275 sn_nsdl_send_coap_message(address,coap_res_ptr);
sam_grove 2:853f9ecc12df 276 } else {
ansond 5:a929d65eb385 277 this->logger()->log("ERROR: resource(PUT) mask is munged (mask: 0x%x)",this->m_res_mask);
ansond 0:b438482ebbfc 278 }
sam_grove 2:853f9ecc12df 279 } else {
ansond 5:a929d65eb385 280 this->logger()->log("ERROR: Binder(PUT) payload is NULL...");
ansond 0:b438482ebbfc 281 }
ansond 21:8487990a3baa 282 } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) {
ansond 21:8487990a3baa 283 if(received_coap_ptr->payload_len > 0) {
ansond 21:8487990a3baa 284 // process the POST if we have registered a callback for it...
ansond 21:8487990a3baa 285 if ((this->m_res_mask&SN_GRS_POST_ALLOWED) != 0) {
ansond 28:8fd9336edeb9 286 // post() delivers values as std::string
ansond 21:8487990a3baa 287 string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len);
ansond 21:8487990a3baa 288
ansond 21:8487990a3baa 289 // call the resource post() to set the resource value
ansond 21:8487990a3baa 290 this->logger()->log("Calling resource(POST) with [%s]=[%s]...",key.c_str(),value.c_str());
ansond 21:8487990a3baa 291 this->post(value);
ansond 21:8487990a3baa 292
ansond 21:8487990a3baa 293 // build out the response and send...
ansond 21:8487990a3baa 294 this->logger()->log("resource(POST) completed for [%s]...",key.c_str());
ansond 21:8487990a3baa 295 coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED);
ansond 21:8487990a3baa 296 sn_nsdl_send_coap_message(address,coap_res_ptr);
ansond 21:8487990a3baa 297 } else {
ansond 21:8487990a3baa 298 this->logger()->log("ERROR: resource(POST) mask is munged (mask: 0x%x)",this->m_res_mask);
ansond 21:8487990a3baa 299 }
ansond 21:8487990a3baa 300 } else {
ansond 21:8487990a3baa 301 this->logger()->log("ERROR: Binder(POST) payload is NULL...");
ansond 21:8487990a3baa 302 }
ansond 21:8487990a3baa 303 } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) {
ansond 21:8487990a3baa 304 if(received_coap_ptr->payload_len > 0) {
ansond 21:8487990a3baa 305 // process the DELETE if we have registered a callback for it...
ansond 21:8487990a3baa 306 if ((this->m_res_mask&SN_GRS_DELETE_ALLOWED) != 0) {
ansond 28:8fd9336edeb9 307 // del() delivers values as std::string
ansond 21:8487990a3baa 308 string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len);
ansond 21:8487990a3baa 309
ansond 21:8487990a3baa 310 // call the resource del() to set the resource value
ansond 21:8487990a3baa 311 this->logger()->log("Calling resource(DELETE) with [%s]=[%s]...",key.c_str(),value.c_str());
ansond 21:8487990a3baa 312 this->del(value);
ansond 21:8487990a3baa 313
ansond 21:8487990a3baa 314 // build out the response and send...
ansond 21:8487990a3baa 315 this->logger()->log("resource(DELETE) completed for [%s]...",key.c_str());
ansond 21:8487990a3baa 316 coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED);
ansond 21:8487990a3baa 317 sn_nsdl_send_coap_message(address,coap_res_ptr);
ansond 21:8487990a3baa 318 } else {
ansond 21:8487990a3baa 319 this->logger()->log("ERROR: resource(DELETE) mask is munged (mask: 0x%x)",this->m_res_mask);
ansond 21:8487990a3baa 320 }
ansond 21:8487990a3baa 321 } else {
ansond 21:8487990a3baa 322 this->logger()->log("ERROR: Binder(DELETE) payload is NULL...");
ansond 21:8487990a3baa 323 }
ansond 0:b438482ebbfc 324 }
ansond 0:b438482ebbfc 325
ansond 0:b438482ebbfc 326 sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr);
ansond 22:192b598ba389 327
ansond 0:b438482ebbfc 328 return 0;
sam_grove 2:853f9ecc12df 329 }
sam_grove 2:853f9ecc12df 330
ansond 21:8487990a3baa 331 // send the notification
ansond 21:8487990a3baa 332 int DynamicResource::notify(const string data) {
ansond 21:8487990a3baa 333 return this->notify((uint8_t *)data.c_str(),(int)data.length());
ansond 21:8487990a3baa 334 }
ansond 21:8487990a3baa 335
ansond 21:8487990a3baa 336 // send the notification
ansond 21:8487990a3baa 337 int DynamicResource::notify(uint8_t *data,int data_length) {
ansond 27:eb6818ad257a 338 uint8_t *notify_data = NULL;
ansond 27:eb6818ad257a 339 int notify_data_length = 0;
ansond 27:eb6818ad257a 340
ansond 27:eb6818ad257a 341 // convert the string from the GET to something suitable for CoAP payloads
ansond 27:eb6818ad257a 342 if (this->getDataWrapper() != NULL) {
ansond 27:eb6818ad257a 343 // wrap the data...
ansond 27:eb6818ad257a 344 this->getDataWrapper()->wrap((uint8_t *)data,data_length);
ansond 27:eb6818ad257a 345
ansond 27:eb6818ad257a 346 // announce (after wrap)
ansond 37:5de33aed0cac 347 //this->logger()->log("Notify payload [%s]...",this->getDataWrapper()->get());
ansond 27:eb6818ad257a 348
ansond 27:eb6818ad257a 349 // fill notify
ansond 27:eb6818ad257a 350 notify_data_length = this->getDataWrapper()->length();
ansond 27:eb6818ad257a 351 notify_data = this->getDataWrapper()->get();
ansond 27:eb6818ad257a 352 }
ansond 27:eb6818ad257a 353 else {
ansond 27:eb6818ad257a 354 // announce (no wrap)
ansond 37:5de33aed0cac 355 //this->logger()->log("Notify payload [%s]...",data);
ansond 27:eb6818ad257a 356
ansond 27:eb6818ad257a 357 // do not wrap the data...
ansond 27:eb6818ad257a 358 notify_data_length = data_length;
ansond 27:eb6818ad257a 359 notify_data = data;
ansond 27:eb6818ad257a 360 }
ansond 27:eb6818ad257a 361
ansond 27:eb6818ad257a 362 // send the observation...
ansond 27:eb6818ad257a 363 int status = sn_nsdl_send_observation_notification(this->m_obs_token_ptr,this->m_obs_token_len,notify_data,notify_data_length,&this->m_obs_number,1,COAP_MSG_TYPE_NON_CONFIRMABLE,0);
ansond 21:8487990a3baa 364 if (status == 0) {
ansond 21:8487990a3baa 365 this->logger()->log("ERROR: resource(NOTIFY) send failed...");
ansond 21:8487990a3baa 366 }
ansond 48:4b9ee3e32f93 367 else {
ansond 48:4b9ee3e32f93 368 ++(this->m_obs_number);
ansond 48:4b9ee3e32f93 369 }
ansond 27:eb6818ad257a 370
ansond 27:eb6818ad257a 371 // return our status
ansond 21:8487990a3baa 372 return status;
ansond 21:8487990a3baa 373 }
ansond 21:8487990a3baa 374
sam_grove 2:853f9ecc12df 375 // default PUT (does nothing)
sam_grove 2:853f9ecc12df 376 void DynamicResource::put(const string value)
sam_grove 2:853f9ecc12df 377 {
sam_grove 2:853f9ecc12df 378 // not used by default
sam_grove 2:853f9ecc12df 379 ;
sam_grove 2:853f9ecc12df 380 }
sam_grove 2:853f9ecc12df 381
ansond 21:8487990a3baa 382 // default POST (does nothing)
ansond 21:8487990a3baa 383 void DynamicResource::post(const string value)
ansond 21:8487990a3baa 384 {
ansond 21:8487990a3baa 385 // not used by default
ansond 21:8487990a3baa 386 ;
ansond 21:8487990a3baa 387 }
ansond 21:8487990a3baa 388
ansond 21:8487990a3baa 389 // default DELETE (does nothing)
ansond 21:8487990a3baa 390 void DynamicResource::del(const string value)
ansond 21:8487990a3baa 391 {
ansond 21:8487990a3baa 392 // not used by default
ansond 21:8487990a3baa 393 ;
ansond 21:8487990a3baa 394 }
ansond 21:8487990a3baa 395
ansond 30:113c2a1d8db2 396 // default observe behavior
ansond 30:113c2a1d8db2 397 void DynamicResource::observe() {
ansond 30:113c2a1d8db2 398 if (this->m_observable == true) {
ansond 30:113c2a1d8db2 399 this->notify(this->get());
ansond 30:113c2a1d8db2 400 }
ansond 30:113c2a1d8db2 401 }
ansond 30:113c2a1d8db2 402
ansond 31:bacc63106754 403 // set the observer pointer
ansond 31:bacc63106754 404 void DynamicResource::setObserver(void *observer) {
ansond 31:bacc63106754 405 this->m_observer = observer;
ansond 31:bacc63106754 406 }
ansond 31:bacc63106754 407
michaeljkoster 52:822611156e35 408 // set the content-format in responses
ansond 53:458c2730e086 409 void DynamicResource::setContentFormat(uint8_t content_format) {
michaeljkoster 52:822611156e35 410 this->m_content_format = content_format;
michaeljkoster 52:822611156e35 411 }
michaeljkoster 52:822611156e35 412
michaeljkoster 52:822611156e35 413 // set the max-age of responses
ansond 53:458c2730e086 414 void DynamicResource::setMaxAge(uint8_t maxage) {
michaeljkoster 52:822611156e35 415 this->m_maxage = maxage;
michaeljkoster 52:822611156e35 416 }
michaeljkoster 52:822611156e35 417
sam_grove 2:853f9ecc12df 418 // convenience method to get the URI from its buffer field...
sam_grove 2:853f9ecc12df 419 string DynamicResource::coapDataToString(uint8_t *coap_data_ptr,int coap_data_ptr_length)
sam_grove 2:853f9ecc12df 420 {
ansond 0:b438482ebbfc 421 if (coap_data_ptr != NULL && coap_data_ptr_length > 0) {
ansond 24:a6915e19814e 422 if (this->getDataWrapper() != NULL) {
ansond 24:a6915e19814e 423 // unwrap the data...
ansond 24:a6915e19814e 424 this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length);
ansond 24:a6915e19814e 425 char *buf = (char *)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper...
ansond 24:a6915e19814e 426 return string(buf);
ansond 24:a6915e19814e 427 }
ansond 24:a6915e19814e 428 else {
ansond 24:a6915e19814e 429 // no unwrap of the data...
ansond 24:a6915e19814e 430 char buf[MAX_VALUE_BUFFER_LENGTH+1];
ansond 24:a6915e19814e 431 memset(buf,0,MAX_VALUE_BUFFER_LENGTH+1);
ansond 24:a6915e19814e 432 memcpy(buf,(char *)coap_data_ptr,coap_data_ptr_length);
ansond 24:a6915e19814e 433 return string(buf);
ansond 24:a6915e19814e 434 }
ansond 0:b438482ebbfc 435 }
ansond 0:b438482ebbfc 436 return string("");
sam_grove 2:853f9ecc12df 437 }