Lines Matching +full:rx +full:- +full:wake +full:- +full:timeout

5  * SPDX-License-Identifier: Apache-2.0
46 frame->id = addr->ext_id; in prepare_frame()
47 frame->flags = ((addr->flags & ISOTP_MSG_IDE) != 0 ? CAN_FRAME_IDE : 0) | in prepare_frame()
48 ((addr->flags & ISOTP_MSG_FDF) != 0 ? CAN_FRAME_FDF : 0) | in prepare_frame()
49 ((addr->flags & ISOTP_MSG_BRS) != 0 ? CAN_FRAME_BRS : 0); in prepare_frame()
55 filter->id = addr->ext_id; in prepare_filter()
56 filter->mask = mask; in prepare_filter()
57 filter->flags = (addr->flags & ISOTP_MSG_IDE) != 0 ? CAN_FILTER_IDE : 0; in prepare_filter()
61 * Wake every context that is waiting for a buffer
72 k_work_submit(&rctx->work); in receive_pool_free()
85 k_work_submit(&rctx->work); in receive_ff_sf_pool_free()
91 rctx->state = ISOTP_RX_STATE_ERR; in receive_report_error()
92 rctx->error_nr = err; in receive_report_error()
104 k_work_submit(&rctx->work); in receive_can_tx()
144 prepare_frame(&frame, &rctx->tx_addr); in receive_send_fc()
146 if ((rctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in receive_send_fc()
147 *data++ = rctx->tx_addr.ext_addr; in receive_send_fc()
151 *data++ = rctx->opts.bs; in receive_send_fc()
152 *data++ = rctx->opts.stmin; in receive_send_fc()
153 payload_len = data - frame.data; in receive_send_fc()
158 ISOTP_PADDED_FRAME_DL_MIN - payload_len); in receive_send_fc()
164 ret = can_send(rctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), receive_can_tx, rctx); in receive_send_fc()
187 remaining_len = len - CONFIG_ISOTP_RX_BUF_SIZE; in receive_alloc_buffer_chain()
199 remaining_len - CONFIG_ISOTP_RX_BUF_SIZE : 0; in receive_alloc_buffer_chain()
209 switch (rctx->state) { in receive_timeout_handler()
211 LOG_ERR("Timeout while waiting for CF"); in receive_timeout_handler()
216 rctx->state = ISOTP_RX_STATE_SEND_WAIT; in receive_timeout_handler()
220 k_work_submit(&rctx->work); in receive_timeout_handler()
227 if (rctx->opts.bs == 0) { in receive_alloc_buffer()
229 buf = receive_alloc_buffer_chain(rctx->length); in receive_alloc_buffer()
232 uint32_t len = MIN(rctx->length, rctx->opts.bs * (rctx->rx_addr.dl - 1)); in receive_alloc_buffer()
238 k_timer_start(&rctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); in receive_alloc_buffer()
240 if (rctx->wft == ISOTP_WFT_FIRST) { in receive_alloc_buffer()
242 rctx->wft = 0; in receive_alloc_buffer()
243 sys_slist_append(&global_ctx.alloc_list, &rctx->alloc_node); in receive_alloc_buffer()
246 rctx->state = ISOTP_RX_STATE_SEND_WAIT; in receive_alloc_buffer()
250 return -1; in receive_alloc_buffer()
253 if (rctx->state == ISOTP_RX_STATE_TRY_ALLOC) { in receive_alloc_buffer()
254 k_timer_stop(&rctx->timer); in receive_alloc_buffer()
255 rctx->wft = ISOTP_WFT_FIRST; in receive_alloc_buffer()
256 sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); in receive_alloc_buffer()
259 if (rctx->opts.bs != 0) { in receive_alloc_buffer()
260 rctx->buf = buf; in receive_alloc_buffer()
262 net_buf_frag_insert(rctx->buf, buf); in receive_alloc_buffer()
265 rctx->act_frag = buf; in receive_alloc_buffer()
274 switch (rctx->state) { in receive_state_machine()
276 rctx->length = receive_get_sf_length(rctx->buf, in receive_state_machine()
277 (rctx->rx_addr.flags & ISOTP_MSG_FDF) != 0); in receive_state_machine()
278 ud_rem_len = net_buf_user_data(rctx->buf); in receive_state_machine()
280 LOG_DBG("SM process SF of length %d", rctx->length); in receive_state_machine()
281 k_fifo_put(&rctx->fifo, rctx->buf); in receive_state_machine()
282 rctx->state = ISOTP_RX_STATE_RECYCLE; in receive_state_machine()
287 rctx->length = receive_get_ff_length(rctx->buf); in receive_state_machine()
288 LOG_DBG("SM process FF. Length: %d", rctx->length); in receive_state_machine()
289 rctx->length -= rctx->buf->len; in receive_state_machine()
290 if (rctx->opts.bs == 0 && in receive_state_machine()
291 rctx->length > CONFIG_ISOTP_RX_BUF_COUNT * CONFIG_ISOTP_RX_BUF_SIZE) { in receive_state_machine()
292 LOG_ERR("Pkt length is %d but buffer has only %d bytes", rctx->length, in receive_state_machine()
299 if (rctx->opts.bs) { in receive_state_machine()
300 rctx->bs = rctx->opts.bs; in receive_state_machine()
301 ud_rem_len = net_buf_user_data(rctx->buf); in receive_state_machine()
302 *ud_rem_len = rctx->length; in receive_state_machine()
303 k_fifo_put(&rctx->fifo, rctx->buf); in receive_state_machine()
306 rctx->wft = ISOTP_WFT_FIRST; in receive_state_machine()
307 rctx->state = ISOTP_RX_STATE_TRY_ALLOC; in receive_state_machine()
311 k_timer_stop(&rctx->timer); in receive_state_machine()
318 rctx->state = ISOTP_RX_STATE_SEND_FC; in receive_state_machine()
323 k_timer_start(&rctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); in receive_state_machine()
324 rctx->state = ISOTP_RX_STATE_WAIT_CF; in receive_state_machine()
328 if (++rctx->wft < CONFIG_ISOTP_WFTMAX) { in receive_state_machine()
329 LOG_DBG("Send wait frame number %d", rctx->wft); in receive_state_machine()
331 k_timer_start(&rctx->timer, K_MSEC(ISOTP_ALLOC_TIMEOUT_MS), K_NO_WAIT); in receive_state_machine()
332 rctx->state = ISOTP_RX_STATE_TRY_ALLOC; in receive_state_machine()
336 sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); in receive_state_machine()
337 LOG_ERR("Sent %d wait frames. Giving up to alloc now", rctx->wft); in receive_state_machine()
341 LOG_DBG("SM ERR state. err nr: %d", rctx->error_nr); in receive_state_machine()
342 k_timer_stop(&rctx->timer); in receive_state_machine()
344 if (rctx->error_nr == ISOTP_N_BUFFER_OVERFLW) { in receive_state_machine()
348 k_fifo_cancel_wait(&rctx->fifo); in receive_state_machine()
349 net_buf_unref(rctx->buf); in receive_state_machine()
350 rctx->buf = NULL; in receive_state_machine()
351 rctx->state = ISOTP_RX_STATE_RECYCLE; in receive_state_machine()
355 rctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, K_NO_WAIT); in receive_state_machine()
356 if (!rctx->buf) { in receive_state_machine()
358 sys_slist_append(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); in receive_state_machine()
362 sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); in receive_state_machine()
363 rctx->state = ISOTP_RX_STATE_WAIT_FF_SF; in receive_state_machine()
385 uint32_t rx_sa; /* ISO-TP fixed source address (if used) */ in process_ff_sf()
386 uint8_t can_dl = can_dlc_to_bytes(frame->dlc); in process_ff_sf()
388 if ((rctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in process_ff_sf()
389 if (frame->data[index++] != rctx->rx_addr.ext_addr) { in process_ff_sf()
394 if ((rctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { in process_ff_sf()
396 rctx->rx_addr.ext_id = frame->id; in process_ff_sf()
397 /* replace TX target address with RX source address */ in process_ff_sf()
398 rx_sa = (frame->id & ISOTP_FIXED_ADDR_SA_MASK) >> in process_ff_sf()
400 rctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_TA_MASK); in process_ff_sf()
401 rctx->tx_addr.ext_id |= rx_sa << ISOTP_FIXED_ADDR_TA_POS; in process_ff_sf()
404 rctx->tx_addr.ext_id &= ~(ISOTP_FIXED_ADDR_PRIO_MASK); in process_ff_sf()
405 rctx->tx_addr.ext_id |= frame->id & ISOTP_FIXED_ADDR_PRIO_MASK; in process_ff_sf()
409 switch (frame->data[index] & ISOTP_PCI_TYPE_MASK) { in process_ff_sf()
418 rctx->state = ISOTP_RX_STATE_PROCESS_FF; in process_ff_sf()
419 rctx->rx_addr.dl = can_dl; in process_ff_sf()
420 rctx->sn_expected = 1; in process_ff_sf()
432 sf_len = frame->data[index] & ISOTP_PCI_SF_DL_MASK; in process_ff_sf()
435 if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (rctx->rx_addr.flags & ISOTP_MSG_FDF) != 0 && in process_ff_sf()
441 sf_len = frame->data[index + 1]; in process_ff_sf()
452 rctx->state = ISOTP_RX_STATE_PROCESS_SF; in process_ff_sf()
460 net_buf_add_mem(rctx->buf, &frame->data[index], payload_len - index); in process_ff_sf()
465 size_t tailroom = net_buf_tailroom(rctx->act_frag); in receive_add_mem()
468 net_buf_add_mem(rctx->act_frag, data, len); in receive_add_mem()
473 net_buf_add_mem(rctx->act_frag, data, tailroom); in receive_add_mem()
474 rctx->act_frag = rctx->act_frag->frags; in receive_add_mem()
475 if (!rctx->act_frag) { in receive_add_mem()
481 net_buf_add_mem(rctx->act_frag, data + tailroom, len - tailroom); in receive_add_mem()
486 uint32_t *ud_rem_len = (uint32_t *)net_buf_user_data(rctx->buf); in process_cf()
489 uint8_t can_dl = can_dlc_to_bytes(frame->dlc); in process_cf()
491 if ((rctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in process_cf()
492 if (frame->data[index++] != rctx->rx_addr.ext_addr) { in process_cf()
497 if ((frame->data[index] & ISOTP_PCI_TYPE_MASK) != ISOTP_PCI_TYPE_CF) { in process_cf()
499 frame->data[index] >> ISOTP_PCI_TYPE_POS); in process_cf()
501 k_work_submit(&rctx->work); in process_cf()
505 k_timer_start(&rctx->timer, K_MSEC(ISOTP_CR_TIMEOUT_MS), K_NO_WAIT); in process_cf()
507 if ((frame->data[index++] & ISOTP_PCI_SN_MASK) != rctx->sn_expected++) { in process_cf()
510 k_work_submit(&rctx->work); in process_cf()
523 /* First frame defines the RX data length, consecutive frames in process_cf()
526 if (can_dl != rctx->rx_addr.dl && rctx->length > can_dl - index) { in process_cf()
533 data_len = MIN(rctx->length, can_dl - index); in process_cf()
534 receive_add_mem(rctx, &frame->data[index], data_len); in process_cf()
535 rctx->length -= data_len; in process_cf()
536 LOG_DBG("%d bytes remaining", rctx->length); in process_cf()
538 if (rctx->length == 0) { in process_cf()
539 rctx->state = ISOTP_RX_STATE_RECYCLE; in process_cf()
541 k_fifo_put(&rctx->fifo, rctx->buf); in process_cf()
545 if (rctx->opts.bs && !--rctx->bs) { in process_cf()
547 rctx->bs = rctx->opts.bs; in process_cf()
548 *ud_rem_len = rctx->length; in process_cf()
549 k_fifo_put(&rctx->fifo, rctx->buf); in process_cf()
550 rctx->state = ISOTP_RX_STATE_TRY_ALLOC; in process_cf()
560 if (IS_ENABLED(CONFIG_CAN_ACCEPT_RTR) && (frame->flags & CAN_FRAME_RTR) != 0U) { in receive_can_rx()
564 switch (rctx->state) { in receive_can_rx()
566 __ASSERT_NO_MSG(rctx->buf); in receive_can_rx()
573 if (rctx->state == ISOTP_RX_STATE_WAIT_CF) { in receive_can_rx()
588 k_work_submit(&rctx->work); in receive_can_rx()
596 if ((rctx->rx_addr.flags & ISOTP_MSG_FIXED_ADDR) != 0) { in add_ff_sf_filter()
598 } else if ((rctx->rx_addr.flags & ISOTP_MSG_IDE) != 0) { in add_ff_sf_filter()
604 prepare_filter(&filter, &rctx->rx_addr, mask); in add_ff_sf_filter()
606 rctx->filter_id = can_add_rx_filter(rctx->can_dev, receive_can_rx, rctx, &filter); in add_ff_sf_filter()
607 if (rctx->filter_id < 0) { in add_ff_sf_filter()
608 LOG_ERR("Error adding FF filter [%d]", rctx->filter_id); in add_ff_sf_filter()
619 k_timeout_t timeout) in isotp_bind() argument
626 __ASSERT(rx_addr && tx_addr, "RX or TX addr is NULL"); in isotp_bind()
629 rctx->can_dev = can_dev; in isotp_bind()
630 rctx->rx_addr = *rx_addr; in isotp_bind()
631 rctx->tx_addr = *tx_addr; in isotp_bind()
632 k_fifo_init(&rctx->fifo); in isotp_bind()
634 __ASSERT(opts->stmin < ISOTP_STMIN_MAX, "STmin limit"); in isotp_bind()
635 __ASSERT(opts->stmin <= ISOTP_STMIN_MS_MAX || in isotp_bind()
636 opts->stmin >= ISOTP_STMIN_US_BEGIN, "STmin reserved"); in isotp_bind()
638 rctx->opts = *opts; in isotp_bind()
639 rctx->state = ISOTP_RX_STATE_WAIT_FF_SF; in isotp_bind()
641 if ((rx_addr->flags & ISOTP_MSG_FDF) != 0 || (tx_addr->flags & ISOTP_MSG_FDF) != 0) { in isotp_bind()
650 rctx->rx_addr.ext_id, rctx->tx_addr.ext_id); in isotp_bind()
652 rctx->buf = net_buf_alloc_fixed(&isotp_rx_sf_ff_pool, timeout); in isotp_bind()
653 if (!rctx->buf) { in isotp_bind()
661 net_buf_unref(rctx->buf); in isotp_bind()
662 rctx->buf = NULL; in isotp_bind()
666 k_work_init(&rctx->work, receive_work_handler); in isotp_bind()
667 k_timer_init(&rctx->timer, receive_timeout_handler, NULL); in isotp_bind()
676 if (rctx->filter_id >= 0 && rctx->can_dev) { in isotp_unbind()
677 can_remove_rx_filter(rctx->can_dev, rctx->filter_id); in isotp_unbind()
680 k_timer_stop(&rctx->timer); in isotp_unbind()
682 sys_slist_find_and_remove(&global_ctx.ff_sf_alloc_list, &rctx->alloc_node); in isotp_unbind()
683 sys_slist_find_and_remove(&global_ctx.alloc_list, &rctx->alloc_node); in isotp_unbind()
685 rctx->state = ISOTP_RX_STATE_UNBOUND; in isotp_unbind()
687 while ((buf = k_fifo_get(&rctx->fifo, K_NO_WAIT))) { in isotp_unbind()
691 k_fifo_cancel_wait(&rctx->fifo); in isotp_unbind()
693 if (rctx->buf) { in isotp_unbind()
694 net_buf_unref(rctx->buf); in isotp_unbind()
700 int isotp_recv_net(struct isotp_recv_ctx *rctx, struct net_buf **buffer, k_timeout_t timeout) in isotp_recv_net() argument
705 buf = k_fifo_get(&rctx->fifo, timeout); in isotp_recv_net()
707 ret = rctx->error_nr ? rctx->error_nr : ISOTP_RECV_TIMEOUT; in isotp_recv_net()
708 rctx->error_nr = 0; in isotp_recv_net()
718 int isotp_recv(struct isotp_recv_ctx *rctx, uint8_t *data, size_t len, k_timeout_t timeout) in isotp_recv() argument
723 if (!rctx->recv_buf) { in isotp_recv()
724 rctx->recv_buf = k_fifo_get(&rctx->fifo, timeout); in isotp_recv()
725 if (!rctx->recv_buf) { in isotp_recv()
726 err = rctx->error_nr ? rctx->error_nr : ISOTP_RECV_TIMEOUT; in isotp_recv()
727 rctx->error_nr = 0; in isotp_recv()
735 while (rctx->recv_buf && copied < len) { in isotp_recv()
736 to_copy = MIN(len - copied, rctx->recv_buf->len); in isotp_recv()
737 memcpy((uint8_t *)data + copied, rctx->recv_buf->data, to_copy); in isotp_recv()
739 if (rctx->recv_buf->len == to_copy) { in isotp_recv()
741 rctx->recv_buf = net_buf_frag_del(NULL, rctx->recv_buf); in isotp_recv()
744 net_buf_pull(rctx->recv_buf, to_copy); in isotp_recv()
755 sctx->state = ISOTP_TX_ERR; in send_report_error()
756 sctx->error_nr = err; in send_report_error()
765 sctx->tx_backlog--; in send_can_tx_cb()
766 k_sem_give(&sctx->tx_sem); in send_can_tx_cb()
768 if (sctx->state == ISOTP_TX_WAIT_BACKLOG) { in send_can_tx_cb()
769 if (sctx->tx_backlog > 0) { in send_can_tx_cb()
773 sctx->state = ISOTP_TX_WAIT_FIN; in send_can_tx_cb()
776 k_work_submit(&sctx->work); in send_can_tx_cb()
783 if (sctx->state != ISOTP_TX_SEND_CF) { in send_timeout_handler()
788 k_work_submit(&sctx->work); in send_timeout_handler()
793 uint8_t *data = frame->data; in send_process_fc()
795 if ((sctx->rx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in send_process_fc()
796 if (sctx->rx_addr.ext_addr != *data++) { in send_process_fc()
809 if (frame->dlc < ISOTP_PADDED_FRAME_DL_MIN) { in send_process_fc()
818 sctx->state = ISOTP_TX_SEND_CF; in send_process_fc()
819 sctx->wft = 0; in send_process_fc()
820 sctx->tx_backlog = 0; in send_process_fc()
821 k_sem_reset(&sctx->tx_sem); in send_process_fc()
822 sctx->opts.bs = *data++; in send_process_fc()
823 sctx->opts.stmin = *data++; in send_process_fc()
824 sctx->bs = sctx->opts.bs; in send_process_fc()
825 LOG_DBG("Got CTS. BS: %d, STmin: %d", sctx->opts.bs, in send_process_fc()
826 sctx->opts.stmin); in send_process_fc()
831 k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); in send_process_fc()
832 if (sctx->wft >= CONFIG_ISOTP_WFTMAX) { in send_process_fc()
837 sctx->wft++; in send_process_fc()
856 if (IS_ENABLED(CONFIG_CAN_ACCEPT_RTR) && (frame->flags & CAN_FRAME_RTR) != 0U) { in send_can_rx_cb()
860 if (sctx->state == ISOTP_TX_WAIT_FC) { in send_can_rx_cb()
861 k_timer_stop(&sctx->timer); in send_can_rx_cb()
868 k_work_submit(&sctx->work); in send_can_rx_cb()
873 return sctx->is_net_buf ? net_buf_frags_len(sctx->buf) : sctx->len; in get_send_ctx_data_len()
878 if (sctx->is_net_buf) { in get_send_ctx_data()
879 return sctx->buf->data; in get_send_ctx_data()
881 return sctx->data; in get_send_ctx_data()
887 if (sctx->is_net_buf) { in pull_send_ctx_data()
888 net_buf_pull_mem(sctx->buf, len); in pull_send_ctx_data()
890 sctx->data += len; in pull_send_ctx_data()
891 sctx->len -= len; in pull_send_ctx_data()
903 prepare_frame(&frame, &sctx->tx_addr); in send_sf()
908 if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in send_sf()
909 frame.data[index++] = sctx->tx_addr.ext_addr; in send_sf()
912 if (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && in send_sf()
913 len > ISOTP_4BIT_SF_MAX_CAN_DL - 1 - index) { in send_sf()
920 if (len > sctx->tx_addr.dl - index) { in send_sf()
922 return -ENOSPC; in send_sf()
928 (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && in send_sf()
931 * Mandatory for ISO-TP CAN FD frames > 8 bytes. in send_sf()
936 can_dlc_to_bytes(frame.dlc) - len - index); in send_sf()
941 sctx->state = ISOTP_TX_SEND_SF; in send_sf()
942 ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); in send_sf()
954 prepare_frame(&frame, &sctx->tx_addr); in send_ff()
956 frame.dlc = can_bytes_to_dlc(sctx->tx_addr.dl); in send_ff()
958 if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in send_ff()
959 frame.data[index++] = sctx->tx_addr.ext_addr; in send_ff()
977 sctx->sn = 1; in send_ff()
979 pull_send_ctx_data(sctx, sctx->tx_addr.dl - index); in send_ff()
980 memcpy(&frame.data[index], data, sctx->tx_addr.dl - index); in send_ff()
982 ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); in send_ff()
995 prepare_frame(&frame, &sctx->tx_addr); in send_cf()
997 if ((sctx->tx_addr.flags & ISOTP_MSG_EXT_ADDR) != 0) { in send_cf()
998 frame.data[index++] = sctx->tx_addr.ext_addr; in send_cf()
1002 frame.data[index++] = ISOTP_PCI_TYPE_CF | sctx->sn; in send_cf()
1005 len = MIN(rem_len, sctx->tx_addr.dl - index); in send_cf()
1006 rem_len -= len; in send_cf()
1011 (IS_ENABLED(CONFIG_CAN_FD_MODE) && (sctx->tx_addr.flags & ISOTP_MSG_FDF) != 0 && in send_cf()
1014 * Mandatory for ISO-TP CAN FD frames > 8 bytes. in send_cf()
1019 can_dlc_to_bytes(frame.dlc) - len - index); in send_cf()
1024 ret = can_send(sctx->can_dev, &frame, K_MSEC(ISOTP_A_TIMEOUT_MS), send_can_tx_cb, sctx); in send_cf()
1026 sctx->sn++; in send_cf()
1028 sctx->bs--; in send_cf()
1029 sctx->tx_backlog++; in send_cf()
1039 if ((*sctx)->is_net_buf) { in free_send_ctx()
1040 net_buf_unref((*sctx)->buf); in free_send_ctx()
1041 (*sctx)->buf = NULL; in free_send_ctx()
1044 if ((*sctx)->is_ctx_slab) { in free_send_ctx()
1049 static int alloc_send_ctx(struct isotp_send_ctx **sctx, k_timeout_t timeout) in alloc_send_ctx() argument
1053 ret = k_mem_slab_alloc(&ctx_slab, (void **)sctx, timeout); in alloc_send_ctx()
1058 (*sctx)->is_ctx_slab = 1; in alloc_send_ctx()
1068 /* According to ISO 15765-2 stmin should be 127ms if value is corrupt */ in stmin_to_timeout()
1075 return K_USEC((stmin + 1 - ISOTP_STMIN_US_BEGIN) * 100U); in stmin_to_timeout()
1085 switch (sctx->state) { in send_state_machine()
1089 k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); in send_state_machine()
1090 sctx->state = ISOTP_TX_WAIT_FC; in send_state_machine()
1096 k_timer_stop(&sctx->timer); in send_state_machine()
1100 sctx->state = ISOTP_TX_WAIT_BACKLOG; in send_state_machine()
1106 send_report_error(sctx, ret == -EAGAIN ? in send_state_machine()
1112 if (sctx->opts.bs && !sctx->bs) { in send_state_machine()
1113 k_timer_start(&sctx->timer, K_MSEC(ISOTP_BS_TIMEOUT_MS), K_NO_WAIT); in send_state_machine()
1114 sctx->state = ISOTP_TX_WAIT_FC; in send_state_machine()
1117 } else if (sctx->opts.stmin) { in send_state_machine()
1118 sctx->state = ISOTP_TX_WAIT_ST; in send_state_machine()
1123 k_sem_take(&sctx->tx_sem, K_FOREVER); in send_state_machine()
1129 k_timer_start(&sctx->timer, stmin_to_timeout(sctx->opts.stmin), K_NO_WAIT); in send_state_machine()
1130 sctx->state = ISOTP_TX_SEND_CF; in send_state_machine()
1140 if (sctx->filter_id >= 0) { in send_state_machine()
1141 can_remove_rx_filter(sctx->can_dev, sctx->filter_id); in send_state_machine()
1145 k_timer_stop(&sctx->timer); in send_state_machine()
1147 if (sctx->has_callback) { in send_state_machine()
1148 sctx->fin_cb.cb(sctx->error_nr, sctx->fin_cb.arg); in send_state_machine()
1151 k_sem_give(&sctx->fin_sem); in send_state_machine()
1154 sctx->state = ISOTP_TX_STATE_RESET; in send_state_machine()
1174 if ((sctx->rx_addr.flags & ISOTP_MSG_IDE) != 0) { in add_fc_filter()
1180 prepare_filter(&filter, &sctx->rx_addr, mask); in add_fc_filter()
1182 sctx->filter_id = can_add_rx_filter(sctx->can_dev, send_can_rx_cb, sctx, in add_fc_filter()
1184 if (sctx->filter_id < 0) { in add_fc_filter()
1185 LOG_ERR("Error adding FC filter [%d]", sctx->filter_id); in add_fc_filter()
1205 if ((rx_addr->flags & ISOTP_MSG_FDF) != 0 || (tx_addr->flags & ISOTP_MSG_FDF) != 0) { in send()
1214 sctx->fin_cb.cb = complete_cb; in send()
1215 sctx->fin_cb.arg = cb_arg; in send()
1216 sctx->has_callback = 1; in send()
1218 k_sem_init(&sctx->fin_sem, 0, 1); in send()
1219 sctx->has_callback = 0; in send()
1222 k_sem_init(&sctx->tx_sem, 0, 1); in send()
1223 sctx->can_dev = can_dev; in send()
1224 sctx->tx_addr = *tx_addr; in send()
1225 sctx->rx_addr = *rx_addr; in send()
1226 sctx->error_nr = ISOTP_N_OK; in send()
1227 sctx->wft = 0; in send()
1228 k_work_init(&sctx->work, send_work_handler); in send()
1229 k_timer_init(&sctx->timer, send_timeout_handler, NULL); in send()
1231 switch (sctx->tx_addr.dl) { in send()
1233 if ((sctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { in send()
1234 sctx->tx_addr.dl = 8; in send()
1236 sctx->tx_addr.dl = 64; in send()
1248 if ((sctx->tx_addr.flags & ISOTP_MSG_FDF) == 0) { in send()
1254 LOG_ERR("Invalid TX_DL: %u", sctx->tx_addr.dl); in send()
1260 sctx->tx_addr.ext_id, sctx->rx_addr.ext_id); in send()
1262 if (len > sctx->tx_addr.dl - (((tx_addr->flags & ISOTP_MSG_EXT_ADDR) != 0) ? 2 : 1) - in send()
1263 ((sctx->tx_addr.dl > ISOTP_4BIT_SF_MAX_CAN_DL) ? 1 : 0)) { in send()
1272 sctx->state = ISOTP_TX_SEND_FF; in send()
1273 k_work_submit(&sctx->work); in send()
1276 sctx->filter_id = -1; in send()
1280 return ret == -EAGAIN ? in send()
1286 k_sem_take(&sctx->fin_sem, K_FOREVER); in send()
1287 ret = sctx->error_nr; in send()
1301 sctx->data = data; in isotp_send()
1302 sctx->len = len; in isotp_send()
1303 sctx->is_ctx_slab = 0; in isotp_send()
1304 sctx->is_net_buf = 0; in isotp_send()
1316 k_timeout_t timeout) in isotp_send_ctx_buf() argument
1323 ret = alloc_send_ctx(&sctx, timeout); in isotp_send_ctx_buf()
1328 sctx->data = data; in isotp_send_ctx_buf()
1329 sctx->len = len; in isotp_send_ctx_buf()
1330 sctx->is_net_buf = 0; in isotp_send_ctx_buf()
1340 k_timeout_t timeout) in isotp_send_net_ctx_buf() argument
1347 ret = alloc_send_ctx(&sctx, timeout); in isotp_send_net_ctx_buf()
1352 sctx->is_net_buf = 1; in isotp_send_net_ctx_buf()
1353 sctx->buf = data; in isotp_send_net_ctx_buf()
1364 k_timeout_t timeout) in isotp_send_buf() argument
1372 ret = alloc_send_ctx(&sctx, timeout); in isotp_send_buf()
1377 buf = net_buf_alloc_len(&isotp_tx_pool, len, timeout); in isotp_send_buf()
1385 sctx->is_net_buf = 1; in isotp_send_buf()
1386 sctx->buf = buf; in isotp_send_buf()