blob: b73ec82b475caae88fbe9ff8f334c71815686758 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <assert.h>
#include <string.h>
#include "os/mynewt.h"
#include <hal/hal_system.h>
#include <hal/hal_watchdog.h>
#include <mgmt/mgmt.h>
#include <console/console.h>
#include <datetime/datetime.h>
#if MYNEWT_VAL(TIMEPERSIST)
#include <timepersist/timepersist.h>
#endif
#include "smp_os/smp_os.h"
#include <tinycbor/cbor.h>
#include <cborattr/cborattr.h>
static int smp_def_console_echo(struct mgmt_ctxt *cb);
static int smp_def_mpstat_read(struct mgmt_ctxt *cb);
static int smp_datetime_get(struct mgmt_ctxt *cb);
static int smp_datetime_set(struct mgmt_ctxt *cb);
static const struct mgmt_handler smp_def_group_handlers[] = {
[SMP_ID_CONS_ECHO_CTRL] = {
smp_def_console_echo, smp_def_console_echo
},
[SMP_ID_MPSTATS] = {
smp_def_mpstat_read, NULL
},
[SMP_ID_DATETIME_STR] = {
smp_datetime_get, smp_datetime_set
},
};
#define SMP_DEF_GROUP_SZ \
(sizeof(smp_def_group_handlers) / sizeof(smp_def_group_handlers[0]))
static struct mgmt_group smp_def_group = {
.mg_handlers = (struct mgmt_handler *)smp_def_group_handlers,
.mg_handlers_count = SMP_DEF_GROUP_SZ,
.mg_group_id = MGMT_GROUP_ID_OS
};
static int
smp_def_console_echo(struct mgmt_ctxt *cb)
{
long long int echo_on = 1;
int rc;
struct cbor_attr_t attrs[2] = {
[0] = {
.attribute = "echo",
.type = CborAttrIntegerType,
.addr.integer = &echo_on,
.nodefault = 1
},
[1] = { 0 },
};
rc = cbor_read_object(&cb->it, attrs);
if (rc) {
return MGMT_ERR_EINVAL;
}
if (echo_on) {
console_echo(1);
} else {
console_echo(0);
}
return (0);
}
static int
smp_def_mpstat_read(struct mgmt_ctxt *cb)
{
struct os_mempool *prev_mp;
struct os_mempool_info omi;
CborError g_err = CborNoError;
CborEncoder pools;
CborEncoder pool;
g_err |= cbor_encode_text_stringz(&cb->encoder, "rc");
g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK);
g_err |= cbor_encode_text_stringz(&cb->encoder, "mpools");
g_err |= cbor_encoder_create_map(&cb->encoder, &pools,
CborIndefiniteLength);
prev_mp = NULL;
while (1) {
prev_mp = os_mempool_info_get_next(prev_mp, &omi);
if (prev_mp == NULL) {
break;
}
g_err |= cbor_encode_text_stringz(&pools, omi.omi_name);
g_err |= cbor_encoder_create_map(&pools, &pool, CborIndefiniteLength);
g_err |= cbor_encode_text_stringz(&pool, "blksiz");
g_err |= cbor_encode_uint(&pool, omi.omi_block_size);
g_err |= cbor_encode_text_stringz(&pool, "nblks");
g_err |= cbor_encode_uint(&pool, omi.omi_num_blocks);
g_err |= cbor_encode_text_stringz(&pool, "nfree");
g_err |= cbor_encode_uint(&pool, omi.omi_num_free);
g_err |= cbor_encode_text_stringz(&pool, "min");
g_err |= cbor_encode_uint(&pool, omi.omi_min_free);
g_err |= cbor_encoder_close_container(&pools, &pool);
}
g_err |= cbor_encoder_close_container(&cb->encoder, &pools);
if (g_err) {
return MGMT_ERR_ENOMEM;
}
return (0);
}
static int
smp_datetime_get(struct mgmt_ctxt *cb)
{
struct os_timeval tv;
struct os_timezone tz;
char buf[DATETIME_BUFSIZE];
int rc;
CborError g_err = CborNoError;
g_err |= cbor_encode_text_stringz(&cb->encoder, "rc");
g_err |= cbor_encode_int(&cb->encoder, MGMT_ERR_EOK);
/* Display the current datetime */
rc = os_gettimeofday(&tv, &tz);
assert(rc == 0);
rc = datetime_format(&tv, &tz, buf, DATETIME_BUFSIZE);
if (rc) {
rc = MGMT_ERR_EINVAL;
goto err;
}
g_err |= cbor_encode_text_stringz(&cb->encoder, "datetime");
g_err |= cbor_encode_text_stringz(&cb->encoder, buf);
if (g_err) {
return MGMT_ERR_ENOMEM;
}
return 0;
err:
return (rc);
}
static int
smp_datetime_set(struct mgmt_ctxt *mc)
{
struct os_timeval tv;
struct os_timezone tz;
char buf[DATETIME_BUFSIZE];
int rc = 0;
const struct cbor_attr_t datetime_write_attr[] = {
[0] = {
.attribute = "datetime",
.type = CborAttrTextStringType,
.addr.string = buf,
.len = sizeof(buf),
},
{ 0 },
};
rc = cbor_read_object(&mc->it, datetime_write_attr);
if (rc) {
return MGMT_ERR_EINVAL;
}
/* Set the current datetime */
rc = datetime_parse(buf, &tv, &tz);
if (!rc) {
rc = os_settimeofday(&tv, &tz);
if (rc) {
return MGMT_ERR_EINVAL;
}
#if MYNEWT_VAL(TIMEPERSIST)
timepersist();
#endif
} else {
return MGMT_ERR_EINVAL;
}
rc = mgmt_write_rsp_status(mc, 0);
if (rc != 0) {
return rc;
}
return 0;
}
void
smp_os_groups_register(void)
{
mgmt_register_group(&smp_def_group);
}
void
smp_os_pkg_init(void)
{
smp_os_groups_register();
}