WXK
2024-09-18 05e2e954bd127de378a9d1dfbb0ed95d725aad63
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
/*
 * 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.
 */
 
#ifndef H_MGMT_MGMT_
#define H_MGMT_MGMT_
 
#include <inttypes.h>
#include "tinycbor/cbor.h"
 
#ifdef __cplusplus
extern "C" {
#endif
 
/* MTU for newtmgr responses */
#define MGMT_MAX_MTU            1024
 
/** Opcodes; encoded in first byte of header. */
#define MGMT_OP_READ            0
#define MGMT_OP_READ_RSP        1
#define MGMT_OP_WRITE           2
#define MGMT_OP_WRITE_RSP       3
 
/**
 * The first 64 groups are reserved for system level mcumgr commands.
 * Per-user commands are then defined after group 64.
 */
#define MGMT_GROUP_ID_OS        0
#define MGMT_GROUP_ID_IMAGE     1
#define MGMT_GROUP_ID_STAT      2
#define MGMT_GROUP_ID_CONFIG    3
#define MGMT_GROUP_ID_LOG       4
#define MGMT_GROUP_ID_CRASH     5
#define MGMT_GROUP_ID_SPLIT     6
#define MGMT_GROUP_ID_RUN       7
#define MGMT_GROUP_ID_FS        8
#define MGMT_GROUP_ID_SHELL     9
#define MGMT_GROUP_ID_PERUSER   64
 
/**
 * mcumgr error codes.
 */
#define MGMT_ERR_EOK            0
#define MGMT_ERR_EUNKNOWN       1
#define MGMT_ERR_ENOMEM         2
#define MGMT_ERR_EINVAL         3
#define MGMT_ERR_ETIMEOUT       4
#define MGMT_ERR_ENOENT         5
#define MGMT_ERR_EBADSTATE      6       /* Current state disallows command. */
#define MGMT_ERR_EMSGSIZE       7       /* Response too large. */
#define MGMT_ERR_ENOTSUP        8       /* Command not supported. */
#define MGMT_ERR_ECORRUPT       9       /* Corrupt */
#define MGMT_ERR_EPERUSER       256
 
#define MGMT_HDR_SIZE           8
 
/*
 * MGMT event opcodes.
 */
#define MGMT_EVT_OP_CMD_RECV            0x01
#define MGMT_EVT_OP_CMD_STATUS          0x02
#define MGMT_EVT_OP_CMD_DONE            0x03
 
struct mgmt_hdr {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    uint8_t  nh_op:3;           /* MGMT_OP_[...] */
    uint8_t  _res1:5;
#endif
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    uint8_t  _res1:5;
    uint8_t  nh_op:3;           /* MGMT_OP_[...] */
#endif
    uint8_t  nh_flags;          /* Reserved for future flags */
    uint16_t nh_len;            /* Length of the payload */
    uint16_t nh_group;          /* MGMT_GROUP_ID_[...] */
    uint8_t  nh_seq;            /* Sequence number */
    uint8_t  nh_id;             /* Message ID within group */
};
 
#define nmgr_hdr mgmt_hdr
 
/*
 * MGMT_EVT_OP_CMD_STATUS argument
 */
struct mgmt_evt_op_cmd_status_arg {
    int status;
};
 
/*
 * MGMT_EVT_OP_CMD_DONE argument
 */
struct mgmt_evt_op_cmd_done_arg {
    int err;                    /* MGMT_ERR_[...] */
};
 
/** @typedef mgmt_on_evt_cb
 * @brief Function to be called on MGMT event.
 *
 * This callback function is used to notify application about mgmt event.
 *
 * @param opcode                MGMT_EVT_OP_[...].
 * @param group                 MGMT_GROUP_ID_[...].
 * @param id                    Message ID within group.
 * @param arg                   Optional event argument.
 */
typedef void mgmt_on_evt_cb(uint8_t opcode, uint16_t group, uint8_t id,
                            void *arg);
 
/** @typedef mgmt_alloc_rsp_fn
 * @brief Allocates a buffer suitable for holding a response.
 *
 * If a source buf is provided, its user data is copied into the new buffer.
 *
 * @param src_buf               An optional source buffer to copy user data
 *                                  from.
 * @param arg                   Optional streamer argument.
 *
 * @return                      Newly-allocated buffer on success
 *                              NULL on failure.
 */
typedef void *mgmt_alloc_rsp_fn(const void *src_buf, void *arg);
 
/** @typedef mgmt_trim_front_fn
 * @brief Trims data from the front of a buffer.
 *
 * If the amount to trim exceeds the size of the buffer, the buffer is
 * truncated to a length of 0.
 *
 * @param buf                   The buffer to trim.
 * @param len                   The number of bytes to remove.
 * @param arg                   Optional streamer argument.
 */
typedef void mgmt_trim_front_fn(void *buf, size_t len, void *arg);
 
/** @typedef mgmt_reset_buf_fn
 * @brief Resets a buffer to a length of 0.
 *
 * The buffer's user data remains, but its payload is cleared.
 *
 * @param buf                   The buffer to reset.
 * @param arg                   Optional streamer argument.
 */
typedef void mgmt_reset_buf_fn(void *buf, void *arg);
 
/** @typedef mgmt_write_at_fn
 * @brief Writes data to a CBOR encoder.
 *
 * Any existing data at the specified offset is overwritten by the new data.
 * Any new data that extends past the buffer's current length is appended.
 *
 * @param writer                The encoder to write to.
 * @param offset                The byte offset to write to,
 * @param data                  The data to write.
 * @param len                   The number of bytes to write.
 * @param arg                   Optional streamer argument.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
typedef int mgmt_write_at_fn(struct cbor_encoder_writer *writer, size_t offset,
                             const void *data, size_t len, void *arg);
 
/** @typedef mgmt_init_reader_fn
 * @brief Initializes a CBOR reader with the specified buffer.
 *
 * @param reader                The reader to initialize.
 * @param buf                   The buffer to configure the reader with.
 * @param arg                   Optional streamer argument.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
typedef int mgmt_init_reader_fn(struct cbor_decoder_reader *reader, void *buf,
                                void *arg);
 
/** @typedef mgmt_init_writer_fn
 * @brief Initializes a CBOR writer with the specified buffer.
 *
 * @param writer                The writer to initialize.
 * @param buf                   The buffer to configure the writer with.
 * @param arg                   Optional streamer argument.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
typedef int mgmt_init_writer_fn(struct cbor_encoder_writer *writer, void *buf,
                                void *arg);
 
/** @typedef mgmt_init_writer_fn
 * @brief Frees the specified buffer.
 *
 * @param buf                   The buffer to free.
 * @param arg                   Optional streamer argument.
 */
typedef void mgmt_free_buf_fn(void *buf, void *arg);
 
/**
 * @brief Configuration for constructing a mgmt_streamer object.
 */
struct mgmt_streamer_cfg {
    mgmt_alloc_rsp_fn *alloc_rsp;
    mgmt_trim_front_fn *trim_front;
    mgmt_reset_buf_fn *reset_buf;
    mgmt_write_at_fn *write_at;
    mgmt_init_reader_fn *init_reader;
    mgmt_init_writer_fn *init_writer;
    mgmt_free_buf_fn *free_buf;
};
 
/**
 * @brief Decodes requests and encodes responses for any mcumgr protocol.
 */
struct mgmt_streamer {
    const struct mgmt_streamer_cfg *cfg;
    void *cb_arg;
    struct cbor_decoder_reader *reader;
    struct cbor_encoder_writer *writer;
};
 
/**
 * @brief Context required by command handlers for parsing requests and writing
 *        responses.
 */
struct mgmt_ctxt {
    struct CborEncoder encoder;
    struct CborParser parser;
    struct CborValue it;
};
 
/** @typedef mgmt_handler_fn
 * @brief Processes a request and writes the corresponding response.
 *
 * A separate handler is required for each supported op-ID pair.
 *
 * @param ctxt                  The mcumgr context to use.
 *
 * @return                      0 if a response was successfully encoded,
 *                                  MGMT_ERR_[...] code on failure.
 */
typedef int mgmt_handler_fn(struct mgmt_ctxt *ctxt);
 
/**
 * @brief Read handler and write handler for a single command ID.
 */
struct mgmt_handler {
    mgmt_handler_fn *mh_read;
    mgmt_handler_fn *mh_write;
};
 
/**
 * @brief A collection of handlers for an entire command group.
 */
struct mgmt_group {
    /** Points to the next group in the list. */
    struct mgmt_group *mg_next;
 
    /** Array of handlers; one entry per command ID. */
    const struct mgmt_handler *mg_handlers;
    uint16_t mg_handlers_count;
 
    /* The numeric ID of this group. */
    uint16_t mg_group_id;
};
 
/**
 * @brief Uses the specified streamer to allocates a response buffer.
 *
 * If a source buf is provided, its user data is copied into the new buffer.
 *
 * @param streamer              The streamer providing the callback.
 * @param src_buf               An optional source buffer to copy user data
 *                                  from.
 *
 * @return                      Newly-allocated buffer on success
 *                              NULL on failure.
 */
void *mgmt_streamer_alloc_rsp(struct mgmt_streamer *streamer,
                              const void *src_buf);
 
/**
 * @brief Uses the specified streamer to trim data from the front of a buffer.
 *
 * If the amount to trim exceeds the size of the buffer, the buffer is
 * truncated to a length of 0.
 *
 * @param streamer              The streamer providing the callback.
 * @param buf                   The buffer to trim.
 * @param len                   The number of bytes to remove.
 */
void mgmt_streamer_trim_front(struct mgmt_streamer *streamer, void *buf,
                              size_t len);
 
/**
 * @brief Uses the specified streamer to reset a buffer to a length of 0.
 *
 * The buffer's user data remains, but its payload is cleared.
 *
 * @param streamer              The streamer providing the callback.
 * @param buf                   The buffer to reset.
 */
void mgmt_streamer_reset_buf(struct mgmt_streamer *streamer, void *buf);
 
/**
 * @brief Uses the specified streamer to write data to a CBOR encoder.
 *
 * Any existing data at the specified offset is overwritten by the new data.
 * Any new data that extends past the buffer's current length is appended.
 *
 * @param streamer              The streamer providing the callback.
 * @param writer                The encoder to write to.
 * @param offset                The byte offset to write to,
 * @param data                  The data to write.
 * @param len                   The number of bytes to write.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
int mgmt_streamer_write_at(struct mgmt_streamer *streamer, size_t offset,
                           const void *data, int len);
 
/**
 * @brief Uses the specified streamer to initialize a CBOR reader.
 *
 * @param streamer              The streamer providing the callback.
 * @param reader                The reader to initialize.
 * @param buf                   The buffer to configure the reader with.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
int mgmt_streamer_init_reader(struct mgmt_streamer *streamer, void *buf);
 
/**
 * @brief Uses the specified streamer to initializes a CBOR writer.
 *
 * @param streamer              The streamer providing the callback.
 * @param writer                The writer to initialize.
 * @param buf                   The buffer to configure the writer with.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
int mgmt_streamer_init_writer(struct mgmt_streamer *streamer, void *buf);
 
/**
 * @brief Uses the specified streamer to free a buffer.
 *
 * @param streamer              The streamer providing the callback.
 * @param buf                   The buffer to free.
 */
void mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf);
 
