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
api/DynamicResource.cpp@0:b438482ebbfc, 2015-01-27 (annotated)
- Committer:
- ansond
- Date:
- Tue Jan 27 22:23:51 2015 +0000
- Revision:
- 0:b438482ebbfc
- Child:
- 2:853f9ecc12df
initial check in
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 |
ansond | 0:b438482ebbfc | 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 | */ |
ansond | 0:b438482ebbfc | 22 | |
ansond | 0:b438482ebbfc | 23 | #include "DynamicResource.h" |
ansond | 0:b438482ebbfc | 24 | |
ansond | 0:b438482ebbfc | 25 | // InstancePointerTable Helper |
ansond | 0:b438482ebbfc | 26 | #include "InstancePointerTableHelper.h" |
ansond | 0:b438482ebbfc | 27 | |
ansond | 0:b438482ebbfc | 28 | // default constructor |
ansond | 0:b438482ebbfc | 29 | 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("")) { |
ansond | 0:b438482ebbfc | 30 | this->m_res_type = string(res_type); |
ansond | 0:b438482ebbfc | 31 | this->m_observable = observable; |
ansond | 0:b438482ebbfc | 32 | this->m_res_mask = res_mask; |
ansond | 0:b438482ebbfc | 33 | } |
ansond | 0:b438482ebbfc | 34 | |
ansond | 0:b438482ebbfc | 35 | // constructor (input initial value) |
ansond | 0:b438482ebbfc | 36 | 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) { |
ansond | 0:b438482ebbfc | 37 | this->m_res_type = string(res_type); |
ansond | 0:b438482ebbfc | 38 | this->m_observable = observable; |
ansond | 0:b438482ebbfc | 39 | this->m_res_mask = res_mask; |
ansond | 0:b438482ebbfc | 40 | } |
ansond | 0:b438482ebbfc | 41 | |
ansond | 0:b438482ebbfc | 42 | // constructor (strings) |
ansond | 0:b438482ebbfc | 43 | 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) { |
ansond | 0:b438482ebbfc | 44 | this->m_res_type = res_type; |
ansond | 0:b438482ebbfc | 45 | this->m_observable = observable; |
ansond | 0:b438482ebbfc | 46 | this->m_res_mask = res_mask; |
ansond | 0:b438482ebbfc | 47 | } |
ansond | 0:b438482ebbfc | 48 | |
ansond | 0:b438482ebbfc | 49 | // copy constructor |
ansond | 0:b438482ebbfc | 50 | DynamicResource::DynamicResource(const DynamicResource &resource) : Resource<string>((const Resource<string> &)resource) { |
ansond | 0:b438482ebbfc | 51 | this->m_res_type = resource.m_res_type; |
ansond | 0:b438482ebbfc | 52 | this->m_observable = resource.m_observable; |
ansond | 0:b438482ebbfc | 53 | this->m_res_mask = resource.m_res_mask; |
ansond | 0:b438482ebbfc | 54 | } |
ansond | 0:b438482ebbfc | 55 | |
ansond | 0:b438482ebbfc | 56 | // destructor |
ansond | 0:b438482ebbfc | 57 | DynamicResource::~DynamicResource() { |
ansond | 0:b438482ebbfc | 58 | } |
ansond | 0:b438482ebbfc | 59 | |
ansond | 0:b438482ebbfc | 60 | // bind resource to NSDL |
ansond | 0:b438482ebbfc | 61 | void DynamicResource::bind(void *p) { |
ansond | 0:b438482ebbfc | 62 | if (p != NULL) { |
ansond | 0:b438482ebbfc | 63 | sn_nsdl_resource_info_s *resource_ptr = (sn_nsdl_resource_info_s *)p; |
ansond | 0:b438482ebbfc | 64 | 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); |
ansond | 0:b438482ebbfc | 65 | const uint8_t *name = (const uint8_t *)(this->getName().c_str()); |
ansond | 0:b438482ebbfc | 66 | const uint8_t *res_type = (const uint8_t *)this->m_res_type.c_str(); |
ansond | 0:b438482ebbfc | 67 | int name_length = this->getName().size(); |
ansond | 0:b438482ebbfc | 68 | int res_type_length = this->m_res_type.size(); |
ansond | 0:b438482ebbfc | 69 | int is_observable = 0; if (this->m_observable == true) is_observable = 1; |
ansond | 0:b438482ebbfc | 70 | const string *key = new string(this->getName()); |
ansond | 0:b438482ebbfc | 71 | ipt_helper_add_instance_pointer(key,this); |
ansond | 0:b438482ebbfc | 72 | 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 | 0:b438482ebbfc | 73 | 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); |
ansond | 0:b438482ebbfc | 74 | } |
ansond | 0:b438482ebbfc | 75 | else { |
ansond | 0:b438482ebbfc | 76 | std::printf("DynamicResource: NULL parameter in bind()\r\n"); |
ansond | 0:b438482ebbfc | 77 | } |
ansond | 0:b438482ebbfc | 78 | } |
ansond | 0:b438482ebbfc | 79 | |
ansond | 0:b438482ebbfc | 80 | // process NSDL message |
ansond | 0:b438482ebbfc | 81 | uint8_t DynamicResource::process(sn_coap_hdr_s *received_coap_ptr, sn_nsdl_addr_s *address, sn_proto_info_s *proto) { |
ansond | 0:b438482ebbfc | 82 | sn_coap_hdr_s *coap_res_ptr = 0; |
ansond | 0:b438482ebbfc | 83 | |
ansond | 0:b438482ebbfc | 84 | // create our key for debugging output... |
ansond | 0:b438482ebbfc | 85 | string key = this->coapDataToString(received_coap_ptr->uri_path_ptr,received_coap_ptr->uri_path_len); |
ansond | 0:b438482ebbfc | 86 | |
ansond | 0:b438482ebbfc | 87 | if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_GET) |
ansond | 0:b438482ebbfc | 88 | { |
ansond | 0:b438482ebbfc | 89 | std::printf("GET requested for [%s]...\r\n",key.c_str()); |
ansond | 0:b438482ebbfc | 90 | coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CONTENT); |
ansond | 0:b438482ebbfc | 91 | |
ansond | 0:b438482ebbfc | 92 | // process the GET if we have registered a callback for it... |
ansond | 0:b438482ebbfc | 93 | if ((this->m_res_mask&SN_GRS_GET_ALLOWED) != 0) { |
ansond | 0:b438482ebbfc | 94 | // call the resource get() to get the resource value |
ansond | 0:b438482ebbfc | 95 | std::printf("Calling resource(GET) for [%s]...\r\n",key.c_str()); |
ansond | 0:b438482ebbfc | 96 | string value = this->get(); |
ansond | 0:b438482ebbfc | 97 | |
ansond | 0:b438482ebbfc | 98 | // convert the string from the GET to something suitable for CoAP payloads |
ansond | 0:b438482ebbfc | 99 | std::printf("Building payload for [%s]=[%s]...\r\n",key.c_str(),value.c_str()); |
ansond | 0:b438482ebbfc | 100 | int length = value.size(); |
ansond | 0:b438482ebbfc | 101 | char value_buffer[MAX_VALUE_BUFFER_LENGTH+1]; |
ansond | 0:b438482ebbfc | 102 | if (length > MAX_VALUE_BUFFER_LENGTH) length = MAX_VALUE_BUFFER_LENGTH; |
ansond | 0:b438482ebbfc | 103 | memset(value_buffer,0,MAX_VALUE_BUFFER_LENGTH+1); |
ansond | 0:b438482ebbfc | 104 | memcpy(value_buffer,value.c_str(),length); |
ansond | 0:b438482ebbfc | 105 | |
ansond | 0:b438482ebbfc | 106 | // fill in the CoAP response payload |
ansond | 0:b438482ebbfc | 107 | coap_res_ptr->payload_len = length; |
ansond | 0:b438482ebbfc | 108 | coap_res_ptr->payload_ptr = (uint8_t *)value_buffer; |
ansond | 0:b438482ebbfc | 109 | |
ansond | 0:b438482ebbfc | 110 | // build out the response and send... |
ansond | 0:b438482ebbfc | 111 | sn_nsdl_send_coap_message(address, coap_res_ptr); |
ansond | 0:b438482ebbfc | 112 | } |
ansond | 0:b438482ebbfc | 113 | else { |
ansond | 0:b438482ebbfc | 114 | std::printf("ERROR: resource(GET) mask is munged (mask: 0x%x)\r\n",this->m_res_mask); |
ansond | 0:b438482ebbfc | 115 | } |
ansond | 0:b438482ebbfc | 116 | } |
ansond | 0:b438482ebbfc | 117 | else if(received_coap_ptr->msg_code == COAP_MSG_CODE_REQUEST_PUT) |
ansond | 0:b438482ebbfc | 118 | { |
ansond | 0:b438482ebbfc | 119 | std::printf("PUT requested for [%s]...\r\n",key.c_str()); |
ansond | 0:b438482ebbfc | 120 | if(received_coap_ptr->payload_len > 0) |
ansond | 0:b438482ebbfc | 121 | { |
ansond | 0:b438482ebbfc | 122 | // process the PUT if we have registered a callback for it... |
ansond | 0:b438482ebbfc | 123 | if ((this->m_res_mask&SN_GRS_PUT_ALLOWED) != 0) { |
ansond | 0:b438482ebbfc | 124 | // binder interacts only with strings |
ansond | 0:b438482ebbfc | 125 | string value = this->coapDataToString(received_coap_ptr->payload_ptr,received_coap_ptr->payload_len); |
ansond | 0:b438482ebbfc | 126 | |
ansond | 0:b438482ebbfc | 127 | // call the resource put() to set the resource value |
ansond | 0:b438482ebbfc | 128 | std::printf("Calling resource(PUT) with [%s]=[%s]...\r\n",key.c_str(),value.c_str()); |
ansond | 0:b438482ebbfc | 129 | this->put(value); |
ansond | 0:b438482ebbfc | 130 | |
ansond | 0:b438482ebbfc | 131 | // build out the response and send... |
ansond | 0:b438482ebbfc | 132 | std::printf("resource(PUT) completed for [%s]...\r\n",key.c_str()); |
ansond | 0:b438482ebbfc | 133 | coap_res_ptr = sn_coap_build_response(received_coap_ptr, COAP_MSG_CODE_RESPONSE_CHANGED); |
ansond | 0:b438482ebbfc | 134 | sn_nsdl_send_coap_message(address, coap_res_ptr); |
ansond | 0:b438482ebbfc | 135 | } |
ansond | 0:b438482ebbfc | 136 | else { |
ansond | 0:b438482ebbfc | 137 | std::printf("ERROR: resource(PUT) mask is munged (mask: 0x%x)\r\n",this->m_res_mask); |
ansond | 0:b438482ebbfc | 138 | } |
ansond | 0:b438482ebbfc | 139 | } |
ansond | 0:b438482ebbfc | 140 | else { |
ansond | 0:b438482ebbfc | 141 | std::printf("ERROR: Binder(PUT) payload is NULL...\r\n"); |
ansond | 0:b438482ebbfc | 142 | } |
ansond | 0:b438482ebbfc | 143 | } |
ansond | 0:b438482ebbfc | 144 | |
ansond | 0:b438482ebbfc | 145 | sn_coap_parser_release_allocated_coap_msg_mem(coap_res_ptr); |
ansond | 0:b438482ebbfc | 146 | |
ansond | 0:b438482ebbfc | 147 | return 0; |
ansond | 0:b438482ebbfc | 148 | } |
ansond | 0:b438482ebbfc | 149 | |
ansond | 0:b438482ebbfc | 150 | // default PUT (does nothing) |
ansond | 0:b438482ebbfc | 151 | void DynamicResource::put(const string value) { |
ansond | 0:b438482ebbfc | 152 | // not used by default |
ansond | 0:b438482ebbfc | 153 | ; |
ansond | 0:b438482ebbfc | 154 | } |
ansond | 0:b438482ebbfc | 155 | |
ansond | 0:b438482ebbfc | 156 | // convenience method to get the URI from its buffer field... |
ansond | 0:b438482ebbfc | 157 | string DynamicResource::coapDataToString(uint8_t *coap_data_ptr,int coap_data_ptr_length) { |
ansond | 0:b438482ebbfc | 158 | if (coap_data_ptr != NULL && coap_data_ptr_length > 0) { |
ansond | 0:b438482ebbfc | 159 | char buf[MAX_VALUE_BUFFER_LENGTH+1]; |
ansond | 0:b438482ebbfc | 160 | memset(buf,0,MAX_VALUE_BUFFER_LENGTH+1); |
ansond | 0:b438482ebbfc | 161 | memcpy(buf,(char *)coap_data_ptr,coap_data_ptr_length); |
ansond | 0:b438482ebbfc | 162 | return string(buf); |
ansond | 0:b438482ebbfc | 163 | } |
ansond | 0:b438482ebbfc | 164 | return string(""); |
ansond | 0:b438482ebbfc | 165 | } |