103 lines
2.5 KiB
C
103 lines
2.5 KiB
C
/*
|
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/net/buf.h>
|
|
#include <zephyr/sys/byteorder.h>
|
|
#include <string.h>
|
|
|
|
#include <zephyr/bluetooth/mesh.h>
|
|
#include "crypto.h"
|
|
#include "access.h"
|
|
|
|
int bt_mesh_dfu_metadata_decode(struct net_buf_simple *buf,
|
|
struct bt_mesh_dfu_metadata *metadata)
|
|
{
|
|
if (buf->len < 12) {
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
metadata->fw_ver.major = net_buf_simple_pull_u8(buf);
|
|
metadata->fw_ver.minor = net_buf_simple_pull_u8(buf);
|
|
metadata->fw_ver.revision = net_buf_simple_pull_le16(buf);
|
|
metadata->fw_ver.build_num = net_buf_simple_pull_le32(buf);
|
|
metadata->fw_size = net_buf_simple_pull_le24(buf);
|
|
metadata->fw_core_type = net_buf_simple_pull_u8(buf);
|
|
|
|
if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
|
|
if (buf->len < 6) {
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
metadata->comp_hash = net_buf_simple_pull_le32(buf);
|
|
metadata->elems = net_buf_simple_pull_le16(buf);
|
|
}
|
|
|
|
metadata->user_data = buf->len > 0 ? buf->data : NULL;
|
|
metadata->user_data_len = buf->len;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int bt_mesh_dfu_metadata_encode(const struct bt_mesh_dfu_metadata *metadata,
|
|
struct net_buf_simple *buf)
|
|
{
|
|
size_t md_len_min = 12 + metadata->user_data_len;
|
|
|
|
if (metadata->fw_core_type & BT_MESH_DFU_FW_CORE_TYPE_APP) {
|
|
md_len_min += 6;
|
|
}
|
|
|
|
if (net_buf_simple_tailroom(buf) < md_len_min) {
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
net_buf_simple_add_u8(buf, metadata->fw_ver.major);
|
|
net_buf_simple_add_u8(buf, metadata->fw_ver.minor);
|
|
net_buf_simple_add_le16(buf, metadata->fw_ver.revision);
|
|
net_buf_simple_add_le32(buf, metadata->fw_ver.build_num);
|
|
net_buf_simple_add_le24(buf, metadata->fw_size);
|
|
net_buf_simple_add_u8(buf, metadata->fw_core_type);
|
|
net_buf_simple_add_le32(buf, metadata->comp_hash);
|
|
net_buf_simple_add_le16(buf, metadata->elems);
|
|
|
|
if (metadata->user_data_len > 0) {
|
|
net_buf_simple_add_mem(buf, metadata->user_data, metadata->user_data_len);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_mesh_dfu_metadata_comp_hash_get(struct net_buf_simple *buf, uint8_t *key, uint32_t *hash)
|
|
{
|
|
uint8_t mac[16];
|
|
int err;
|
|
struct bt_mesh_sg sg = {.data = buf->data, .len = buf->len};
|
|
|
|
err = bt_mesh_aes_cmac_raw_key(key, &sg, 1, mac);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
*hash = sys_get_le32(mac);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int bt_mesh_dfu_metadata_comp_hash_local_get(uint8_t *key, uint32_t *hash)
|
|
{
|
|
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
|
|
int err;
|
|
|
|
err = bt_mesh_comp_data_get_page_0(&buf, 0);
|
|
if (err) {
|
|
return err;
|
|
}
|
|
|
|
err = bt_mesh_dfu_metadata_comp_hash_get(&buf, key, hash);
|
|
return err;
|
|
}
|