| /* |
| * 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 "tinycbor/cbor.h" |
| #include "cborattr/cborattr.h" |
| #include "mgmt/mgmt.h" |
| #include "os_mgmt/os_mgmt.h" |
| #include "os_mgmt/os_mgmt_impl.h" |
| #include "os_mgmt/os_mgmt_config.h" |
| |
| #if OS_MGMT_ECHO |
| static mgmt_handler_fn os_mgmt_echo; |
| #endif |
| |
| static mgmt_handler_fn os_mgmt_reset; |
| |
| #if OS_MGMT_TASKSTAT |
| static mgmt_handler_fn os_mgmt_taskstat_read; |
| #endif |
| |
| static const struct mgmt_handler os_mgmt_group_handlers[] = { |
| #if OS_MGMT_ECHO |
| [OS_MGMT_ID_ECHO] = { |
| os_mgmt_echo, os_mgmt_echo |
| }, |
| #endif |
| #if OS_MGMT_TASKSTAT |
| [OS_MGMT_ID_TASKSTAT] = { |
| os_mgmt_taskstat_read, NULL |
| }, |
| #endif |
| [OS_MGMT_ID_RESET] = { |
| NULL, os_mgmt_reset |
| }, |
| }; |
| |
| #define OS_MGMT_GROUP_SZ \ |
| (sizeof os_mgmt_group_handlers / sizeof os_mgmt_group_handlers[0]) |
| |
| static struct mgmt_group os_mgmt_group = { |
| .mg_handlers = os_mgmt_group_handlers, |
| .mg_handlers_count = OS_MGMT_GROUP_SZ, |
| .mg_group_id = MGMT_GROUP_ID_OS, |
| }; |
| |
| /** |
| * Command handler: os echo |
| */ |
| #if OS_MGMT_ECHO |
| static int |
| os_mgmt_echo(struct mgmt_ctxt *ctxt) |
| { |
| char echo_buf[128]; |
| CborError err; |
| |
| const struct cbor_attr_t attrs[2] = { |
| [0] = { |
| .attribute = "d", |
| .type = CborAttrTextStringType, |
| .addr.string = echo_buf, |
| .nodefault = 1, |
| .len = sizeof echo_buf, |
| }, |
| [1] = { |
| .attribute = NULL |
| } |
| }; |
| |
| echo_buf[0] = '\0'; |
| |
| err = cbor_read_object(&ctxt->it, attrs); |
| if (err != 0) { |
| return MGMT_ERR_EINVAL; |
| } |
| |
| err |= cbor_encode_text_stringz(&ctxt->encoder, "r"); |
| err |= cbor_encode_text_string(&ctxt->encoder, echo_buf, strlen(echo_buf)); |
| |
| if (err != 0) { |
| return MGMT_ERR_ENOMEM; |
| } |
| |
| return 0; |
| } |
| #endif |
| |
| #if OS_MGMT_TASKSTAT |
| /** |
| * Encodes a single taskstat entry. |
| */ |
| static int |
| os_mgmt_taskstat_encode_one(struct CborEncoder *encoder, |
| const struct os_mgmt_task_info *task_info) |
| { |
| CborEncoder task_map; |
| CborError err; |
| |
| err = 0; |
| err |= cbor_encode_text_stringz(encoder, task_info->oti_name); |
| err |= cbor_encoder_create_map(encoder, &task_map, CborIndefiniteLength); |
| err |= cbor_encode_text_stringz(&task_map, "prio"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_prio); |
| err |= cbor_encode_text_stringz(&task_map, "tid"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_taskid); |
| err |= cbor_encode_text_stringz(&task_map, "state"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_state); |
| err |= cbor_encode_text_stringz(&task_map, "stkuse"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_stkusage); |
| err |= cbor_encode_text_stringz(&task_map, "stksiz"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_stksize); |
| err |= cbor_encode_text_stringz(&task_map, "cswcnt"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_cswcnt); |
| err |= cbor_encode_text_stringz(&task_map, "runtime"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_runtime); |
| err |= cbor_encode_text_stringz(&task_map, "last_checkin"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_last_checkin); |
| err |= cbor_encode_text_stringz(&task_map, "next_checkin"); |
| err |= cbor_encode_uint(&task_map, task_info->oti_next_checkin); |
| err |= cbor_encoder_close_container(encoder, &task_map); |
| |
| if (err != 0) { |
| return MGMT_ERR_ENOMEM; |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * Command handler: os taskstat |
| */ |
| static int |
| os_mgmt_taskstat_read(struct mgmt_ctxt *ctxt) |
| { |
| struct os_mgmt_task_info task_info; |
| struct CborEncoder tasks_map; |
| CborError err; |
| int task_idx; |
| int rc; |
| |
| err = 0; |
| err |= cbor_encode_text_stringz(&ctxt->encoder, "tasks"); |
| err |= cbor_encoder_create_map(&ctxt->encoder, &tasks_map, |
| CborIndefiniteLength); |
| if (err != 0) { |
| return MGMT_ERR_ENOMEM; |
| } |
| |
| /* Iterate the list of tasks, encoding each. */ |
| for (task_idx = 0; ; task_idx++) { |
| rc = os_mgmt_impl_task_info(task_idx, &task_info); |
| if (rc == MGMT_ERR_ENOENT) { |
| /* No more tasks to encode. */ |
| break; |
| } else if (rc != 0) { |
| return rc; |
| } |
| |
| rc = os_mgmt_taskstat_encode_one(&tasks_map, &task_info); |
| if (rc != 0) { |
| cbor_encoder_close_container(&ctxt->encoder, &tasks_map); |
| return rc; |
| } |
| } |
| |
| err = cbor_encoder_close_container(&ctxt->encoder, &tasks_map); |
| if (err != 0) { |
| return MGMT_ERR_ENOMEM; |
| } |
| |
| return 0; |
| } |
| #endif |
| |
| /** |
| * Command handler: os reset |
| */ |
| static int |
| os_mgmt_reset(struct mgmt_ctxt *ctxt) |
| { |
| return os_mgmt_impl_reset(OS_MGMT_RESET_MS); |
| } |
| |
| void |
| os_mgmt_register_group(void) |
| { |
| mgmt_register_group(&os_mgmt_group); |
| } |
| |
| void |
| os_mgmt_module_init(void) |
| { |
| os_mgmt_register_group(); |
| } |