WXK
2024-12-16 9201a33e45484b3247271759c91c158063baccac
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
/*  Bluetooth Mesh */
 
/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
 
#include "mesh/mesh.h"
 
void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode)
{
    net_buf_simple_init(msg, 0);
 
    switch (BT_MESH_MODEL_OP_LEN(opcode)) {
    case 1:
        net_buf_simple_add_u8(msg, opcode);
        break;
    case 2:
        net_buf_simple_add_be16(msg, opcode);
        break;
    case 3:
        net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
        /* Using LE for the CID since the model layer is defined as
         * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3
         * will declare the opcode in this way.
         */
        net_buf_simple_add_le16(msg, opcode & 0xffff);
        break;
    default:
        BT_WARN("Unknown opcode format");
        break;
    }
}
 
void bt_mesh_msg_ack_ctx_clear(struct bt_mesh_msg_ack_ctx *ack)
{
    ack->op = 0U;
    ack->user_data = NULL;
    ack->dst = BT_MESH_ADDR_UNASSIGNED;
}
 
int bt_mesh_msg_ack_ctx_prepare(struct bt_mesh_msg_ack_ctx *ack,
    uint32_t op, uint16_t dst, void *user_data)
{
    if (ack->op) {
        BT_WARN("Another synchronous operation pending");
        return -EBUSY;
    }
 
    ack->op = op;
    ack->user_data = user_data;
    ack->dst = dst;
 
    return 0;
}
 
int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout)
{
    int err;
 
    err = k_sem_take(&ack->sem, timeout);
    bt_mesh_msg_ack_ctx_clear(ack);
 
    if (err == -EAGAIN) {
        return -ETIMEDOUT;
    }
 
    return err;
}
 
bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack,
    uint32_t op, uint16_t addr, void **user_data)
{
    if (ack->op != op || (BT_MESH_ADDR_IS_UNICAST(ack->dst) && ack->dst != addr)) {
        return false;
    }
 
    if (user_data != NULL) {
        *user_data = ack->user_data;
    }
 
    return true;
}