custom for >5 resources

Fork of mbedConnectorInterface by Doug Anson

Committer:
ansond
Date:
Tue Apr 14 13:44:41 2015 +0000
Revision:
53:458c2730e086
Parent:
52:822611156e35
Child:
54:6963bb4d0399
minor change to maxAge and cacheControl changes so that method calls are similar in form to others in DynamicResource...

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