| /* |
| * 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 <string.h> |
| |
| #include "tinycbor/cbor.h" |
| #include "mgmt/endian.h" |
| #include "mgmt/mgmt.h" |
| |
| static mgmt_on_evt_cb *evt_cb; |
| static struct mgmt_group *mgmt_group_list; |
| static struct mgmt_group *mgmt_group_list_end; |
| |
| void * |
| mgmt_streamer_alloc_rsp(struct mgmt_streamer *streamer, const void *req) |
| { |
| return streamer->cfg->alloc_rsp(req, streamer->cb_arg); |
| } |
| |
| void |
| mgmt_streamer_trim_front(struct mgmt_streamer *streamer, void *buf, size_t len) |
| { |
| streamer->cfg->trim_front(buf, len, streamer->cb_arg); |
| } |
| |
| void |
| mgmt_streamer_reset_buf(struct mgmt_streamer *streamer, void *buf) |
| { |
| streamer->cfg->reset_buf(buf, streamer->cb_arg); |
| } |
| |
| int |
| mgmt_streamer_write_at(struct mgmt_streamer *streamer, size_t offset, |
| const void *data, int len) |
| { |
| return streamer->cfg->write_at(streamer->writer, offset, data, len, |
| streamer->cb_arg); |
| } |
| |
| int |
| mgmt_streamer_init_reader(struct mgmt_streamer *streamer, void *buf) |
| { |
| return streamer->cfg->init_reader(streamer->reader, buf, streamer->cb_arg); |
| } |
| |
| int |
| mgmt_streamer_init_writer(struct mgmt_streamer *streamer, void *buf) |
| { |
| return streamer->cfg->init_writer(streamer->writer, buf, streamer->cb_arg); |
| } |
| |
| void |
| mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf) |
| { |
| streamer->cfg->free_buf(buf, streamer->cb_arg); |
| } |
| |
| static struct mgmt_group * |
| mgmt_find_group(uint16_t group_id, uint16_t command_id) |
| { |
| struct mgmt_group *group; |
| |
| /* |
| * Find the group with the specified group id, if one exists |
| * check the handler for the command id and make sure |
| * that is not NULL. If that is not set, look for the group |
| * with a command id that is set |
| */ |
| for (group = mgmt_group_list; group != NULL; group = group->mg_next) { |
| if (group->mg_group_id == group_id) { |
| if (command_id >= group->mg_handlers_count) { |
| return NULL; |
| } |
| |
| if (!group->mg_handlers[command_id].mh_read && |
| !group->mg_handlers[command_id].mh_write) { |
| continue; |
| } |
| |
| break; |
| } |
| } |
| |
| return group; |
| } |
| |
| void |
| mgmt_register_group(struct mgmt_group *group) |
| { |
| if (mgmt_group_list_end == NULL) { |
| mgmt_group_list = group; |
| } else { |
| mgmt_group_list_end->mg_next = group; |
| } |
| mgmt_group_list_end = group; |
| } |
| |
| const struct mgmt_handler * |
| mgmt_find_handler(uint16_t group_id, uint16_t command_id) |
| { |
| const struct mgmt_group *group; |
| |
| group = mgmt_find_group(group_id, command_id); |
| if (!group) { |
| return NULL; |
| } |
| |
| return &group->mg_handlers[command_id]; |
| } |
| |
| int |
| mgmt_write_rsp_status(struct mgmt_ctxt *ctxt, int errcode) |
| { |
| int rc; |
| |
| rc = cbor_encode_text_stringz(&ctxt->encoder, "rc"); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| rc = cbor_encode_int(&ctxt->encoder, errcode); |
| if (rc != 0) { |
| return rc; |
| } |
| |
| return 0; |
| } |
| |
| int |
| mgmt_err_from_cbor(int cbor_status) |
| { |
| switch (cbor_status) { |
| case CborNoError: return MGMT_ERR_EOK; |
| case CborErrorOutOfMemory: return MGMT_ERR_ENOMEM; |
| default: return MGMT_ERR_EUNKNOWN; |
| } |
| } |
| |
| int |
| mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer) |
| { |
| int rc; |
| |
| #ifdef __ZEPHYR__ |
| rc = cbor_parser_cust_reader_init(streamer->reader, 0, &ctxt->parser, |
| &ctxt->it); |
| #else |
| rc = cbor_parser_init(streamer->reader, 0, &ctxt->parser, &ctxt->it); |
| #endif |
| if (rc != CborNoError) { |
| return mgmt_err_from_cbor(rc); |
| } |
| |
| #ifdef __ZEPHYR__ |
| cbor_encoder_cust_writer_init(&ctxt->encoder, streamer->writer, 0); |
| #else |
| cbor_encoder_init(&ctxt->encoder, streamer->writer, 0); |
| #endif |
| |
| return 0; |
| } |
| |
| void |
| mgmt_ntoh_hdr(struct mgmt_hdr *hdr) |
| { |
| hdr->nh_len = ntohs(hdr->nh_len); |
| hdr->nh_group = ntohs(hdr->nh_group); |
| } |
| |
| void |
| mgmt_hton_hdr(struct mgmt_hdr *hdr) |
| { |
| hdr->nh_len = htons(hdr->nh_len); |
| hdr->nh_group = htons(hdr->nh_group); |
| } |
| |
| void |
| mgmt_register_evt_cb(mgmt_on_evt_cb *cb) |
| { |
| evt_cb = cb; |
| } |
| |
| void |
| mgmt_evt(uint8_t opcode, uint16_t group, uint8_t id, void *arg) |
| { |
| if (evt_cb) { |
| evt_cb(opcode, group, id, arg); |
| } |
| } |