mbed Connector Endpoint interface. This interface permits a mbed endpoint to easily setup MDS resources and emit those resources to an MDS server.
Dependents: IoT_LED_demo ServoTest uWater_Project hackathon ... more
Diff: api/DynamicResource.cpp
- Revision:
- 0:b438482ebbfc
- Child:
- 2:853f9ecc12df
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/DynamicResource.cpp Tue Jan 27 22:23:51 2015 +0000 @@ -0,0 +1,165 @@ +/** + * @file DynamicResource.cpp + * @brief mbed CoAP Endpoint Dynamic Resource class + * @author Doug Anson/Chris Paola + * @version 1.0 + * @see + * + * Copyright (c) 2014 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "DynamicResource.h" + + // InstancePointerTable Helper + #include "InstancePointerTableHelper.h" + + // default constructor + 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("")) { + this->m_res_type = string(res_type); + this->m_observable = observable; + this->m_res_mask = res_mask; + } + + // constructor (input initial value) + 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) { + this->m_res_type = string(res_type); + this->m_observable = observable; + this->m_res_mask = res_mask; + } + + // constructor (strings) + 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) { + this->m_res_type = res_type; + this->m_observable = observable; + this->m_res_mask = res_mask; + } + + // copy constructor + DynamicResource::DynamicResource(const DynamicResource &resource) : Resource<string>((const Resource<string> &)resource) { + this->m_res_type = resource.m_res_type; + this->m_observable = resource.m_observable; + this->m_res_mask = resource.m_res_mask; + } + + // destructor + DynamicResource::~DynamicResource() { + } + + // bind resource to NSDL + void DynamicResource::bind(void *p) { + if (p != NULL) { + sn_nsdl_resource_info_s *resource_ptr = (sn_nsdl_resource_info_s *)p; + std::printf("DynamicResource: name[%s] type:[%s] mask: 0x%.2x\r\n",this->getName().c_str(),this->m_res_type.c_str(),this->m_res_mask); + const uint8_t *name = (const uint8_t *)(this->getName().c_str()); + const uint8_t *res_type = (const uint8_t *)this->m_res_type.c_str(); + int name_length = this->getName().size(); + int res_type_length = this->m_res_type.size(); + int is_observable = 0; if (this->m_observable == true) is_observable = 1; + const string *key = new string(this->getName()); + ipt_helper_add_instance_pointer(key,this); + 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); + std::printf("DynamicResource[%s(%d)] type: %s(%d) bound mask: 0x%.2x\r\n",name,name_length,res_type,res_type_length,this->m_res_mask); + } + else { + std::printf("DynamicResource: NULL parameter in bind()\r\n"); + } + } + + // process NSDL message + uint8_t DynamicResource::process(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s *proto) { + sn_coap_hdr_s *coap_res_ptr = 0; + + // create our key for debugging output... + string key = this->coapDataToString(received_coap_ptr->uri_path_ptr,received_coap_ptr->uri_path_len); + + if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) + { + std::printf("GET requested for [%s]...\r\n",key.c_str()); + coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT); + + // process the GET if we have registered a callback for it... + if ((this->m_res_mask&SN_GRS_GET_ALLOWED) != 0) { + // call the resource get() to get the resource value + std::printf("Calling resource(GET) for [%s]...\r\n",key.c_str()); + string value = this->get(); + + // convert the string from the GET to something suitable for CoAP payloads + std::printf("Building payload for [%s]=[%s]...\r\n",key.c_str(),value.c_str()); + int length = value.size(); + char value_buffer[MAX_VALUE_BUFFER_LENGTH+1]; + if (length > MAX_VALUE_BUFFER_LENGTH) length = MAX_VALUE_BUFFER_LENGTH; + memset(value_buffer,0,MAX_VALUE_BUFFER_LENGTH+1); + memcpy(value_buffer,value.c_str(),length); + + // fill in the CoAP response payload + coap_res_ptr->payload_len = length; + coap_res_ptr->payload_ptr = (uint8_t *)value_buffer; + + // build out the response and send... + sn_nsdl_send_coap_message(address, coap_res_ptr); + } + else { + std::printf("ERROR: resource(GET) mask is munged (mask: 0x%x)\r\n",this->m_res_mask); + } + } + else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) + { + std::printf("PUT requested for [%s]...\r\n",key.c_str()); + if(received_coap_ptr->payload_len > 0) + { + // process the PUT if we have registered a callback for it... + if ((this->m_res_mask&SN_GRS_PUT_ALLOWED) != 0) { + // binder interacts only with strings + string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len); + + // call the resource put() to set the resource value + std::printf("Calling resource(PUT) with [%s]=[%s]...\r\n",key.c_str(),value.c_str()); + this->put(value); + + // build out the response and send... + std::printf("resource(PUT) completed for [%s]...\r\n",key.c_str()); + coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED); + sn_nsdl_send_coap_message(address, coap_res_ptr); + } + else { + std::printf("ERROR: resource(PUT) mask is munged (mask: 0x%x)\r\n",this->m_res_mask); + } + } + else { + std::printf("ERROR: Binder(PUT) payload is NULL...\r\n"); + } + } + + sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr); + + return 0; + } + + // default PUT (does nothing) + void DynamicResource::put(const string value) { + // not used by default + ; + } + + // convenience method to get the URI from its buffer field... + string DynamicResource::coapDataToString(uint8_t *coap_data_ptr,int coap_data_ptr_length) { + if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { + char buf[MAX_VALUE_BUFFER_LENGTH+1]; + memset(buf,0,MAX_VALUE_BUFFER_LENGTH+1); + memcpy(buf,(char *)coap_data_ptr,coap_data_ptr_length); + return string(buf); + } + return string(""); + } \ No newline at end of file