in nimble/host/mesh/src/net.c [814:874]
void bt_mesh_net_recv(struct os_mbuf *data, int8_t rssi,
enum bt_mesh_net_if net_if)
{
struct os_mbuf *buf = NET_BUF_SIMPLE(BT_MESH_NET_MAX_PDU_LEN);
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
struct net_buf_simple_state state;
BT_DBG("rssi %d net_if %u", rssi, net_if);
if (!bt_mesh_is_provisioned()) {
BT_ERR("Not provisioned; dropping packet");
goto done;
}
if (bt_mesh_net_decode(data, net_if, &rx, buf)) {
goto done;
}
/* Save the state so the buffer can later be relayed */
net_buf_simple_save(buf, &state);
rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) ||
bt_mesh_has_addr(rx.ctx.recv_dst));
if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) &&
net_if == BT_MESH_NET_IF_PROXY) {
bt_mesh_proxy_addr_add(data, rx.ctx.addr);
if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_DISABLED &&
!rx.local_match) {
BT_INFO("Proxy is disabled; ignoring message");
goto done;
}
}
/* The transport layer has indicated that it has rejected the message,
* but would like to see it again if it is received in the future.
* This can happen if a message is received when the device is in
* Low Power mode, but the message was not encrypted with the friend
* credentials. Remove it from the message cache so that we accept
* it again in the future.
*/
if (bt_mesh_trans_recv(buf, &rx) == -EAGAIN) {
BT_WARN("Removing rejected message from Network Message Cache");
msg_cache[rx.msg_cache_idx].src = BT_MESH_ADDR_UNASSIGNED;
/* Rewind the next index now that we're not using this entry */
msg_cache_next = rx.msg_cache_idx;
}
/* Relay if this was a group/virtual address, or if the destination
* was neither a local element nor an LPN we're Friends for.
*/
if (!BT_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) ||
(!rx.local_match && !rx.friend_match)) {
net_buf_simple_restore(buf, &state);
bt_mesh_net_relay(buf, &rx);
}
done:
os_mbuf_free_chain(buf);
}