Skip to content

Commit 70dcd8b

Browse files
author
Yogesh Pande
committed
First draft with working version on K64F, Ethernet only
1 parent 02a90f1 commit 70dcd8b

22 files changed

+472
-2050
lines changed

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
1-
WIP
1+
# Pelion Client Mbed OS Example
2+
3+
Features:
4+
- Mbed OS 5.13
5+
- Supports Update
6+
- 200 lines of codes + credential sources
7+
8+
# Deploying
9+
10+
Because the point of this repository is to propose the change ideas, mbed-cloud-client patching is required before compilation.
11+
12+
mbed import new-mbed-os-pelion-example
13+
cd new-mbed-os-pelion-example
14+
git checkout -b reduced-configuration -t origin/reduced-configuration
15+
./patch-mbed-cloud-client.sh
16+
17+
# Compilation
18+
19+
mbed target K64F
20+
mbed toolchain GCC_ARM
21+
mbed compile
22+
23+
24+
# Program Flow
25+
26+
1. Bootstrap
27+
1. Register
28+
1. Send enter through putty/minicom to simulate button
29+
1. Send 'i' to print endpoint name
30+
1. Send Ctrl-C through putty/minicom to unregister

main.cpp

Lines changed: 135 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -17,180 +17,180 @@
1717
// ----------------------------------------------------------------------------
1818
#ifndef MBED_TEST_MODE
1919
#include "mbed.h"
20-
#include "simplem2mclient.h"
21-
#include "platform_setup.h"
20+
#include "kv_config.h"
21+
#include "mbed-cloud-client/MbedCloudClient.h" // Required for new MbedCloudClient()
22+
#include "factory_configurator_client.h" // Required for fcc_* functions and FCC_* defines
23+
#include "m2mresource.h" // Required for M2MResource
2224

23-
#ifndef MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT
24-
#include "certificate_enrollment_user_cb.h"
25-
#endif
25+
#include "mbed-trace/mbed_trace.h" // Required for mbed_trace_*
26+
#include "mbed-trace-helper.h" // Required for mbed_trace_mutex_*
2627

2728
// Pointers to the resources that will be created in main_application().
28-
static M2MResource* button_res;
29-
static M2MResource* pattern_res;
30-
static M2MResource* blink_res;
29+
static MbedCloudClient *cloud_client;
30+
static bool cloud_client_registered = false;
3131

32-
// An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
33-
// This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
34-
EventQueue eventQueue;
32+
static M2MResource* m2m_get_res;
33+
static M2MResource* m2m_put_res;
34+
static M2MResource* m2m_post_res;
3535

36-
// Pointer to mbedClient, used for calling close function.
37-
static SimpleM2MClient *client;
3836

39-
void pattern_updated(const char *)
37+
void print_client_ids(void)
4038
{
41-
printf("PUT received, new value: %s\n", pattern_res->get_value_string().c_str());
39+
printf("Account ID: %s\r\n", cloud_client->endpoint_info()->account_id.c_str());
40+
printf("ID: %s\r\n", cloud_client->endpoint_info()->endpoint_name.c_str());
41+
printf("Endpoint Name: %s\r\n", cloud_client->endpoint_info()->internal_endpoint_name.c_str());
4242
}
4343

44-
void blink_callback(void *)
44+
void button_press(void)
4545
{
46-
String pattern_string = pattern_res->get_value_string();
47-
const char *pattern = pattern_string.c_str();
48-
printf("LED pattern = %s\n", pattern);
49-
50-
// The pattern is something like 500:200:500, so parse that.
51-
// LED blinking is done while parsing.
52-
// TBD
53-
blink_res->send_delayed_post_response();
46+
m2m_get_res->set_value(m2m_get_res->get_value_int() + 1);
47+
printf("\nCounter %" PRId64, m2m_get_res->get_value_int());
5448
}
5549

