#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#define LOCATION_OBJ_ID (6)
#define LOCATION_OBJ_LATITUDE_RES_ID (0)
#define LOCATION_OBJ_LONGITUDE_RES_ID (1)
#define LOCATION_OBJ_TIMESTAMP_RES_ID (5)
#define ONE_SECOND (1000)
#define LIFETIME (60)
#define SERVER_OBJ_ID (1)
#define SERVER_OBJ_SHORT_RES_ID (0)
#define SERVER_OBJ_LIFETIME_RES_ID (1)
#define SERVER_OBJ_BINDING_RES_ID (7)
#define SERVER_OBJ_REGISTRATION_UPDATE_RES_ID (8)
#define ACCESS_CONTROL_OBJ_ID (2)
#define ACCESS_CONTROL_OBJ_OBJECT_RES_ID (0)
#define ACCESS_CONTROL_OBJ_INSTANCE_RES_ID (1)
#define ACCESS_CONTROL_OBJ_ACL_RES_ID (2)
#define ACCESS_CONTROL_OBJ_OWNER_RES_ID (3)
#define SECURITY_OBJ_ID (0)
#define SECURITY_SERVER_URI_RES_ID (0)
#define SECURITY_IS_BOOTSTRAP_RES_ID (1)
#define SECURITY_SECURITY_MODE_RES_ID (2)
#define SECURITY_PUBLIC_KEY_OR_IDENTITY_RES_ID (3)
#define SECURITY_SERVER_PUBLIC_KEY_RES_ID (4)
#define SECURITY_SECRET_KEY_RES_ID (5)
#define SECURITY_SERVER_ID_RES_ID (10)
#define SECURITY_CLIENT_HOLD_OFF_TIME_RES_ID (11)
#define SECURITY_BOOTSTRAP_SERVER_ACCOUNT_TIMEOUT_RES_ID (12)
#define PSK_KEY_LEN 16
#define RPK_PRIVATE_KEY_LEN 32
#define RPK_PUBLIC_KEY_LEN (2 * RPK_PRIVATE_KEY_LEN)
#define CLIENT_BS_PSK_ID ("cli1-bs")
#define CLIENT_BS_PSK_KEY ("FEDCBA9876543210")
#define CLIENT_SERVER_PSK_ID ("cli1")
#define CLIENT_SERVER_PSK_KEY ("0123456789ABCDEF")
#define CLIENT_PRIVATE_KEY ("D9E2707A72DA6A0504995C86EDDBE3EFC7F1CD74838F7570C8072D0A76261BD4")
#define CLIENT_PUBLIC_KEY ("D055EE14084D6E0615599DB583913E4A3E4526A2704D61F27A4CCFBA9758EF9A" \
"B418B64AFE8030DA1DDCF4F42E2F2631D043B1FB03E22F4D17DE43F9F9ADEE70")
#define BS_SERVER_PUBLIC_KEY ("cd4110e97bbd6e7e5a800028079d02915c70b915ea4596402098deea585eb7ad" \
"f3e080487327f70758b13bc0583f4293d13288a0164a8e324779aa4f7ada26c1")
#define SERVER_PUBLIC_KEY ("3b88c213ca5ccfd9c5a7f73715760d7d9a5220768f2992d2628ae1389cbca4c6" \
"d1b73cc6d61ae58783135749fb03eaaa64a7a1adab8062ed5fc0d7b86ba2d5ca")
};
};
};
};
};
};
.parent = NULL,
.mem = (void *)"coaps://localhost:5783",
.
size =
sizeof(
"coaps://localhost:5783") - 1,
.refcnt = 1
};
.parent = NULL,
.mem = (void *)"coap://localhost:5683",
.
size =
sizeof(
"coap://localhost:5683") - 1,
.refcnt = 1
};
.parent = NULL,
.mem = (void *)"coaps://localhost:5684",
.
size =
sizeof(
"coaps://localhost:5684") - 1,
.refcnt = 1
};
.parent = NULL,
.mem = (void *)"U",
.refcnt = 1
};
{
int r;
char *str;
r = asprintf(&str, "%g", d);
if (r < 0) {
fprintf(stderr, "Could not convert the latitude/longitude to string\n");
return NULL;
}
if (!blob) {
fprintf(stderr, "Could not create a blob to store the latitude/longitude\n");
free(str);
return NULL;
}
return blob;
}
static bool
{
int r = 0;
static const char *paths[] = { "/6/0/0",
"/6/0/1", "/6/0/5", NULL };
instance_ctx->
latitude = ((double)rand() / (double)RAND_MAX);
instance_ctx->
longitude = ((double)rand() / (double)RAND_MAX);
instance_ctx->
timestamp = (int64_t)time(NULL);
printf(
"New latitude: %g - New longitude: %g\n", instance_ctx->
latitude,
if (r < 0) {
fprintf(stderr, "Could not notify the observers\n");
} else
printf("Sending new location coordinates to the observers\n");
return true;
}
static int
{
int r;
uint16_t i;
fprintf(stderr, "Only one location object instance is allowed\n");
return -EINVAL;
}
fprintf(stderr, "Content type is not in TLV format\n");
return -EINVAL;
}
if (!instance_ctx) {
fprintf(stderr, "Could not alloc memory for location object context\n");
return -ENOMEM;
}
instance_ctx);
fprintf(stderr, "Could not create the client timer\n");
r = -ENOMEM;
goto err_free_instance;
}
r = -EINVAL;
fprintf(stderr, "Missing mandatory fields.\n");
goto err_free_timeout;
}
double *prop = NULL;
} else
if (r < 0) {
fprintf(stderr, "Could not get the tlv value for resource %"
goto err_free_timeout;
}
if (buf.used) {
char *endptr = NULL;
if (errno != 0 || endptr == buf.data) {
r = -EINVAL;
fprintf(stderr, "Could not copy the longitude/latitude"
" property\n");
goto err_free_timeout;
}
}
}
instance_ctx->
client = client;
*instance_data = instance_ctx;
printf("Location object created\n");
return 0;
err_free_timeout:
err_free_instance:
free(instance_ctx);
return r;
}
static int
{
int r;
switch (res_id) {
break;
break;
break;
default:
if (res_id >= 2 && res_id <= 4)
r = -ENOENT;
else
r = -EINVAL;
}
return r;
}
static int
{
int r;
switch (res_id) {
break;
break;
break;
r = -ENOENT;
else
break;
r = -ENOENT;
else
break;
r = -ENOENT;
else
break;
break;
break;
break;
default:
if (res_id >= 6 && res_id <= 9)
r = -ENOENT;
else
r = -EINVAL;
}
return r;
}
static int
{
int r = 0;
break;
break;
break;
break;
break;
break;
break;
break;
break;
default:
if (res->
id >= 6 && res->
id <= 9)
r = -ENOENT;
else
r = -EINVAL;
}
if (r >= 0)
printf("Resource written to Security object at /0/%" PRIu16 "/%" PRIu16 "\n",
return r;
}
static int
{
int r = 0;
uint16_t i;
if (r < 0)
return r;
return -EINVAL;
break;
if (r < 0)
return r;
break;
if (r < 0)
return r;
break;
if (r < 0)
return r;
return -EINVAL;
break;
if (r < 0)
return r;
return -EINVAL;
break;
if (r < 0)
return r;
return -EINVAL;
break;
if (r < 0)
return r;
break;
if (r < 0)
return r;
break;
if (r < 0)
return r;
break;
default:
fprintf(stderr, "tlv type: %u, ID: %" PRIu16 ", Size: %zu, Content: %.*s"
" could not be written to Security Server Object at /0/%" PRIu16,
return -EINVAL;
}
}
if (tlvs->
len == 1 && r >= 0)
printf("TLV written to Security object at /1/%" PRIu16 "/%" PRIu16 "\n",
else
printf("TLV written to Security object at /1/%" PRIu16 "\n", instance_id);
return r;
}
static int
uint16_t instance_id, void **instance_data,
{
int r;
uint16_t i;
fprintf(stderr, "Content type is not in TLV format\n");
return -EINVAL;
}
if (!instance_ctx) {
fprintf(stderr, "Could not alloc memory for security object context\n");
return -ENOMEM;
}
if (r < 0)
goto err_free_instance;
fprintf(stderr, "Could not set server_uri resource\n");
goto err_free_instance;
}
if (r < 0)
goto err_free_instance;
fprintf(stderr, "Could not set public_key_or_id resource\n");
goto err_free_instance;
}
if (r < 0)
goto err_free_instance;
fprintf(stderr, "Could not set server_public_key resource\n");
goto err_free_instance;
}
if (r < 0)
goto err_free_instance;
fprintf(stderr, "Could not set secret_key resource\n");
goto err_free_instance;
}
}
if (r < 0) {
fprintf(stderr, "Could not get the tlv value for resource %"
goto err_free_instance;
}
}
instance_ctx->
client = client;
*instance_data = instance_ctx;
printf("Security object created at /0/%" PRIu16 "\n", instance_id);
return 0;
err_free_instance:
free(instance_ctx);
return r;
}
static int
{
free(instance_ctx);
return 0;
}
static int
{
int r;
switch (res_id) {
break;
break;
break;
default:
if (res_id >= 2 && res_id <= 6)
r = -ENOENT;
else
r = -EINVAL;
}
return r;
}
static int
{
int r = 0;
break;
break;
break;
default:
if (res->
id >= 2 && res->
id <= 6)
r = -ENOENT;
else
r = -EINVAL;
}
if (r >= 0)
printf("Resource written to Server object at /1/%" PRIu16 "/%" PRIu16 "\n",
return r;
}
static int
{
int r = 0;
uint16_t i;
if (r < 0)
return r;
break;
if (r < 0)
return r;
break;
if (r < 0)
return r;
return -EINVAL;
break;
default:
fprintf(stderr, "tlv type: %u, ID: %" PRIu16 ", Size: %zu, Content: %.*s"
" could not be written to Server Object at /1/%" PRIu16,
return -EINVAL;
}
}
if (tlvs->
len == 1 && r >= 0)
printf("TLV written to Server object at /1/%" PRIu16 "/%" PRIu16 "\n",
else
printf("TLV written to Server object at /1/%" PRIu16 "\n", instance_id);
return r;
}
static int
uint16_t instance_id, void **instance_data,
{
int r;
uint16_t i;
fprintf(stderr, "Content type is not in TLV format\n");
return -EINVAL;
}
if (!instance_ctx) {
fprintf(stderr, "Could not alloc memory for server object context\n");
return -ENOMEM;
}
if (r < 0)
goto err_free_instance;
fprintf(stderr, "Could not set binding resource\n");
goto err_free_instance;
}
}
if (r < 0) {
fprintf(stderr, "Could not get the tlv value for resource %"
goto err_free_instance;
}
}
instance_ctx->
client = client;
*instance_data = instance_ctx;
printf("Server object created at /1/%" PRIu16 "\n", instance_id);
return 0;
err_free_instance:
free(instance_ctx);
return r;
}
static int
{
return -EINVAL;
}
static int
{
free(instance_ctx);
return 0;
}
static int
{
free(instance_ctx);
return 0;
}
static int
{
int r;
uint16_t i;
struct sol_lwm2m_resource_data *res_data;
return -ENOENT;
res_data->id = acl_item->
key;
res_data->content.integer = acl_item->
value;
}
} else {
r = -EINVAL;
}
return r;
}
static int
{
int r = 0;
uint16_t i;
break;
break;
if (!acl_item) {
fprintf(stderr, "Could not alloc memory for access control list Resource Instance\n");
r = -ENOMEM;
goto err_free_acl;
}
printf(
"<<[WRITE_RES]<< acl[%" PRIu16
"]=%" PRId64
">>>>\n", acl_item->
key, acl_item->
value);
}
} else {
r = -EINVAL;
}
break;
break;
default:
r = -EINVAL;
}
if (r >= 0)
printf("Resource written to Access Control object at /2/%" PRIu16 "/%" PRIu16 "\n",
return r;
err_free_acl:
return r;
}
static int
struct sol_vector *tlvs, uint16_t *j,
bool is_create)
{
int64_t res_val;
int r;
if (r < 0)
return r;
if (!acl_item) {
fprintf(stderr, "Could not alloc memory for access control list Resource Instance\n");
return -ENOMEM;
}
acl_item->
key = res_tlv->
id;
acl_item->
value = res_val;
if (is_create)
printf(
"<<[CREATE]<< acl[%" PRIu16
"]=%" PRId64
">>>>\n", acl_item->
key, acl_item->
value);
else
printf(
"<<[WRITE_TLV]<< acl[%" PRIu16
"]=%" PRId64
">>>>\n", acl_item->
key, acl_item->
value);
(*j)++;
}
return 0;
}
static int
{
int r = -EINVAL;
uint16_t i;
if (r < 0)
return r;
if (r < 0)
return r;
uint16_t j = i + 1;
if (r < 0)
goto err_free_acl;
i = j - 1;
if (r < 0)
return r;
} else {
fprintf(stderr, "tlv type: %u, ID: %" PRIu16 ", Size: %zu, Content: %.*s"
" could not be written to Access Control Object at /2/%" PRIu16,
return -EINVAL;
}
}
if (tlvs->
len == 1 && r >= 0)
printf("TLV written to Access Control object at /2/%" PRIu16 "/%" PRIu16 "\n",
else
printf("TLV written to Access Control object at /2/%" PRIu16 "\n", instance_id);
return r;
err_free_acl:
return r;
}
static int
uint16_t instance_id, void **instance_data,
{
int r;
uint16_t i;
fprintf(stderr, "Content type is not in TLV format\n");
return -EINVAL;
}
if (!instance_ctx) {
fprintf(stderr, "Could not alloc memory for access control object context\n");
return -ENOMEM;
}
uint16_t j = i + 1;
if (r < 0)
goto err_free_acl;
i = j - 1;
}
if (r < 0) {
fprintf(stderr, "Could not get the tlv value for resource %"
goto err_free_acl;
}
}
instance_ctx->
client = client;
*instance_data = instance_ctx;
printf("Access Control object created at /2/%" PRIu16 "\n\n", instance_id);
return 0;
err_free_acl:
free(instance_ctx);
return r;
}
static int
{
free(instance_ctx);
return 0;
}
static void
{
printf("...<Call local Bootstrap clean-up operations>...\n"
"...<Now that it should have a Server, try to register again>\n");
fprintf(stderr, "Bootstrap Request or Bootstrap Finish Failed!\n");
}
}
.resources_count = 6
};
.resources_count = 12,
};
.resources_count = 9,
};
.resources_count = 4,
};
int
main(
int argc,
char *argv[])
{
int r;
struct sol_blob *public_key_or_id, *server_public_key, *secret_key;
char *cli_name = NULL;
srand(time(NULL));
snprintf(usage, sizeof(usage), "Usage: ./lwm2m-sample-client <client-name> [-b] [-s SEC_MODE]\n"
"Where Factory Bootstrap is default and SEC_MODE is an integer as per:\n"
"\tPRE_SHARED_KEY=%d\n"
"\tRAW_PUBLIC_KEY=%d\n"
"\tCERTIFICATE=%d\n"
"\tNO_SEC=%d (default)\n",
while ((r = getopt(argc, argv, "bs:")) != -1) {
switch (r) {
case 'b':
break;
case 's':
sec_mode = atoi(optarg);
if (sec_mode < 0 || sec_mode > 3) {
fprintf(stderr, "%s", usage);
return -1;
}
break;
default:
fprintf(stderr, "%s", usage);
return -1;
}
}
cli_name = argv[optind];
if (!cli_name) {
fprintf(stderr, "%s", usage);
return -1;
}
fprintf(stderr, "Non-Factory Bootstrap Mode needs DTLS security enabled\n");
return -1;
}
switch (sec_mode) {
} else {
}
server_public_key = NULL;
break;
} else {
}
break;
fprintf(stderr, "Certificate security mode is not supported yet.\n");
return -1;
default:
public_key_or_id = NULL;
server_public_key = NULL;
secret_key = NULL;
break;
}
if (!client) {
r = -1;
fprintf(stderr, "Could not the create the LWM2M client\n");
goto exit;
}
if (!security_data) {
fprintf(stderr, "Could not alloc memory for security object context\n");
r = -ENOMEM;
goto exit_del;
}
security_data->
client = client;
if (!server_data) {
fprintf(stderr, "Could not alloc memory for server object context\n");
r = -ENOMEM;
goto exit_del;
}
if (r < 0) {
fprintf(stderr, "Could not add a server object instance\n");
goto exit_del;
}
&server_addr_coap : &server_addr_dtls;
} else {
NULL);
if (r < 0) {
fprintf(stderr, "Could not add a bootstrap monitor\n");
goto exit_del;
}
}
if (r < 0) {
fprintf(stderr, "Could not add a security object instance\n");
goto exit_del;
}
r = 0;
exit_del:
free(security_data);
free(server_data);
exit:
return r;
}