/**
 * @brief Registers a full command group.
 *
 * @param group                 The group to register.
 */
void mgmt_register_group(struct mgmt_group *group);
 
/**
 * @brief Unregisters a full command group.
 *
 * @param group                 The group to register.
 */
void
mgmt_unregister_group(struct mgmt_group *group);
 
/**
 * @brief Finds a registered command handler.
 *
 * @param group_id              The group of the command to find.
 * @param command_id            The ID of the command to find.
 *
 * @return                      The requested command handler on success;
 *                              NULL on failure.
 */
const struct mgmt_handler *mgmt_find_handler(uint16_t group_id,
                                             uint16_t command_id);
 
/**
 * @brief Encodes a response status into the specified management context.
 *
 * @param ctxt                  The management context to encode into.
 * @param status                The response status to write.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
int mgmt_write_rsp_status(struct mgmt_ctxt *ctxt, int status);
 
/**
 * @brief Initializes a management context object with the specified streamer.
 *
 * @param ctxt                  The context object to initialize.
 * @param streamer              The streamer that will be used with the
 *                                  context.
 *
 * @return                      0 on success, MGMT_ERR_[...] code on failure.
 */
int mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer);
 
/**
 * @brief Converts a CBOR status code to a MGMT_ERR_[...] code.
 *
 * @param cbor_status           The CBOR status code to convert.
 *
 * @return                      The corresponding MGMT_ERR_[,,,] code.
 */
int mgmt_err_from_cbor(int cbor_status);
 
/**
 * @brief Byte-swaps an mcumgr header from network to host byte order.
 *
 * @param hdr                   The mcumgr header to byte-swap.
 */
void mgmt_ntoh_hdr(struct mgmt_hdr *hdr);
 
/**
 * @brief Byte-swaps an mcumgr header from host to network byte order.
 *
 * @param hdr                   The mcumgr header to byte-swap.
 */
void mgmt_hton_hdr(struct mgmt_hdr *hdr);
 
/**
 * @brief Register event callback function.
 *
 * @param cb                    Callback function.
 */
void mgmt_register_evt_cb(mgmt_on_evt_cb *cb);
 
/**
 * @brief This function is called to notify about mgmt event.
 *
 * @param opcode                MGMT_EVT_OP_[...].
 * @param group                 MGMT_GROUP_ID_[...].
 * @param id                    Message ID within group.
 * @param arg                   Optional event argument.
 */
void mgmt_evt(uint8_t opcode, uint16_t group, uint8_t id, void *arg);
 
#ifdef __cplusplus
}
#endif
 
#endif /* MGMT_MGMT_H_ */