Skip to content

Commit 97e522b

Browse files
authored
Merge pull request ARMmbed#393 from ARMmbed/execute_params_optimization
m2mresource: save RAM and ROM at M2MExecuteParameter
2 parents b05a343 + f0b5062 commit 97e522b

File tree

3 files changed

+91
-43
lines changed

3 files changed

+91
-43
lines changed

mbed-client/m2mresource.h

+28-12
Original file line numberDiff line numberDiff line change
@@ -295,22 +295,24 @@ class M2MResource::M2MExecuteParameter {
295295
private:
296296

297297
/**
298-
* \brief Constructor
298+
* \brief Constructor, since there is no implementation, it prevents invalid use of it
299299
*/
300300
M2MExecuteParameter();
301301

302-
/**
303-
* Destructor
304-
*/
305-
~M2MExecuteParameter();
302+
#ifdef MEMORY_OPTIMIZED_API
303+
M2MExecuteParameter(const char *object_name, const char *resource_name, uint16_t object_instance_id);
304+
#else
305+
// This is a deprecated constructor, to be removed on next release.
306+
M2MExecuteParameter(const String &object_name, const String &resource_name, uint16_t object_instance_id);
307+
#endif
306308

307309
public:
308310

309311
/**
310312
* \brief Returns the value of an argument.
311313
* \return uint8_t * The argument value.
312314
*/
313-
uint8_t *get_argument_value() const;
315+
const uint8_t *get_argument_value() const;
314316

315317
/**
316318
* \brief Returns the length of the value argument.
@@ -322,13 +324,21 @@ class M2MResource::M2MExecuteParameter {
322324
* \brief Returns the name of the object where the resource exists.
323325
* \return Object name.
324326
*/
327+
#ifdef MEMORY_OPTIMIZED_API
328+
const char* get_argument_object_name() const;
329+
#else
325330
const String& get_argument_object_name() const;
331+
#endif
326332

327333
/**
328334
* \brief Returns the resource name.
329335
* \return Resource name.
330336
*/
337+
#ifdef MEMORY_OPTIMIZED_API
338+
const char* get_argument_resource_name() const;
339+
#else
331340
const String& get_argument_resource_name() const;
341+
#endif
332342

333343
/**
334344
* \brief Returns the instance ID of the object where the resource exists.
@@ -337,13 +347,19 @@ class M2MResource::M2MExecuteParameter {
337347
uint16_t get_argument_object_instance_id() const;
338348

339349
private:
350+
// pointers to const data, not owned by this instance
351+
352+
#ifdef MEMORY_OPTIMIZED_API
353+
const char *_object_name;
354+
const char *_resource_name;
355+
#else
356+
const String &_object_name;
357+
const String &_resource_name;
358+
#endif
340359

341-
String _object_name;
342-
String _resource_name;
343-
uint8_t * _value;
344-
uint16_t _value_length;
345-
uint16_t _object_instance_id;
346-
360+
const uint8_t *_value;
361+
uint16_t _value_length;
362+
uint16_t _object_instance_id;
347363

348364
friend class Test_M2MResource;
349365
friend class M2MResource;

source/m2mresource.cpp

+40-24
Original file line numberDiff line numberDiff line change
@@ -528,24 +528,17 @@ sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl,
528528
// process the POST if we have registered a callback for it
529529
if(received_coap_header) {
530530
if ((operation() & SN_GRS_POST_ALLOWED) != 0) {
531-
M2MResource::M2MExecuteParameter *exec_params = new M2MResource::M2MExecuteParameter();
532-
if (exec_params) {
533-
exec_params->_object_name = object_name();
534-
exec_params->_resource_name = name();
535-
exec_params->_object_instance_id = object_instance_id();
536-
}
531+
M2MResource::M2MExecuteParameter exec_params(object_name(), name(), object_instance_id());
532+
537533
uint16_t coap_content_type = 0;
538534
if(received_coap_header->payload_ptr) {
539535
if(received_coap_header->content_format != COAP_CT_NONE) {
540536
coap_content_type = received_coap_header->content_format;
541537
}
542538
if(coap_content_type == 0) {
543-
if (exec_params){
544-
exec_params->_value = alloc_string_copy(received_coap_header->payload_ptr,
545-
received_coap_header->payload_len);
546-
if (exec_params->_value) {
547-
exec_params->_value_length = received_coap_header->payload_len;
548-
}
539+
exec_params._value = received_coap_header->payload_ptr;
540+
if (exec_params._value) {
541+
exec_params._value_length = received_coap_header->payload_len;
549542
}
550543
} else {
551544
msg_code = COAP_MSG_CODE_RESPONSE_UNSUPPORTED_CONTENT_FORMAT;
@@ -578,9 +571,9 @@ sn_coap_hdr_s* M2MResource::handle_post_request(nsdl_s *nsdl,
578571
#ifndef DISABLE_DELAYED_RESPONSE
579572
}
580573
#endif
581-
execute(exec_params);
574+
execute(&exec_params);
582575
}
583-
delete exec_params;
576+
584577
} else { // if ((object->operation() & SN_GRS_POST_ALLOWED) != 0)
585578
tr_error("M2MResource::handle_post_request - COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED");
586579
msg_code = COAP_MSG_CODE_RESPONSE_METHOD_NOT_ALLOWED; // 4.05
@@ -619,21 +612,32 @@ const char* M2MResource::object_name() const
619612
return parent_object.name();
620613
}
621614

622-
M2MResource::M2MExecuteParameter::M2MExecuteParameter()
615+
#ifdef MEMORY_OPTIMIZED_API
616+
M2MResource::M2MExecuteParameter::M2MExecuteParameter(const char *object_name, const char *resource_name,
617+
uint16_t object_instance_id) :
618+
_object_name(object_name),
619+
_resource_name(resource_name),
620+
_value(NULL),
621+
_value_length(0),
622+
_object_instance_id(object_instance_id)
623623
{
624-
_value = NULL;
625-
_value_length = 0;
626-
_object_name = "";
627-
_resource_name = "";
628-
_object_instance_id = 0;
629624
}
630-
631-
M2MResource::M2MExecuteParameter::~M2MExecuteParameter()
625+
#else
626+
M2MResource::M2MExecuteParameter::M2MExecuteParameter(const String &object_name, const String &resource_name,
627+
uint16_t object_instance_id) :
628+
_object_name(object_name),
629+
_resource_name(resource_name),
630+
_value(NULL),
631+
_value_length(0),
632+
_object_instance_id(object_instance_id)
632633
{
633-
free(_value);
634634
}
635+
#endif
635636

636-
uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const
637+
// These could be actually changed to be inline ones, as it would likely generate
638+
// smaller code at application side.
639+
640+
const uint8_t *M2MResource::M2MExecuteParameter::get_argument_value() const
637641
{
638642
return _value;
639643
}
@@ -643,6 +647,17 @@ uint16_t M2MResource::M2MExecuteParameter::get_argument_value_length() const
643647
return _value_length;
644648
}
645649

650+
#ifdef MEMORY_OPTIMIZED_API
651+
const char* M2MResource::M2MExecuteParameter::get_argument_object_name() const
652+
{
653+
return _object_name;
654+
}
655+
656+
const char* M2MResource::M2MExecuteParameter::get_argument_resource_name() const
657+
{
658+
return _resource_name;
659+
}
660+
#else
646661
const String& M2MResource::M2MExecuteParameter::get_argument_object_name() const
647662
{
648663
return _object_name;
@@ -652,6 +667,7 @@ const String& M2MResource::M2MExecuteParameter::get_argument_resource_name() con
652667
{
653668
return _resource_name;
654669
}
670+
#endif
655671

656672
uint16_t M2MResource::M2MExecuteParameter::get_argument_object_instance_id() const
657673
{

test/mbedclient/utest/m2mresource/test_m2mresource.cpp

+23-7
Original file line numberDiff line numberDiff line change
@@ -645,28 +645,44 @@ void Test_M2MResource::test_delayed_response()
645645

646646
void Test_M2MResource::test_execute_params()
647647
{
648-
M2MResource::M2MExecuteParameter *params = new M2MResource::M2MExecuteParameter();
648+
// Note: we need to use const name&objname here as the params is just storing references
649+
// so passing dummy "" or "object" there will cause segfault when the value is being verified.
650+
const String empty_name("");
651+
const String empty_object_name("");
652+
653+
M2MResource::M2MExecuteParameter *params = new M2MResource::M2MExecuteParameter(empty_name, empty_object_name, 0);
654+
649655
CHECK(params->get_argument_value() == NULL);
650656
CHECK(params->get_argument_value_length() == 0);
651657
CHECK(params->get_argument_object_name() == "");
652658
CHECK(params->get_argument_resource_name() == "");
653659
CHECK(params->get_argument_object_instance_id() == 0);
654660

655-
uint8_t value[] = {"test"};
661+
const uint8_t value[] = {"testvalue"};
656662
int length = sizeof(value);
657-
params->_value = (uint8_t*)malloc(length);
658-
memcpy(params->_value,value,length);
663+
uint8_t* temp_value = (uint8_t*)malloc(length);
664+
memcpy(temp_value, value, length);
665+
666+
delete params;
667+
668+
// then test with something more than just empty values
669+
const String param_name("object");
670+
const String param_object_name("resource");
671+
672+
params = new M2MResource::M2MExecuteParameter(param_name, param_object_name, 1);
673+
params->_value = temp_value;
659674
params->_value_length = length;
660-
params->_object_name = "object";
661-
params->_resource_name = "resource";
662-
params->_object_instance_id = 0;
675+
params->_object_instance_id = 7;
676+
663677
CHECK(params->_value == params->get_argument_value());
664678
CHECK(params->_value_length == params->get_argument_value_length());
665679
CHECK(params->_resource_name == params->get_argument_resource_name());
666680
CHECK(params->_object_name == params->get_argument_object_name());
667681
CHECK(params->_object_instance_id == params->get_argument_object_instance_id());
668682

669683
delete params;
684+
685+
free(temp_value);
670686
}
671687

672688
void Test_M2MResource::test_ctor()

0 commit comments

Comments
 (0)