custom for >5 resources
Fork of mbedConnectorInterface by
api/DynamicResource.cpp@54:6963bb4d0399, 2015-04-14 (annotated)
- Committer:
- ansond
- Date:
- Tue Apr 14 13:54:41 2015 +0000
- Revision:
- 54:6963bb4d0399
- Parent:
- 53:458c2730e086
- Child:
- 56:aaf84e56c422
minor cleanups and additions of comments for max_age and content_type in the code
Who changed what in which revision?
User | Revision | Line number | New 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 | 48:4b9ee3e32f93 | 212 | |
ansond | 48:4b9ee3e32f93 | 213 | // get observe start/stop value from received options list pointer |
ansond | 48:4b9ee3e32f93 | 214 | uint8_t OBS_command = *received_coap_ptr->options_list_ptr->observe_ptr; |
ansond | 48:4b9ee3e32f93 | 215 | if (OBS_command == START_OBS) { |
ansond | 48:4b9ee3e32f93 | 216 | coap_res_ptr->options_list_ptr->observe_ptr = &this->m_obs_number; // see nullify note below... |
ansond | 48:4b9ee3e32f93 | 217 | coap_res_ptr->options_list_ptr->observe_len = 1; |
ansond | 48:4b9ee3e32f93 | 218 | this->m_obs_number++; |
ansond | 48:4b9ee3e32f93 | 219 | if (observer != NULL) observer->beginObservation(); |
ansond | 48:4b9ee3e32f93 | 220 | } |
ansond | 48:4b9ee3e32f93 | 221 | if (OBS_command == STOP_OBS) { |
ansond | 48:4b9ee3e32f93 | 222 | if (observer != NULL) observer->stopObservation(); |
ansond | 48:4b9ee3e32f93 | 223 | } |
ansond | 48:4b9ee3e32f93 | 224 | } |
ansond | 48:4b9ee3e32f93 | 225 | else { |
ansond | 48:4b9ee3e32f93 | 226 | // non-GET controlled observationing: simply fill in the observation requirements... |
ansond | 48:4b9ee3e32f93 | 227 | coap_res_ptr->options_list_ptr->observe_ptr = &this->m_obs_number; // see nullify note below... |
ansond | 31:bacc63106754 | 228 | coap_res_ptr->options_list_ptr->observe_len = 1; |
ansond | 31:bacc63106754 | 229 | this->m_obs_number++; |
ansond | 31:bacc63106754 | 230 | } |
ansond | 21:8487990a3baa | 231 | } |
sam_grove | 2:853f9ecc12df | 232 | |
sam_grove | 2:853f9ecc12df | 233 | // build out the response and send... |
ansond | 21:8487990a3baa | 234 | sn_nsdl_send_coap_message(address,coap_res_ptr); |
ansond | 54:6963bb4d0399 | 235 | |
ansond | 54:6963bb4d0399 | 236 | // freeing up the options_list_ptr and clearing the content_type pointer |
michaeljkoster | 50:1a9e2184945e | 237 | nsdl_free(coap_res_ptr->options_list_ptr); |
michaeljkoster | 50:1a9e2184945e | 238 | coap_res_ptr->options_list_ptr = NULL; |
michaeljkoster | 51:b308658817e5 | 239 | coap_res_ptr->content_type_ptr = NULL; |
ansond | 22:192b598ba389 | 240 | |
ansond | 22:192b598ba389 | 241 | // |
ansond | 22:192b598ba389 | 242 | // nullify note: |
ansond | 22:192b598ba389 | 243 | // |
ansond | 22:192b598ba389 | 244 | // because our obs_number (assigned to observe_ptr) is part of this object instance, we dont |
ansond | 22:192b598ba389 | 245 | // want to have the underlying free() try to free it... to just nullify here |
ansond | 22:192b598ba389 | 246 | // |
ansond | 54:6963bb4d0399 | 247 | if (coap_res_ptr->options_list_ptr) coap_res_ptr->options_list_ptr->observe_ptr = 0; |
ansond | 21:8487990a3baa | 248 | } |
ansond | 21:8487990a3baa | 249 | else { |
ansond | 5:a929d65eb385 | 250 | this->logger()->log("ERROR: resource(GET) mask is munged (mask: 0x%x)",this->m_res_mask); |
ansond | 0:b438482ebbfc | 251 | } |
sam_grove | 2:853f9ecc12df | 252 | } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) { |
sam_grove | 2:853f9ecc12df | 253 | if(received_coap_ptr->payload_len > 0) { |
ansond | 0:b438482ebbfc | 254 | // process the PUT if we have registered a callback for it... |
ansond | 0:b438482ebbfc | 255 | if ((this->m_res_mask&SN_GRS_PUT_ALLOWED) != 0) { |
ansond | 28:8fd9336edeb9 | 256 | // put() delivers values as std::string |
ansond | 0:b438482ebbfc | 257 | string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len); |
sam_grove | 2:853f9ecc12df | 258 | |
ansond | 0:b438482ebbfc | 259 | // call the resource put() to set the resource value |
ansond | 5:a929d65eb385 | 260 | this->logger()->log("Calling resource(PUT) with [%s]=[%s]...",key.c_str(),value.c_str()); |
ansond | 0:b438482ebbfc | 261 | this->put(value); |
sam_grove | 2:853f9ecc12df | 262 | |
ansond | 0:b438482ebbfc | 263 | // build out the response and send... |
ansond | 5:a929d65eb385 | 264 | this->logger()->log("resource(PUT) completed for [%s]...",key.c_str()); |
ansond | 21:8487990a3baa | 265 | coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED); |
ansond | 21:8487990a3baa | 266 | sn_nsdl_send_coap_message(address,coap_res_ptr); |
sam_grove | 2:853f9ecc12df | 267 | } else { |
ansond | 5:a929d65eb385 | 268 | this->logger()->log("ERROR: resource(PUT) mask is munged (mask: 0x%x)",this->m_res_mask); |
ansond | 0:b438482ebbfc | 269 | } |
sam_grove | 2:853f9ecc12df | 270 | } else { |
ansond | 5:a929d65eb385 | 271 | this->logger()->log("ERROR: Binder(PUT) payload is NULL..."); |
ansond | 0:b438482ebbfc | 272 | } |
ansond | 21:8487990a3baa | 273 | } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_POST) { |
ansond | 21:8487990a3baa | 274 | if(received_coap_ptr->payload_len > 0) { |
ansond | 21:8487990a3baa | 275 | // process the POST if we have registered a callback for it... |
ansond | 21:8487990a3baa | 276 | if ((this->m_res_mask&SN_GRS_POST_ALLOWED) != 0) { |
ansond | 28:8fd9336edeb9 | 277 | // post() delivers values as std::string |
ansond | 21:8487990a3baa | 278 | string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len); |
ansond | 21:8487990a3baa | 279 | |
ansond | 21:8487990a3baa | 280 | // call the resource post() to set the resource value |
ansond | 21:8487990a3baa | 281 | this->logger()->log("Calling resource(POST) with [%s]=[%s]...",key.c_str(),value.c_str()); |
ansond | 21:8487990a3baa | 282 | this->post(value); |
ansond | 21:8487990a3baa | 283 | |
ansond | 21:8487990a3baa | 284 | // build out the response and send... |
ansond | 21:8487990a3baa | 285 | this->logger()->log("resource(POST) completed for [%s]...",key.c_str()); |
ansond | 21:8487990a3baa | 286 | coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED); |
ansond | 21:8487990a3baa | 287 | sn_nsdl_send_coap_message(address,coap_res_ptr); |
ansond | 21:8487990a3baa | 288 | } else { |
ansond | 21:8487990a3baa | 289 | this->logger()->log("ERROR: resource(POST) mask is munged (mask: 0x%x)",this->m_res_mask); |
ansond | 21:8487990a3baa | 290 | } |
ansond | 21:8487990a3baa | 291 | } else { |
ansond | 21:8487990a3baa | 292 | this->logger()->log("ERROR: Binder(POST) payload is NULL..."); |
ansond | 21:8487990a3baa | 293 | } |
ansond | 21:8487990a3baa | 294 | } else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_DELETE) { |
ansond | 21:8487990a3baa | 295 | if(received_coap_ptr->payload_len > 0) { |
ansond | 21:8487990a3baa | 296 | // process the DELETE if we have registered a callback for it... |
ansond | 21:8487990a3baa | 297 | if ((this->m_res_mask&SN_GRS_DELETE_ALLOWED) != 0) { |
ansond | 28:8fd9336edeb9 | 298 | // del() delivers values as std::string |
ansond | 21:8487990a3baa | 299 | string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len); |
ansond | 21:8487990a3baa | 300 | |
ansond | 21:8487990a3baa | 301 | // call the resource del() to set the resource value |
ansond | 21:8487990a3baa | 302 | this->logger()->log("Calling resource(DELETE) with [%s]=[%s]...",key.c_str(),value.c_str()); |
ansond | 21:8487990a3baa | 303 | this->del(value); |
ansond | 21:8487990a3baa | 304 | |
ansond | 21:8487990a3baa | 305 | // build out the response and send... |
ansond | 21:8487990a3baa | 306 | this->logger()->log("resource(DELETE) completed for [%s]...",key.c_str()); |
ansond | 21:8487990a3baa | 307 | coap_res_ptr = sn_coap_build_response(received_coap_ptr,COAP_MSG_CODE_RESPONSE_CHANGED); |
ansond | 21:8487990a3baa | 308 | sn_nsdl_send_coap_message(address,coap_res_ptr); |
ansond | 21:8487990a3baa | 309 | } else { |
ansond | 21:8487990a3baa | 310 | this->logger()->log("ERROR: resource(DELETE) mask is munged (mask: 0x%x)",this->m_res_mask); |
ansond | 21:8487990a3baa | 311 | } |
ansond | 21:8487990a3baa | 312 | } else { |
ansond | 21:8487990a3baa | 313 | this->logger()->log("ERROR: Binder(DELETE) payload is NULL..."); |
ansond | 21:8487990a3baa | 314 | } |
ansond | 0:b438482ebbfc | 315 | } |
ansond | 0:b438482ebbfc | 316 | |
ansond | 0:b438482ebbfc | 317 | sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr); |
ansond | 22:192b598ba389 | 318 | |
ansond | 0:b438482ebbfc | 319 | return 0; |
sam_grove | 2:853f9ecc12df | 320 | } |
sam_grove | 2:853f9ecc12df | 321 | |
ansond | 21:8487990a3baa | 322 | // send the notification |
ansond | 21:8487990a3baa | 323 | int DynamicResource::notify(const string data) { |
ansond | 21:8487990a3baa | 324 | return this->notify((uint8_t *)data.c_str(),(int)data.length()); |
ansond | 21:8487990a3baa | 325 | } |
ansond | 21:8487990a3baa | 326 | |
ansond | 21:8487990a3baa | 327 | // send the notification |
ansond | 21:8487990a3baa | 328 | int DynamicResource::notify(uint8_t *data,int data_length) { |
ansond | 27:eb6818ad257a | 329 | uint8_t *notify_data = NULL; |
ansond | 27:eb6818ad257a | 330 | int notify_data_length = 0; |
ansond | 27:eb6818ad257a | 331 | |
ansond | 27:eb6818ad257a | 332 | // convert the string from the GET to something suitable for CoAP payloads |
ansond | 27:eb6818ad257a | 333 | if (this->getDataWrapper() != NULL) { |
ansond | 27:eb6818ad257a | 334 | // wrap the data... |
ansond | 27:eb6818ad257a | 335 | this->getDataWrapper()->wrap((uint8_t *)data,data_length); |
ansond | 27:eb6818ad257a | 336 | |
ansond | 27:eb6818ad257a | 337 | // announce (after wrap) |
ansond | 37:5de33aed0cac | 338 | //this->logger()->log("Notify payload [%s]...",this->getDataWrapper()->get()); |
ansond | 27:eb6818ad257a | 339 | |
ansond | 27:eb6818ad257a | 340 | // fill notify |
ansond | 27:eb6818ad257a | 341 | notify_data_length = this->getDataWrapper()->length(); |
ansond | 27:eb6818ad257a | 342 | notify_data = this->getDataWrapper()->get(); |
ansond | 27:eb6818ad257a | 343 | } |
ansond | 27:eb6818ad257a | 344 | else { |
ansond | 27:eb6818ad257a | 345 | // announce (no wrap) |
ansond | 37:5de33aed0cac | 346 | //this->logger()->log("Notify payload [%s]...",data); |
ansond | 27:eb6818ad257a | 347 | |
ansond | 27:eb6818ad257a | 348 | // do not wrap the data... |
ansond | 27:eb6818ad257a | 349 | notify_data_length = data_length; |
ansond | 27:eb6818ad257a | 350 | notify_data = data; |
ansond | 27:eb6818ad257a | 351 | } |
ansond | 27:eb6818ad257a | 352 | |
ansond | 27:eb6818ad257a | 353 | // send the observation... |
ansond | 27:eb6818ad257a | 354 | 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 | 355 | if (status == 0) { |
ansond | 21:8487990a3baa | 356 | this->logger()->log("ERROR: resource(NOTIFY) send failed..."); |
ansond | 21:8487990a3baa | 357 | } |
ansond | 48:4b9ee3e32f93 | 358 | else { |
ansond | 48:4b9ee3e32f93 | 359 | ++(this->m_obs_number); |
ansond | 48:4b9ee3e32f93 | 360 | } |
ansond | 27:eb6818ad257a | 361 | |
ansond | 27:eb6818ad257a | 362 | // return our status |
ansond | 21:8487990a3baa | 363 | return status; |
ansond | 21:8487990a3baa | 364 | } |
ansond | 21:8487990a3baa | 365 | |
sam_grove | 2:853f9ecc12df | 366 | // default PUT (does nothing) |
sam_grove | 2:853f9ecc12df | 367 | void DynamicResource::put(const string value) |
sam_grove | 2:853f9ecc12df | 368 | { |
sam_grove | 2:853f9ecc12df | 369 | // not used by default |
sam_grove | 2:853f9ecc12df | 370 | ; |
sam_grove | 2:853f9ecc12df | 371 | } |
sam_grove | 2:853f9ecc12df | 372 | |
ansond | 21:8487990a3baa | 373 | // default POST (does nothing) |
ansond | 21:8487990a3baa | 374 | void DynamicResource::post(const string value) |
ansond | 21:8487990a3baa | 375 | { |
ansond | 21:8487990a3baa | 376 | // not used by default |
ansond | 21:8487990a3baa | 377 | ; |
ansond | 21:8487990a3baa | 378 | } |
ansond | 21:8487990a3baa | 379 | |
ansond | 21:8487990a3baa | 380 | // default DELETE (does nothing) |
ansond | 21:8487990a3baa | 381 | void DynamicResource::del(const string value) |
ansond | 21:8487990a3baa | 382 | { |
ansond | 21:8487990a3baa | 383 | // not used by default |
ansond | 21:8487990a3baa | 384 | ; |
ansond | 21:8487990a3baa | 385 | } |
ansond | 21:8487990a3baa | 386 | |
ansond | 30:113c2a1d8db2 | 387 | // default observe behavior |
ansond | 30:113c2a1d8db2 | 388 | void DynamicResource::observe() { |
ansond | 30:113c2a1d8db2 | 389 | if (this->m_observable == true) { |
ansond | 30:113c2a1d8db2 | 390 | this->notify(this->get()); |
ansond | 30:113c2a1d8db2 | 391 | } |
ansond | 30:113c2a1d8db2 | 392 | } |
ansond | 30:113c2a1d8db2 | 393 | |
ansond | 31:bacc63106754 | 394 | // set the observer pointer |
ansond | 31:bacc63106754 | 395 | void DynamicResource::setObserver(void *observer) { |
ansond | 31:bacc63106754 | 396 | this->m_observer = observer; |
ansond | 31:bacc63106754 | 397 | } |
ansond | 31:bacc63106754 | 398 | |
michaeljkoster | 52:822611156e35 | 399 | // set the content-format in responses |
ansond | 53:458c2730e086 | 400 | void DynamicResource::setContentFormat(uint8_t content_format) { |
michaeljkoster | 52:822611156e35 | 401 | this->m_content_format = content_format; |
michaeljkoster | 52:822611156e35 | 402 | } |
michaeljkoster | 52:822611156e35 | 403 | |
michaeljkoster | 52:822611156e35 | 404 | // set the max-age of responses |
ansond | 53:458c2730e086 | 405 | void DynamicResource::setMaxAge(uint8_t maxage) { |
michaeljkoster | 52:822611156e35 | 406 | this->m_maxage = maxage; |
michaeljkoster | 52:822611156e35 | 407 | } |
michaeljkoster | 52:822611156e35 | 408 | |
sam_grove | 2:853f9ecc12df | 409 | // convenience method to get the URI from its buffer field... |
sam_grove | 2:853f9ecc12df | 410 | string DynamicResource::coapDataToString(uint8_t *coap_data_ptr,int coap_data_ptr_length) |
sam_grove | 2:853f9ecc12df | 411 | { |
ansond | 0:b438482ebbfc | 412 | if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { |
ansond | 24:a6915e19814e | 413 | if (this->getDataWrapper() != NULL) { |
ansond | 24:a6915e19814e | 414 | // unwrap the data... |
ansond | 24:a6915e19814e | 415 | this->getDataWrapper()->unwrap(coap_data_ptr,coap_data_ptr_length); |
ansond | 24:a6915e19814e | 416 | char *buf = (char *)this->getDataWrapper()->get(); // assumes data is null terminated in DataWrapper... |
ansond | 24:a6915e19814e | 417 | return string(buf); |
ansond | 24:a6915e19814e | 418 | } |
ansond | 24:a6915e19814e | 419 | else { |
ansond | 24:a6915e19814e | 420 | // no unwrap of the data... |
ansond | 24:a6915e19814e | 421 | char buf[MAX_VALUE_BUFFER_LENGTH+1]; |
ansond | 24:a6915e19814e | 422 | memset(buf,0,MAX_VALUE_BUFFER_LENGTH+1); |
ansond | 24:a6915e19814e | 423 | memcpy(buf,(char *)coap_data_ptr,coap_data_ptr_length); |
ansond | 24:a6915e19814e | 424 | return string(buf); |
ansond | 24:a6915e19814e | 425 | } |
ansond | 0:b438482ebbfc | 426 | } |
ansond | 0:b438482ebbfc | 427 | return string(""); |
sam_grove | 2:853f9ecc12df | 428 | } |