forked from eclipse-threadx/netxduo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
demo_netx_duo_lwm2m_client.c
1383 lines (1099 loc) · 41.7 KB
/
demo_netx_duo_lwm2m_client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* This is a demonstration of the NetX LWM2M Client.
*/
#include "nx_api.h"
#include "nx_lwm2m_client.h"
#ifndef SAMPLE_DHCP_DISABLE
#include "nxd_dhcp_client.h"
#endif /* SAMPLE_DHCP_DISABLE */
#ifndef SAMPLE_DNS_DISABLE
#include "nxd_dns.h"
#endif /* SAMPLE_DNS_DISABLE */
#ifdef NX_SECURE_ENABLE_DTLS
#include "nx_secure_dtls_api.h"
#include "nx_crypto_aes.h"
#include "nx_crypto_sha2.h"
#include "nx_crypto_tls_prf_sha256.h"
#endif /* NX_SECURE_ENABLE_DTLS */
/* Enable LWM2M Bootstrap to start Client Initiated Bootstrap. */
//#define BOOTSTRAP
/* LwM2M Client endpoint. */
#ifndef LWM2M_CLIENT_ENDPOINT
#define LWM2M_CLIENT_ENDPOINT "nxlwm2mclient"
#endif /* LWM2M_CLIENT_ENDPOINT */
/* IP address of LwM2M Server or LwM2M Bootstrap Server. */
#ifndef LWM2M_SERVER_ADDRESS
#define LWM2M_SERVER_ADDRESS IP_ADDRESS(23, 97, 187, 154)
#endif /* LWM2M_SERVER_ADDRESS*/
/* Port of LwM2M Server or LwM2M Bootstrap Server. */
#ifndef LWM2M_SERVER_PORT
#define LWM2M_SERVER_PORT 5683
#endif /* LWM2M_SERVER_PORT*/
#ifndef LWM2M_BOOTSTRAP_SERVER_PORT
#define LWM2M_BOOTSTRAP_SERVER_PORT 5783
#endif /* LWM2M_BOOTSTRAP_SERVER_PORT*/
#ifndef LWM2M_SERVER_DTLS_PORT
#define LWM2M_SERVER_DTLS_PORT 5684
#endif /* LWM2M_SERVER_DTLS_PORT*/
#ifndef LWM2M_BOOTSTRAP_SERVER_DTLS_PORT
#define LWM2M_BOOTSTRAP_SERVER_DTLS_PORT 5784
#endif /* LWM2M_BOOTSTRAP_SERVER_DTLS_PORT */
/* LwM2M server ID */
#ifndef LWM2M_SERVER_ID
#define LWM2M_SERVER_ID 1234
#endif /* LWM2M_SERVER_ID */
/* Use DTLS to establish a secure DTLS connection with LwM2M Server or LwM2M Bootstrap Server.
Note: NX_SECURE_ENABLE_DTLS must be defined, and configure the identity and key. */
//#define USE_DTLS
#ifdef NX_SECURE_ENABLE_DTLS
#ifndef LWM2M_DTLS_IDENTITY
#define LWM2M_DTLS_IDENTITY "Identity"
#endif /* LWM2M_DTLS_IDENTITY */
/* LWM2M_DTLS_KEY */
#ifndef LWM2M_DTLS_KEY
#define LWM2M_DTLS_KEY "Key"
#endif /* LWM2M_DTLS_KEY */
#endif /* NX_SECURE_ENABLE_DTLS */
/* Define the ThreadX and NetX object control blocks... */
static NX_PACKET_POOL pool_0;
static NX_IP ip_0;
#ifndef SAMPLE_DHCP_DISABLE
static NX_DHCP dhcp_client;
#endif /* SAMPLE_DHCP_DISABLE */
#ifndef SAMPLE_DNS_DISABLE
static NX_DNS dns_client;
#endif /* SAMPLE_DNS_DISABLE */
/* Define the IP thread's stack area. */
static ULONG ip_thread_stack[2048 / sizeof(ULONG)];
/* Define packet pool for the demonstration. */
static ULONG packet_pool_area[((1536 + sizeof(NX_PACKET)) * 32) / sizeof(ULONG)];
/* Define the ARP cache area. */
static ULONG arp_space_area[512 / sizeof(ULONG)];
/* Define an error counter. */
static ULONG error_counter;
/* Define application thread. */
static TX_THREAD main_thread;
static ULONG main_stack[4096 / sizeof(ULONG)];
#ifdef BOOTSTRAP
static TX_SEMAPHORE semaphore_bootstarp_finish;
#endif /* BOOTSTRAP */
#ifdef NX_SECURE_ENABLE_DTLS
/* Declare the NULL encrypt */
extern NX_CRYPTO_METHOD crypto_method_null;
/* Declare the AES-CCM-8 encrytion method. */
extern NX_CRYPTO_METHOD crypto_method_aes_ccm_8;
/* Declare the SHA256 hash method */
extern NX_CRYPTO_METHOD crypto_method_sha256;
/* Declare the TLSv1.2 default PRF hash method */
extern NX_CRYPTO_METHOD crypto_method_tls_prf_sha256;
/* Declare the MD5 hash method */
extern NX_CRYPTO_METHOD crypto_method_md5;
/* Declare the SHA1 hash method */
extern NX_CRYPTO_METHOD crypto_method_sha1;
/* Declare the TLSv1.0/1.1 PRF hash method */
extern NX_CRYPTO_METHOD crypto_method_tls_prf_1;
/* Declare a placeholder for PSK. */
extern NX_CRYPTO_METHOD crypto_method_auth_psk;
/* Lookup table used to map ciphersuites to cryptographic routines. */
NX_SECURE_TLS_CIPHERSUITE_INFO crypto_ciphersuite_lookup_table[] =
{
/* Ciphersuite, public cipher, public_auth, session cipher & cipher mode, iv size, key size, hash method, hash size, TLS PRF */
{TLS_PSK_WITH_AES_128_CCM_8, &crypto_method_null, &crypto_method_auth_psk, &crypto_method_aes_ccm_8, 16, 16, &crypto_method_null, 0, &crypto_method_tls_prf_sha256},
};
/* Define the object we can pass into TLS. */
const NX_SECURE_TLS_CRYPTO crypto_tls_ciphers =
{
/* Ciphersuite lookup table and size. */
crypto_ciphersuite_lookup_table,
sizeof(crypto_ciphersuite_lookup_table) / sizeof(NX_SECURE_TLS_CIPHERSUITE_INFO),
#ifndef NX_SECURE_DISABLE_X509
/* X.509 certificate cipher table and size. */
NX_NULL,
0,
#endif
#if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
&crypto_method_md5,
&crypto_method_sha1,
&crypto_method_tls_prf_1,
#endif
#if (NX_SECURE_TLS_TLS_1_2_ENABLED)
&crypto_method_sha256,
&crypto_method_tls_prf_sha256
#endif
};
static NX_SECURE_DTLS_SESSION dtls_session;
static UCHAR dtls_metadata_buffer[10 * 1024];
static UCHAR dtls_packet_buffer[5 * 1024];
#endif /* NX_SECURE_ENABLE_DTLS */
#ifndef SAMPLE_DHCP_DISABLE
#define IPV4_ADDRESS IP_ADDRESS(0, 0, 0, 0)
#define IPV4_NETWORK_MASK IP_ADDRESS(0, 0, 0, 0)
#else
#define IPV4_ADDRESS IP_ADDRESS(10, 1, 0, 212)
#define IPV4_NETWORK_MASK IP_ADDRESS(255, 255, 0, 0)
#define IPV4_GATEWAY_ADDR IP_ADDRESS(10, 1, 0, 1)
#define DNS_SERVER_ADDRESS IP_ADDRESS(10, 1, 0, 1)
#endif /* SAMPLE_DHCP_DISABLE */
#ifndef SAMPLE_DNS_DISABLE
static CHAR host_buffer[256];
#endif /* SAMPLE_DNS_DISABLE */
/* Define the Temperature IPSO Resources IDs */
#define IPSO_TEMPERATURE_OBJECT_ID 3303
#define IPSO_RESOURCE_MIN_VALUE 5601
#define IPSO_RESOURCE_MAX_VALUE 5602
#define IPSO_RESOURCE_RESET_MINMAX 5605
#define IPSO_RESOURCE_VALUE 5700
#define IPSO_RESOURCE_UNITS 5701
/* Define the Actuation IPSO Resources IDs */
#define IPSO_ACTUATION_OBJECT_ID 3306
#define IPSO_RESOURCE_ONOFF 5850
/* Define the Temperature Object Instance structure */
typedef struct
{
/* The LWM2M Object Instance */
NX_LWM2M_CLIENT_OBJECT_INSTANCE object_instance;
/* Resources Data */
NX_LWM2M_FLOAT32 temperature;
NX_LWM2M_FLOAT32 min_temperature;
NX_LWM2M_FLOAT32 max_temperature;
} IPSO_TEMPERATURE_INSTANCE;
/* Define the Actuation Object Instance structure */
typedef struct
{
/* The LWM2M Object Instance */
NX_LWM2M_CLIENT_OBJECT_INSTANCE object_instance;
/* Resources Data */
NX_LWM2M_BOOL onoff;
} IPSO_ACTUATION_INSTANCE;
/* LWM2M Client data */
NX_LWM2M_CLIENT client;
ULONG client_stack[4096 / sizeof(ULONG)];
NX_LWM2M_CLIENT_SESSION session;
NX_LWM2M_CLIENT_FIRMWARE firmware;
/* Custom Object Data */
NX_LWM2M_CLIENT_OBJECT temperature_object;
IPSO_TEMPERATURE_INSTANCE temperature_instance;
NX_LWM2M_CLIENT_OBJECT actuation_object;
IPSO_ACTUATION_INSTANCE actuation_instance;
IPSO_ACTUATION_INSTANCE actuation_instance_new;
UINT actuation_instance_new_created = NX_FALSE;
/* Device Object */
const CHAR manufacturer[] = "Microsoft Corporation";
/* Firmware Update Object (emulation) */
int firmware_timer = 0;
int firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_IDLE;
int firmware_version_number = 1;
const CHAR firmware_name[] = "Test Firmware";
CHAR firmware_version[] = "Version 1";
/***** Substitute your ethernet driver entry function here *********/
#ifndef NETWORK_DRIVER
#define NETWORK_DRIVER _nx_ram_network_driver
#endif
extern VOID NETWORK_DRIVER(NX_IP_DRIVER *driver_req_ptr);
#ifndef SAMPLE_DHCP_DISABLE
static void dhcp_wait();
#endif /* SAMPLE_DHCP_DISABLE */
#ifndef SAMPLE_DNS_DISABLE
static UINT dns_create();
#endif /* SAMPLE_DNS_DISABLE */
#ifdef NX_SECURE_ENABLE_DTLS
static UINT dtls_setup(NX_SECURE_DTLS_SESSION *dtls_session_ptr, UCHAR *key, UINT key_len, UCHAR *identity, UINT identity_len);
#endif /* NX_SECURE_ENABLE_DTLS */
static UINT uri_parse(const char *uri, NXD_ADDRESS *ip_addr, UINT *udp_port);
/*
* Custom Object implementations
*/
/* IPSO Temperature */
/* Define the 'Read' Method */
UINT ipso_temperature_read(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
IPSO_TEMPERATURE_INSTANCE *temp = ((IPSO_TEMPERATURE_INSTANCE *) instance_ptr);
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_MIN_VALUE:
/* return the minimum measured temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> min_temperature);
break;
case IPSO_RESOURCE_MAX_VALUE:
/* return the maximum measured temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> max_temperature);
break;
case IPSO_RESOURCE_VALUE:
/* return the temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> temperature);
break;
case IPSO_RESOURCE_RESET_MINMAX:
/* Not readable */
return(NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED);
case IPSO_RESOURCE_UNITS:
/* return the temperature units */
nx_lwm2m_client_resource_string_set(&resource[i], "Cel", 3);
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the 'Discover' method */
UINT ipso_temperature_discover(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resources, UINT *resource_count)
{
if (*resource_count < 5)
{
return(NX_LWM2M_CLIENT_BUFFER_TOO_SMALL);
}
/* return the list of supported resources IDs */
*resource_count = 5;
nx_lwm2m_client_resource_info_set(&resources[0], IPSO_RESOURCE_MIN_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[1], IPSO_RESOURCE_MAX_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[2], IPSO_RESOURCE_RESET_MINMAX, NX_LWM2M_CLIENT_RESOURCE_OPERATION_EXECUTABLE);
nx_lwm2m_client_resource_info_set(&resources[3], IPSO_RESOURCE_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[4], IPSO_RESOURCE_UNITS, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
return(NX_SUCCESS);
}
/* Define the 'Execute' method */
UINT ipso_temperature_execute(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, const CHAR *args_ptr, UINT args_length)
{
IPSO_TEMPERATURE_INSTANCE *temp = ((IPSO_TEMPERATURE_INSTANCE *) instance_ptr);
NX_LWM2M_CLIENT_RESOURCE value;
NX_LWM2M_ID resource_id;
/* Get resource id */
nx_lwm2m_client_resource_info_get(resource, &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_MIN_VALUE:
case IPSO_RESOURCE_MAX_VALUE:
case IPSO_RESOURCE_VALUE:
case IPSO_RESOURCE_UNITS:
/* read-only resource */
return(NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED);
case IPSO_RESOURCE_RESET_MINMAX:
/* reset min/max values to current temperature */
nx_lwm2m_client_resource_float32_set(&value, temp -> temperature);
if (temp -> min_temperature != temp -> temperature)
{
temp -> min_temperature = temp -> temperature;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MIN_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(object_ptr, instance_ptr, &value);
}
if (temp -> max_temperature != temp -> temperature)
{
temp -> max_temperature = temp -> temperature;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MAX_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(object_ptr, instance_ptr, &value);
}
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
return(NX_SUCCESS);
}
/* Define the operation callback function of Temperature Object */
UINT ipso_temperature_operation(UINT operation, NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *object_instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT *resource_count, VOID *args_ptr, UINT args_length)
{
switch (operation)
{
case NX_LWM2M_CLIENT_OBJECT_READ:
/* Call read function */
return ipso_temperature_read(object_ptr, object_instance_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DISCOVER:
/* Call discover function */
return ipso_temperature_discover(object_ptr, object_instance_ptr, resource, resource_count);
case NX_LWM2M_CLIENT_OBJECT_EXECUTE:
/* Call execute function */
return ipso_temperature_execute(object_ptr, object_instance_ptr, resource, args_ptr, args_length);
default:
/*Unsupported operation */
return(NX_LWM2M_CLIENT_NOT_SUPPORTED);
}
}
/* Update the temperature */
void ipso_temperature_update()
{
NX_LWM2M_FLOAT32 temp;
NX_LWM2M_CLIENT_RESOURCE value;
/* Simulate some temperature variation */
switch (NX_RAND() % 10)
{
case 0:
temp = temperature_instance.temperature + 0.1f;
break;
case 1:
temp = temperature_instance.temperature - 0.1f;
break;
default:
temp = temperature_instance.temperature;
break;
}
if (temp != temperature_instance.temperature)
{
/* update object value */
temperature_instance.temperature = temp;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_VALUE, NX_NULL);
nx_lwm2m_client_resource_float32_set(&value, temp);
nx_lwm2m_client_object_resource_changed(&temperature_object, &(temperature_instance.object_instance), &value);
/* update min/max */
if (temp < temperature_instance.min_temperature)
{
temperature_instance.min_temperature = temp;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MIN_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(&temperature_object, &(temperature_instance.object_instance), &value);
}
if (temp > temperature_instance.max_temperature)
{
temperature_instance.max_temperature = temp;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MAX_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(&temperature_object, &(temperature_instance.object_instance), &value);
}
}
}
/* IPSO Actuation */
/* Define the 'Read' Method */
UINT ipso_actuation_read(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
IPSO_ACTUATION_INSTANCE *act = ((IPSO_ACTUATION_INSTANCE *) instance_ptr);
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_ONOFF:
/* return the on/off value */
nx_lwm2m_client_resource_boolean_set(&resource[i], act -> onoff);
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the 'Discover' method */
UINT ipso_actuation_discover(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resources, UINT *resource_count)
{
if (*resource_count < 1)
{
return(NX_LWM2M_CLIENT_BUFFER_TOO_SMALL);
}
/* return the list of supported resources IDs */
*resource_count = 1;
nx_lwm2m_client_resource_info_set(&resources[0], IPSO_RESOURCE_ONOFF, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ_WRITE);
return(NX_SUCCESS);
}
/* Define the 'Write' method */
UINT ipso_actuation_write(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count, UINT flags)
{
IPSO_ACTUATION_INSTANCE *act = ((IPSO_ACTUATION_INSTANCE *) instance_ptr);
UINT ret;
NX_LWM2M_BOOL onoff;
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_ONOFF:
/* assign on/off boolean value */
ret = nx_lwm2m_client_resource_boolean_get(&resource[i], &onoff);
if (ret != NX_SUCCESS)
{
/* invalid value type */
return(ret);
}
if (onoff != act->onoff)
{
act->onoff = onoff;
printf("Set actuation switch %s\n", onoff ? "On" : "Off");
}
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the 'Create' method */
UINT ipso_actuation_create(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_ID *instance_id, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
UINT status;
/* Check if there is free instance */
if (actuation_instance_new_created)
{
return(NX_LWM2M_CLIENT_NO_MEMORY);
}
status = ipso_actuation_write(object_ptr, &(actuation_instance_new.object_instance), resource, resource_count, NX_NULL);
if (status)
{
return(status);
}
/* Add a new instance */
status = nx_lwm2m_client_object_instance_add(object_ptr, &(actuation_instance_new.object_instance), instance_id);
if (status)
{
return(status);
}
actuation_instance_new_created = NX_TRUE;
return(NX_SUCCESS);
}
/* Define the 'Delete' method */
UINT ipso_actuation_delete(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr)
{
UINT status;
/* Only support deleting the created new instance */
if (!actuation_instance_new_created || instance_ptr != &(actuation_instance_new.object_instance))
{
return(NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED);
}
/* Remove the instance from instance list */
status = nx_lwm2m_client_object_instance_remove(object_ptr, instance_ptr);
if (status)
{
return(status);
}
actuation_instance_new_created = NX_FALSE;
return(status);
}
/* Define the operation callback function of Actuation Object */
UINT ipso_actuation_operation(UINT operation, NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *object_instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT *resource_count, VOID *args_ptr, UINT args_length)
{
UINT write_op;
switch (operation)
{
case NX_LWM2M_CLIENT_OBJECT_READ:
/* Call read function */
return ipso_actuation_read(object_ptr, object_instance_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DISCOVER:
/* Call discover function */
return ipso_actuation_discover(object_ptr, object_instance_ptr, resource, resource_count);
case NX_LWM2M_CLIENT_OBJECT_WRITE:
/* Get the type of write operation */
write_op = *(UINT *)args_ptr;
/* Call write function */
return ipso_actuation_write(object_ptr, object_instance_ptr, resource, *resource_count, write_op);
case NX_LWM2M_CLIENT_OBJECT_CREATE:
/* Call create function */
return ipso_actuation_create(object_ptr, (NX_LWM2M_ID *)args_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DELETE:
/* Call delete function */
return ipso_actuation_delete(object_ptr, object_instance_ptr);
default:
/* Unsupported operation */
return(NX_LWM2M_CLIENT_NOT_SUPPORTED);
}
}
/* Define the 'Read' method */
UINT device_read(NX_LWM2M_CLIENT *client_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case NX_LWM2M_CLIENT_DEVICE_MANUFACTURER_ID:
/* return 'Manufacturer' string */
nx_lwm2m_client_resource_string_set(&resource[i], (CHAR *)manufacturer, sizeof(manufacturer) - 1);
break;
default:
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the operation callback function of Device Object */
UINT device_operation(UINT operation, NX_LWM2M_CLIENT *client_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT *resource_count, VOID *args_ptr, UINT args_length)
{
switch (operation)
{
case NX_LWM2M_CLIENT_OBJECT_READ:
/* Call read function */
return device_read(client_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DISCOVER:
/* Call discover function */
*resource_count = 1;
nx_lwm2m_client_resource_info_set(resource, NX_LWM2M_CLIENT_DEVICE_MANUFACTURER_ID, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
return(NX_SUCCESS);
default:
/* Unsupported operation */
return(NX_LWM2M_CLIENT_NOT_SUPPORTED);
}
}
/* Firmware Package URI callback */
UINT firmware_package_uri(NX_LWM2M_CLIENT_FIRMWARE *firmware_ptr, const CHAR *uri, UINT uri_length)
{
if (uri_length == 0)
{
printf("Firmware package URI: Cancel Download\n");
/* cancel package download */
firmware_timer = 0;
firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_IDLE;
nx_lwm2m_client_firmware_state_set(firmware_ptr, NX_LWM2M_CLIENT_FIRMWARE_STATE_IDLE);
nx_lwm2m_client_firmware_result_set(firmware_ptr, NX_LWM2M_CLIENT_FIRMWARE_RESULT_INIT);
}
else if (firmware_timer != 0)
{
printf("Firmware package URI: Download already in progress!\n");
/* download in progress */
return(NX_LWM2M_CLIENT_NOT_ACCEPTABLE);
}
else
{
static CHAR tmp[256];
if (uri_length > 255)
{
uri_length = 255;
}
if (uri_length > 0)
{
memcpy(tmp, uri, uri_length); /* Use case of memcpy is verified. */
}
tmp[uri_length] = 0;
printf("Firmware package URI: start downloading '%s'...\n", tmp);
/* Emulate the firmware "downloading" */
firmware_timer = 30;
firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADING;
nx_lwm2m_client_firmware_state_set(firmware_ptr, NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADING);
nx_lwm2m_client_firmware_result_set(firmware_ptr, NX_LWM2M_CLIENT_FIRMWARE_RESULT_INIT);
}
return(NX_SUCCESS);
}
/* Firmware Update callback */
UINT firmware_update(NX_LWM2M_CLIENT_FIRMWARE *firmware_ptr, NX_LWM2M_BOOL update_objects, const CHAR *args_ptr, UINT args_length)
{
if (firmware_state == NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADED)
{
printf("Firmware update: start updating firmware...\n");
/* Emulate the firmware "updating" */
firmware_timer = 15;
firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_UPDATING;
nx_lwm2m_client_firmware_state_set(firmware_ptr, NX_LWM2M_CLIENT_FIRMWARE_STATE_UPDATING);
return(NX_SUCCESS);
}
printf("Firmware update: cannot update firmware: invalid state.\n");
return(NX_LWM2M_CLIENT_NOT_ACCEPTABLE);
}
/* Update the firmware state */
void firmware_state_update()
{
/* firmware update timers */
if (firmware_timer != 0)
{
if (--firmware_timer == 0)
{
if (firmware_state == NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADING)
{
printf("Firmware update: package downloaded!\n");
firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADED;
nx_lwm2m_client_firmware_state_set(&firmware, NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADED);
}
else
{
printf("Firmware update: updated!\n");
firmware_state = NX_LWM2M_CLIENT_FIRMWARE_STATE_IDLE;
nx_lwm2m_client_firmware_state_set(&firmware, NX_LWM2M_CLIENT_FIRMWARE_STATE_IDLE);
nx_lwm2m_client_firmware_result_set(&firmware, NX_LWM2M_CLIENT_FIRMWARE_RESULT_SUCCESS);
/* Update firmware version */
firmware_version_number++;
firmware_version[sizeof(firmware_version) - 2] = firmware_version_number + '0';
nx_lwm2m_client_firmware_package_info_set(&firmware, firmware_name, sizeof(firmware_name) - 1, firmware_version, sizeof(firmware_version) - 1);
}
}
else if (firmware_timer % 5 == 0)
{
printf("Firmware update: %s...\n", firmware_state == NX_LWM2M_CLIENT_FIRMWARE_STATE_DOWNLOADING ? "downloading" : "updating");
}
}
}
/* Define the session state callback */
void session_callback(NX_LWM2M_CLIENT_SESSION *session_ptr, UINT state)
{
printf("LWM2M Callback: -> %d\n", state);
switch (state)
{
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_REQUESTING:
printf("Start client initiated bootstrap\n");
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_INITIATED:
printf("Got message from boostrap server\n");
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_FINISHED:
/* Bootstrap session done, we can register to the LWM2M Server */
printf( "Boostrap finished.\n");
#ifdef BOOTSTRAP
tx_semaphore_put(&semaphore_bootstarp_finish);
#endif
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_ERROR:
/* Failed to Bootstrap the LWM2M Client. */
printf( "Failed to boostrap device, error=%02x\n", nx_lwm2m_client_session_error_get(session_ptr));
break;
case NX_LWM2M_CLIENT_SESSION_REGISTERED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device registered.\n");
break;
case NX_LWM2M_CLIENT_SESSION_DISABLED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device disabled.\n");
break;
case NX_LWM2M_CLIENT_SESSION_DEREGISTERED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device deregistered.\n");
break;
case NX_LWM2M_CLIENT_SESSION_ERROR:
/* Failed to register to the LWM2M Client. */
printf( "Failed to register device, error=%02x\n", nx_lwm2m_client_session_error_get(session_ptr));
break;
}
}
/* Application main thread */
void application_thread(ULONG info)
{
NX_LWM2M_ID server_id = 0;
NXD_ADDRESS server_addr;
UINT udp_port = 0;
UINT status;
#if NX_LWM2M_CLIENT_MAX_SECURITY_INSTANCES && defined (BOOTSTRAP)
CHAR *server_uri = NX_NULL;
UINT server_uri_len = 0;
UCHAR security_mode = 0;
#ifdef USE_DTLS
UCHAR *pub_key_or_id = NX_NULL;
UINT pub_key_or_id_len = 0;
UCHAR *secret_key = NX_NULL;
UINT secret_key_len = 0;
#endif /* USE_DTLS */
#endif /* BOOTSTRAP */
#ifndef SAMPLE_DHCP_DISABLE
dhcp_wait();
#endif /* SAMPLE_DHCP_DISABLE */
#ifndef SAMPLE_DNS_DISABLE
/* Create DNS instance. */
dns_create();
#endif /* SAMPLE_DNS_DISABLE */
/* Create the LWM2M client */
status = nx_lwm2m_client_create(&client, &ip_0, &pool_0, LWM2M_CLIENT_ENDPOINT, sizeof(LWM2M_CLIENT_ENDPOINT) - 1, NX_NULL, 0, NX_LWM2M_CLIENT_BINDING_U, client_stack, sizeof(client_stack), 4);
if (status)
{
return;
}
/* Define our custom objects: */
/* Add Temperature Object */
status = nx_lwm2m_client_object_add(&client, &temperature_object, IPSO_TEMPERATURE_OBJECT_ID, ipso_temperature_operation);
if (status)
{
return;
}
/* Define a single instance */
temperature_instance.temperature = 22.5f;
temperature_instance.min_temperature = temperature_instance.temperature;
temperature_instance.max_temperature = temperature_instance.temperature;
status = nx_lwm2m_client_object_instance_add(&temperature_object, &temperature_instance.object_instance, NX_NULL);
if (status)
{
return;
}
/* Add Actuation Object */
status = nx_lwm2m_client_object_add(&client, &actuation_object, IPSO_ACTUATION_OBJECT_ID, ipso_actuation_operation);
if (status)
{
return;
}
/* Define a single instance */
actuation_instance.onoff = NX_FALSE;
status = nx_lwm2m_client_object_instance_add(&actuation_object, &actuation_instance.object_instance, NX_NULL);
if (status)
{
return;
}
/* Add firmware update object */
status = nx_lwm2m_client_firmware_create(&firmware, &client, NX_LWM2M_CLIENT_FIRMWARE_PROTOCOL_HTTP|NX_LWM2M_CLIENT_FIRMWARE_PROTOCOL_HTTPS, NX_NULL, firmware_package_uri, firmware_update);
if (status)
{
return;
}
/* Set firmware info */
nx_lwm2m_client_firmware_package_info_set(&firmware, firmware_name, sizeof(firmware_name) - 1, firmware_version, sizeof(firmware_version) - 1);
/* Setup device object callback */
nx_lwm2m_client_device_callback_set(&client, device_operation);
/* Create a session */
status = nx_lwm2m_client_session_create(&session, &client, session_callback);
if (status)
{
return;
}
/* start bootstrap/lwm2m session */
server_addr.nxd_ip_version = NX_IP_VERSION_V4;
server_addr.nxd_ip_address.v4 = LWM2M_SERVER_ADDRESS;
#ifdef NX_SECURE_ENABLE_DTLS
/* Create the DTLS Client Session. */
dtls_setup(&dtls_session, LWM2M_DTLS_KEY, sizeof(LWM2M_DTLS_KEY) - 1, LWM2M_DTLS_IDENTITY, sizeof(LWM2M_DTLS_IDENTITY) - 1);
#endif /* NX_SECURE_ENABLE_DTLS */
#if NX_LWM2M_CLIENT_MAX_SECURITY_INSTANCES && defined (BOOTSTRAP)
#ifdef USE_DTLS
printf("Start boostraping with DTLS\r\n");
status = nx_lwm2m_client_session_bootstrap_dtls(&session, 0, &server_addr, LWM2M_BOOTSTRAP_SERVER_DTLS_PORT, &dtls_session);
#else
printf("Start boostraping\r\n");
status = nx_lwm2m_client_session_bootstrap(&session, 0, &server_addr, LWM2M_BOOTSTRAP_SERVER_PORT);
#endif
if (status)
{
return;
}
tx_semaphore_get(&semaphore_bootstarp_finish, NX_WAIT_FOREVER);
/* Get the info for register */
#ifdef USE_DTLS
status = nx_lwm2m_client_session_register_info_get(&session, NX_LWM2M_CLIENT_RESERVED_ID, &server_id, &server_uri, &server_uri_len, &security_mode, &pub_key_or_id, &pub_key_or_id_len, NX_NULL, NX_NULL, &secret_key, &secret_key_len);
if (status || (security_mode != NX_LWM2M_CLIENT_SECURITY_MODE_PRE_SHARED_KEY))
{
return;
}
#else
status = nx_lwm2m_client_session_register_info_get(&session, NX_LWM2M_CLIENT_RESERVED_ID, &server_id, &server_uri, &server_uri_len, &security_mode, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL);
if (status || (security_mode != NX_LWM2M_CLIENT_SECURITY_MODE_NOSEC))
{
return;
}
#endif
printf("Got LWM2M server info, uri='%s', id=%d\r\n", server_uri, server_id);
/* Get IP address and UDP port from server URI */
status = uri_parse(server_uri, &server_addr, &udp_port);
if (status)
{
return;
}
#ifdef USE_DTLS
/* Re-create the DTLS Client Session. */
nx_secure_dtls_session_delete(&dtls_session);
dtls_setup(&dtls_session, secret_key, secret_key_len, pub_key_or_id, pub_key_or_id_len);
#endif /* USE_DTLS */
#else /* !BOOTSTRAP */
/* Set the info for register */