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

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