56-
// TODO: move somewhere in the helper folder
57-
void notification_status_callback(const M2MBase& object,
58-
const M2MBase::MessageDeliveryStatus status,
59-
const M2MBase::MessageType /*type*/)
50+
void put_update(const char* /*object_name*/)
6051
{
61-
switch(status) {
62-
case M2MBase::MESSAGE_STATUS_BUILD_ERROR:
63-
printf("Message status callback: (%s) error when building CoAP message\n", object.uri_path());
64-
break;
65-
case M2MBase::MESSAGE_STATUS_RESEND_QUEUE_FULL:
66-
printf("Message status callback: (%s) CoAP resend queue full\n", object.uri_path());
67-
break;
68-
case M2MBase::MESSAGE_STATUS_SENT:
69-
printf("Message status callback: (%s) Message sent to server\n", object.uri_path());
70-
break;
71-
case M2MBase::MESSAGE_STATUS_DELIVERED:
72-
printf("Message status callback: (%s) Message delivered\n", object.uri_path());
73-
break;
74-
case M2MBase::MESSAGE_STATUS_SEND_FAILED:
75-
printf("Message status callback: (%s) Message sending failed\n", object.uri_path());
76-
break;
77-
case M2MBase::MESSAGE_STATUS_SUBSCRIBED:
78-
printf("Message status callback: (%s) subscribed\n", object.uri_path());
79-
break;
80-
case M2MBase::MESSAGE_STATUS_UNSUBSCRIBED:
81-
printf("Message status callback: (%s) subscription removed\n", object.uri_path());
82-
break;
83-
case M2MBase::MESSAGE_STATUS_REJECTED:
84-
printf("Message status callback: (%s) server has rejected the message\n", object.uri_path());
85-
break;
86-
default:
87-
break;
88-
}
52+
printf("PUT update %d\r\n", (int)m2m_put_res->get_value_int());
53+
}
54+
55+
void execute_post(void */*arguments*/)
56+
{
57+
printf("POST executed\r\n");
58+
}
59+
60+
void client_registered(void)
61+
{
62+
printf("Client registered: \r\n");
63+
print_client_ids();
64+
cloud_client_registered = true;
65+
}
66+
67+
void client_unregistered(void)
68+
{
69+
printf("Client unregistered\r\n");
70+
cloud_client_registered = false;
8971
}
9072

91-
// This function is called when a POST request is received for resource 5000/0/1.
92-
void unregister(void *)
73+
void client_error(int err)
9374
{
94-
printf("Unregister resource executed\n");
95-
client->close();
75+
printf("client_error(%d) -> %s\r\n", err, cloud_client->error_description());
9676
}
9777

