in nimble/host/mesh/src/transport.c [625:695]
int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
const uint8_t *key;
uint8_t aid;
int err;
if (msg->om_len < 1) {
BT_ERR("Zero-length SDU not allowed");
return -EINVAL;
}
if (msg->om_len > BT_MESH_TX_SDU_MAX - BT_MESH_MIC_SHORT) {
BT_ERR("Message too big: %u", msg->om_len);
return -EMSGSIZE;
}
if (net_buf_simple_tailroom(msg) < BT_MESH_MIC_SHORT) {
BT_ERR("Insufficient tailroom for Transport MIC");
return -EINVAL;
}
if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) {
tx->ctx->send_ttl = bt_mesh_default_ttl_get();
} else if (tx->ctx->send_ttl > BT_MESH_TTL_MAX) {
BT_ERR("TTL too large (max 127)");
return -EINVAL;
}
if (msg->om_len > BT_MESH_SDU_UNSEG_MAX) {
tx->ctx->send_rel = true;
}
if (tx->ctx->addr == BT_MESH_ADDR_UNASSIGNED ||
(!BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr) &&
BT_MESH_IS_DEV_KEY(tx->ctx->app_idx))) {
BT_ERR("Invalid destination address");
return -EINVAL;
}
err = bt_mesh_keys_resolve(tx->ctx, &tx->sub, &key, &aid);
if (err) {
return err;
}
BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx,
tx->ctx->app_idx, tx->ctx->addr);
BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len));
tx->xmit = bt_mesh_net_transmit_get();
tx->aid = aid;
if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) {
tx->aszmic = 0;
} else {
tx->aszmic = 1;
}
err = trans_encrypt(tx, key, msg);
if (err) {
return err;
}
if (tx->ctx->send_rel) {
err = send_seg(tx, msg, cb, cb_data, NULL);
} else {
err = send_unseg(tx, msg, cb, cb_data, NULL);
}
return err;
}