Lines Matching full:rx

717 static void seg_rx_assemble(struct seg_rx *rx, struct net_buf_simple *buf,  in seg_rx_assemble()  argument
724 for (i = 0; i <= rx->seg_n; i++) { in seg_rx_assemble()
725 net_buf_simple_add_mem(buf, rx->seg[i], in seg_rx_assemble()
726 MIN(seg_len(rx->ctl), in seg_rx_assemble()
727 rx->len - (i * seg_len(rx->ctl)))); in seg_rx_assemble()
731 if (!rx->ctl) { in seg_rx_assemble()
743 static int sdu_try_decrypt(struct bt_mesh_net_rx *rx, const struct bt_mesh_key *key, in sdu_try_decrypt() argument
756 if (BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { in sdu_try_decrypt()
757 ctx->crypto.ad = bt_mesh_va_uuid_get(rx->ctx.recv_dst, ctx->crypto.ad, in sdu_try_decrypt()
770 if (!err && BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { in sdu_try_decrypt()
771 rx->ctx.uuid = ctx->crypto.ad; in sdu_try_decrypt()
777 static int sdu_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, uint8_t aszmic, in sdu_recv() argument
785 .src = rx->ctx.addr, in sdu_recv()
786 .dst = rx->ctx.recv_dst, in sdu_recv()
787 .seq_num = seg ? (seg->seq_auth & 0xffffff) : rx->seq, in sdu_recv()
788 .iv_index = BT_MESH_NET_IVI_RX(rx), in sdu_recv()
797 if (!rx->local_match) { in sdu_recv()
799 return rx->friend_match ? 0 : -ENXIO; in sdu_recv()
802 rx->ctx.app_idx = bt_mesh_app_key_find(ctx.crypto.dev_key, AID(&hdr), in sdu_recv()
803 rx, sdu_try_decrypt, &ctx); in sdu_recv()
804 if (rx->ctx.app_idx == BT_MESH_KEY_UNUSED) { in sdu_recv()
809 rx->ctx.uuid = ctx.crypto.ad; in sdu_recv()
811 LOG_DBG("Decrypted (AppIdx: 0x%03x)", rx->ctx.app_idx); in sdu_recv()
813 return bt_mesh_access_recv(&rx->ctx, sdu); in sdu_recv()
846 static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, in trans_ack() argument
865 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match) { in trans_ack()
866 LOG_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst); in trans_ack()
868 *seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(rx), seq_zero); in trans_ack()
870 } else if (!rx->local_match) { in trans_ack()
878 tx = seg_tx_lookup(seq_zero, obo, rx->ctx.addr); in trans_ack()
958 static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, in ctl_recv() argument
967 return trans_ack(rx, hdr, buf, seq_auth); in ctl_recv()
969 return bt_mesh_hb_recv(rx, buf); in ctl_recv()
973 if (!rx->local_match) { in ctl_recv()
980 return bt_mesh_friend_poll(rx, buf); in ctl_recv()
982 return bt_mesh_friend_req(rx, buf); in ctl_recv()
984 return bt_mesh_friend_clear(rx, buf); in ctl_recv()
986 return bt_mesh_friend_clear_cfm(rx, buf); in ctl_recv()
988 return bt_mesh_friend_sub_add(rx, buf); in ctl_recv()
990 return bt_mesh_friend_sub_rem(rx, buf); in ctl_recv()
996 return bt_mesh_lpn_friend_offer(rx, buf); in ctl_recv()
999 if (rx->ctx.addr == bt_mesh.lpn.frnd) { in ctl_recv()
1001 return bt_mesh_lpn_friend_clear_cfm(rx, buf); in ctl_recv()
1004 if (!rx->friend_cred) { in ctl_recv()
1011 return bt_mesh_lpn_friend_update(rx, buf); in ctl_recv()
1013 return bt_mesh_lpn_friend_sub_cfm(rx, buf); in ctl_recv()
1023 static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, in trans_unseg() argument
1038 if (bt_mesh_rpl_check(rx, &rpl, false)) { in trans_unseg()
1039 LOG_WRN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst, in trans_unseg()
1040 rx->seq); in trans_unseg()
1046 if (rx->ctl) { in trans_unseg()
1047 err = ctl_recv(rx, hdr, buf, seq_auth); in trans_unseg()
1054 err = sdu_recv(rx, hdr, 0, buf, &sdu, NULL); in trans_unseg()
1059 bt_mesh_rpl_update(rpl, rx); in trans_unseg()
1143 static void seg_rx_reset(struct seg_rx *rx, bool full_reset) in seg_rx_reset() argument
1147 LOG_DBG("rx %p", rx); in seg_rx_reset()
1150 * it checks rx->in_use. in seg_rx_reset()
1152 (void)k_work_cancel_delayable(&rx->ack); in seg_rx_reset()
1153 (void)k_work_cancel_delayable(&rx->discard); in seg_rx_reset()
1155 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->obo && in seg_rx_reset()
1156 rx->block != BLOCK_COMPLETE(rx->seg_n)) { in seg_rx_reset()
1158 bt_mesh_friend_clear_incomplete(rx->sub, rx->src, rx->dst, in seg_rx_reset()
1159 &rx->seq_auth); in seg_rx_reset()
1162 for (i = 0; i <= rx->seg_n; i++) { in seg_rx_reset()
1163 if (!rx->seg[i]) { in seg_rx_reset()
1167 k_mem_slab_free(&segs, rx->seg[i]); in seg_rx_reset()
1168 rx->seg[i] = NULL; in seg_rx_reset()
1171 rx->in_use = 0U; in seg_rx_reset()
1178 rx->seq_auth = 0U; in seg_rx_reset()
1179 rx->sub = NULL; in seg_rx_reset()
1180 rx->src = BT_MESH_ADDR_UNASSIGNED; in seg_rx_reset()
1181 rx->dst = BT_MESH_ADDR_UNASSIGNED; in seg_rx_reset()
1188 struct seg_rx *rx = CONTAINER_OF(dwork, struct seg_rx, discard); in seg_discard() local
1191 seg_rx_reset(rx, false); in seg_discard()
1192 rx->block = 0U; in seg_discard()
1202 struct seg_rx *rx = CONTAINER_OF(dwork, struct seg_rx, ack); in seg_ack() local
1204 if (!rx->in_use || rx->block == BLOCK_COMPLETE(rx->seg_n)) { in seg_ack()
1214 LOG_DBG("rx %p", rx); in seg_ack()
1216 send_ack(rx->sub, rx->dst, rx->src, rx->ttl, &rx->seq_auth, in seg_ack()
1217 rx->block, rx->obo); in seg_ack()
1219 rx->last_ack = k_uptime_get_32(); in seg_ack()
1221 if (rx->attempts_left == 0) { in seg_ack()
1226 if (rx->seg_n > BT_MESH_SAR_RX_SEG_THRESHOLD) { in seg_ack()
1227 --rx->attempts_left; in seg_ack()
1228 k_work_schedule(&rx->ack, K_MSEC(BT_MESH_SAR_RX_SEG_INT_MS)); in seg_ack()
1243 struct seg_rx *rx = &seg_rx[i]; in seg_rx_find() local
1245 if (rx->src != net_rx->ctx.addr || in seg_rx_find()
1246 rx->dst != net_rx->ctx.recv_dst) { in seg_rx_find()
1250 /* Return newer RX context in addition to an exact match, so in seg_rx_find()
1253 if (rx->seq_auth >= *seq_auth) { in seg_rx_find()
1254 return rx; in seg_rx_find()
1257 if (rx->in_use) { in seg_rx_find()
1263 seg_rx_reset(rx, true); in seg_rx_find()
1273 static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx, in seg_rx_is_valid() argument
1276 if (rx->hdr != *hdr || rx->seg_n != seg_n) { in seg_rx_is_valid()
1281 if (rx->src != net_rx->ctx.addr || rx->dst != net_rx->ctx.recv_dst) { in seg_rx_is_valid()
1286 if (rx->ctl != net_rx->ctl) { in seg_rx_is_valid()
1301 * the collaborative Bluetooth rx thread: in seg_rx_alloc()
1309 struct seg_rx *rx = &seg_rx[i]; in seg_rx_alloc() local
1311 if (rx->in_use) { in seg_rx_alloc()
1315 rx->in_use = 1U; in seg_rx_alloc()
1316 rx->sub = net_rx->sub; in seg_rx_alloc()
1317 rx->ctl = net_rx->ctl; in seg_rx_alloc()
1318 rx->seq_auth = *seq_auth; in seg_rx_alloc()
1319 rx->seg_n = seg_n; in seg_rx_alloc()
1320 rx->hdr = *hdr; in seg_rx_alloc()
1321 rx->ttl = net_rx->ctx.send_ttl; in seg_rx_alloc()
1322 rx->src = net_rx->ctx.addr; in seg_rx_alloc()
1323 rx->dst = net_rx->ctx.recv_dst; in seg_rx_alloc()
1324 rx->block = 0U; in seg_rx_alloc()
1326 LOG_DBG("New RX context. Block Complete 0x%08x", BLOCK_COMPLETE(seg_n)); in seg_rx_alloc()
1328 return rx; in seg_rx_alloc()
1339 struct seg_rx *rx; in trans_seg() local
1396 /* Look for old RX sessions */ in trans_seg()
1397 rx = seg_rx_find(net_rx, seq_auth); in trans_seg()
1398 if (rx) { in trans_seg()
1400 if (rx->seq_auth > *seq_auth) { in trans_seg()
1405 if (!seg_rx_is_valid(rx, net_rx, hdr, seg_n)) { in trans_seg()
1409 if (rx->in_use) { in trans_seg()
1410 LOG_DBG("Existing RX context. Block 0x%08x", rx->block); in trans_seg()
1414 if (rx->block == BLOCK_COMPLETE(rx->seg_n)) { in trans_seg()
1422 if (k_uptime_get_32() - rx->last_ack > in trans_seg()
1426 seq_auth, rx->block, rx->obo); in trans_seg()
1427 rx->last_ack = k_uptime_get_32(); in trans_seg()
1492 /* Look for free slot for a new RX session */ in trans_seg()
1493 rx = seg_rx_alloc(net_rx, hdr, seq_auth, seg_n); in trans_seg()
1494 if (!rx) { in trans_seg()
1503 rx->obo = net_rx->friend_match; in trans_seg()
1506 if (BIT(seg_o) & rx->block) { in trans_seg()
1517 rx->len = seg_n * seg_len(rx->ctl) + buf->len; in trans_seg()
1518 LOG_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl), buf->len, rx->len); in trans_seg()
1520 if (rx->len > BT_MESH_RX_SDU_MAX) { in trans_seg()
1524 seq_auth, 0, rx->obo); in trans_seg()
1525 seg_rx_reset(rx, true); in trans_seg()
1529 if (buf->len != seg_len(rx->ctl)) { in trans_seg()
1536 k_work_schedule(&rx->discard, in trans_seg()
1538 rx->attempts_left = BT_MESH_SAR_RX_ACK_RETRANS_COUNT; in trans_seg()
1540 if (!bt_mesh_lpn_established() && BT_MESH_ADDR_IS_UNICAST(rx->dst)) { in trans_seg()
1541 LOG_DBG("ack delay %u", ACK_DELAY(rx->seg_n)); in trans_seg()
1542 k_work_reschedule(&rx->ack, K_MSEC(ACK_DELAY(rx->seg_n))); in trans_seg()
1546 err = k_mem_slab_alloc(&segs, &rx->seg[seg_o], K_NO_WAIT); in trans_seg()
1552 memcpy(rx->seg[seg_o], buf->data, buf->len); in trans_seg()
1557 rx->block |= BIT(seg_o); in trans_seg()
1559 if (rx->block != BLOCK_COMPLETE(seg_n)) { in trans_seg()
1568 * block is fully received, or rx->in_use is false. in trans_seg()
1570 (void)k_work_cancel_delayable(&rx->ack); in trans_seg()
1573 net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); in trans_seg()
1574 rx->last_ack = k_uptime_get_32(); in trans_seg()
1578 seg_rx_assemble(rx, &sdu, 0U); in trans_seg()
1580 } else if (rx->len < 1 + APP_MIC_LEN(ASZMIC(hdr))) { in trans_seg()
1593 &sdu, seg_buf.data, rx->len - APP_MIC_LEN(ASZMIC(hdr))); in trans_seg()
1595 err = sdu_recv(net_rx, *hdr, ASZMIC(hdr), &seg_buf, &sdu, rx); in trans_seg()
1609 seg_rx_reset(rx, false); in trans_seg()
1614 int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) in bt_mesh_trans_recv() argument
1623 rx->friend_match = bt_mesh_friend_match(rx->sub->net_idx, in bt_mesh_trans_recv()
1624 rx->ctx.recv_dst); in bt_mesh_trans_recv()
1626 rx->friend_match = false; in bt_mesh_trans_recv()
1629 LOG_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u", rx->ctx.addr, rx->ctx.recv_dst, in bt_mesh_trans_recv()
1630 rx->seq, rx->friend_match); in bt_mesh_trans_recv()
1638 bt_mesh_test_net_recv(rx->ctx.recv_ttl, rx->ctl, rx->ctx.addr, rx->ctx.recv_dst, in bt_mesh_trans_recv()
1647 bt_mesh_lpn_established() && rx->net_if == BT_MESH_NET_IF_ADV && in bt_mesh_trans_recv()
1648 (!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) { in bt_mesh_trans_recv()
1662 if (!rx->local_match && !rx->friend_match) { in bt_mesh_trans_recv()
1666 err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); in bt_mesh_trans_recv()
1673 if (!rx->ctl && !rx->local_match && !rx->friend_match) { in bt_mesh_trans_recv()
1677 err = trans_unseg(buf, rx, &seq_auth); in bt_mesh_trans_recv()
1682 bt_mesh_lpn_msg_received(rx); in bt_mesh_trans_recv()
1687 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match && !err) { in bt_mesh_trans_recv()
1689 bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, in bt_mesh_trans_recv()
1692 bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, in bt_mesh_trans_recv()