98-
// This function is called when a POST request is received for resource 5000/0/2.
99-
void factory_reset(void *)
78+
void update_progress(uint32_t progress, uint32_t total)
10079
{
101-
printf("Factory reset resource executed\n");
102-
client->close();
103-
kcm_status_e kcm_status = kcm_factory_reset();
104-
if (kcm_status != KCM_STATUS_SUCCESS) {
105-
printf("Failed to do factory reset - %d\n", kcm_status);
106-
} else {
107-
printf("Factory reset completed. Now restart the device\n");
80+
uint8_t percent = (uint8_t)((uint64_t)progress * 100 / total);
81+
printf("Update progress = %" PRIu8 "%%\r\n", percent);
82+
}
83+
84+
void update_authorize(int32_t request)
85+
{
86+
switch (request) {
87+
case MbedCloudClient::UpdateRequestDownload:
88+
printf("Download authorized\r\n");
89+
cloud_client->update_authorize(MbedCloudClient::UpdateRequestDownload);
90+
break;
91+
92+
case MbedCloudClient::UpdateRequestInstall:
93+
printf("Update authorized -> reboot\r\n");
94+
cloud_client->update_authorize(MbedCloudClient::UpdateRequestInstall);
95+
break;
96+
97+
default:
98+
printf("update_authorize(%" PRId32 "), unknown request", request);
99+
break;
108100
}
109101
}
110102

111103
int main(void)
112104
{
113-
// Initialize trace-library first
114-
if (application_init_mbed_trace() != 0) {
115-
printf("Failed initializing mbed trace\n" );
116-
return -1;
117-
}
105+
int status;
118106

119-
// Initialize platform-specific components
120-
if(platform_init() != 0) {
121-
printf("ERROR - platform_init() failed!\n");
107+
status = mbed_trace_init();
108+
if (status != 0) {
109+
printf("mbed_trace_init() failed with %d\r\n", status);
122110
return -1;
123111
}
124112

125-
// Print platform information
126-
platform_info();
113+
mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO); // trace level info
127114

128-
// Initialize network
129-
if (!platform_init_connection()) {
130-
printf("Network initialized, registering...\n");
131-
} else {
115+
printf("Init KVStore\r\n");
116+
// Mount default kvstore
117+
status = kv_init_storage_config();
118+
if (status != MBED_SUCCESS) {
119+
printf("kv_init_storage_config() - failed, status %d\r\n", status);
132120
return -1;
133121
}
134122

135-
// Print some statistics of the object sizes and their heap memory consumption.
136-
// NOTE: This *must* be done before creating MbedCloudClient, as the statistic calculation
137-
// creates and deletes M2MSecurity and M2MDevice singleton objects, which are also used by
138-
// the MbedCloudClient.
139-
#ifdef MBED_HEAP_STATS_ENABLED
140-
print_m2mobject_stats();
141-
#endif
142-
143-
// SimpleClient is used for registering and unregistering resources to a server.
144-
SimpleM2MClient mbedClient;
145-
146-
// Factory Config Client initialization
147-
if (application_init_fcc() != 0) {
148-
printf("Failed initializing FCC, exiting application!\n");
123+
// Connect with NetworkInterface
124+
NetworkInterface *network = NetworkInterface::get_default_instance();
125+
if (network == NULL) {
126+
printf("Failed to get default NetworkInterface\n");
127+
return -1;
128+
}
129+
status = network->connect();
130+
if (status != NSAPI_ERROR_OK) {
131+
printf("NetworkInterface failed to connect with %d\n", status);
132+
return -1;
133+
}
134+
printf("Network connected\r\n");
135+
136+
// Run developer flow
137+
printf("Using developer flow\r\n");
138+
status = fcc_init();
139+
status = fcc_developer_flow();
140+
if (status != FCC_STATUS_SUCCESS && status != FCC_STATUS_KCM_FILE_EXIST_ERROR) {
141+
printf("fcc_developer_flow() failed with %d\r\n", status);
149142
return -1;
150143
}
151144

152-
// Save pointer to mbedClient so that other functions can access it.
153-
client = &mbedClient;
154-
155-
#ifdef MBED_HEAP_STATS_ENABLED
156-
printf("Client initialized\r\n");
157-
print_heap_stats();
158-
#endif
159-
#ifdef MBED_STACK_STATS_ENABLED
160-
print_stack_statistics();
161-
#endif
162-
163-
// Create resource for button count. Path of this resource will be: 3200/0/5501.
164-
button_res = mbedClient.add_cloud_resource(3200, 0, 5501, "button_resource", M2MResourceInstance::INTEGER,
165-
M2MBase::GET_ALLOWED, 0, true, NULL, (void*)notification_status_callback);
166-
167-
// Create resource for led blinking pattern. Path of this resource will be: 3201/0/5853.
168-
pattern_res = mbedClient.add_cloud_resource(3201, 0, 5853, "pattern_resource", M2MResourceInstance::STRING,
169-
M2MBase::GET_PUT_ALLOWED, "500:500:500:500", true, (void*)pattern_updated, (void*)notification_status_callback);
170-
171-
// Create resource for starting the led blinking. Path of this resource will be: 3201/0/5850.
172-
blink_res = mbedClient.add_cloud_resource(3201, 0, 5850, "blink_resource", M2MResourceInstance::STRING,
173-
M2MBase::POST_ALLOWED, "", false, (void*)blink_callback, (void*)notification_status_callback);
174-
// Use delayed response
175-
blink_res->set_delayed_response(true);
176-
177-
// Create resource for unregistering the device. Path of this resource will be: 5000/0/1.
178-
mbedClient.add_cloud_resource(5000, 0, 1, "unregister", M2MResourceInstance::STRING,
179-
M2MBase::POST_ALLOWED, NULL, false, (void*)unregister, NULL);
180-
181-
// Create resource for running factory reset for the device. Path of this resource will be: 5000/0/2.
182-
mbedClient.add_cloud_resource(5000, 0, 2, "factory_reset", M2MResourceInstance::STRING,
183-
M2MBase::POST_ALLOWED, NULL, false, (void*)factory_reset, NULL);
145+
printf("Create resources\r\n");
146+
M2MObjectList m2m_obj_list;
184147

185-
mbedClient.register_and_connect();
148+
// GET resource 3200/0/5501
149+
m2m_get_res = M2MInterfaceFactory::create_resource(m2m_obj_list, 3200, 0, 5501, M2MResourceInstance::INTEGER, M2MBase::GET_ALLOWED);
150+
if (m2m_get_res->set_value(0) != true) {
151+
printf("m2m_get_res->set_value() failed\r\n");
152+
return -1;
153+
}
186154

187-
#ifndef MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT
188-
// Add certificate renewal callback
189-
mbedClient.get_cloud_client().on_certificate_renewal(certificate_renewal_cb);
190-
#endif // MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT
155+
// PUT resource 3200/0/5500
156+
m2m_put_res = M2MInterfaceFactory::create_resource(m2m_obj_list, 3342, 0, 5500, M2MResourceInstance::INTEGER, M2MBase::GET_PUT_ALLOWED);
157+
if (m2m_put_res->set_value(0) != true) {
158+
printf("m2m_led_res->set_value() failed\r\n");
159+
return -1;
160+
}
161+
if (m2m_put_res->set_value_updated_function(put_update) != true) { // PUT sets led
162+
printf("m2m_put_res->set_value_updated_function() failed\r\n");
163+
return -1;
164+
}
191165

192-
eventQueue.dispatch_forever();
166+
m2m_post_res = M2MInterfaceFactory::create_resource(m2m_obj_list, 3342, 0, 5500, M2MResourceInstance::INTEGER, M2MBase::POST_ALLOWED);
167+
if (m2m_post_res->set_execute_function(execute_post) != true) { // POST toggles led
168+
printf("m2m_post_res->set_execute_function() failed\r\n");
169+
return -1;
170+
}
193171

172+
printf("Starting Pelion Device Management Client\r\n");
173+
cloud_client = new MbedCloudClient(client_registered, client_unregistered, client_error, update_authorize, update_progress);
174+
cloud_client->add_objects(m2m_obj_list);
175+
cloud_client->setup(network); // cloud_client->setup(NULL); -- https://jira.arm.com/browse/IOTCLT-3114
176+
177+
printf("Application loop\r\n");
178+
while(1) {
179+
int in_char = getchar();
180+
if (in_char == 'i') {
181+
print_client_ids(); // When 'i' is pressed, print endpoint info
182+
continue;
183+
} else if (in_char > 0 && in_char != 0x03) { // Ctrl+C is 0x03 in Mbed OS and Linux returns negative number
184+
button_press(); // Simulate button press
185+
continue;
186+
}
187+
printf("Unregistering\r\n");
188+
cloud_client->close();
189+
while (cloud_client_registered == true) {
190+
wait(1);
191+
}
192+
break;
193+
}
194194
return 0;
195195
}
196196

0 commit comments

Comments
 (0)