# Various questions about libcanard

**URL:** <https://forum.opencyphal.org/t/various-questions-about-libcanard/928>\
**Category:** Libcanard\
**Created:** [August 25, 2020, 6:52am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928 "2020-08-25T06:52:13Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 6, 2020, 3:48pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/25 "2020-09-06T15:48:04Z")

</div>

What does this code to do at canardRxAccept in canard.c

```auto
         while ((sub != NULL) && (sub->_port_id != model.port_id))
                {
                	
                    sub = sub->_next;
                 
                }

```

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 6, 2020, 4:01pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/26 "2020-09-06T16:01:26Z")

</div>

> **[Linked list](https://en.wikipedia.org/wiki/Linked_list)**
>
> In computer science, a linked list is a linear collection of data elements whose order is not given by their physical placement in memory. Instead, each element points to the next. It is a data structure consisting of a collection of nodes which together represent a sequence. In its most basic form, each node contains data, and a reference (in other words, a link) to the next node in the sequence. This structure allows for efficient insertion or removal of elements from any position in the sequen...

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 6, 2020, 4:08pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/27 "2020-09-06T16:08:13Z")

</div>

Thank you very,very, very much!

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 7, 2020, 3:37am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/28 "2020-09-07T03:37:37Z")

</div>

```auto
      // There are two possible reasons why the session may not exist: 1. OOM; 2. SOT-miss.
        if (subscription->_sessions[frame->source_node_id] != NULL)
        {  
            CANARD_ASSERT(out == 0);
            out = rxSessionUpdate(ins,
                                  subscription->_sessions[frame->source_node_id],
                                  frame,
                                  redundant_transport_index,
                                  subscription->_transfer_id_timeout_usec,
                                  subscription->_payload_size_max,
                                  out_transfer);
        }

```

What does “SOT-miss.” mean？

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 7, 2020, 7:35am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/29 "2020-09-07T07:35:15Z")

</div>

Start of transfer?

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 7, 2020, 8:18am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/30 "2020-09-07T08:18:56Z")

</div>

```auto
   out->payload_size = frame->payload_size- 1U; // Cut off the tail byte.

```

I found that this line of code caused me to miss one byte of data that I received. Could you please give me some guidance?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 7, 2020, 2:47pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/31 "2020-09-07T14:47:40Z")

</div>

> [@newcomer](#):
>
> I found that this line of code caused me to miss one byte of data that I received. Could you please give me some guidance?

You don’t need this byte because it contains the transport metadata that is consumed by the library.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 18, 2020, 3:58am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/32 "2020-09-18T03:58:17Z")

</div>

When I continuously send the heartbeat node and the custom node information, after being processed by canardRxAccept, I can only receive each node once, from which canardRxAccept will not return 1. Why?

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 18, 2020, 6:17am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/33 "2020-09-18T06:17:03Z")

</div>

Is it because it’s the first frame of a transfer?

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 18, 2020, 8:17am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/34 "2020-09-18T08:17:17Z")

</div>

And. When i send 8 bytes,canardRxAccept return 0 , how to send multi frame ? 😭

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 18, 2020, 6:06pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/35 "2020-09-18T18:06:54Z")

</div>

Re first question: you probably forgot to make the transfer-ID variable static. If that’s the case, then you’re sending multiple transfers under the same transfer-ID, which are then rejected by the receiving node as duplicates.

Re second question: sending a multi-frame transfer is no different from sending a single-frame transfer.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 1:51am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/36 "2020-09-19T01:51:43Z")

</div>

I’m confused about tranfer-ID.  
I made "static uint8\_t my\_message\_transfer\_id;"And “+ + my\_message\_transfer\_id;”  
However, when I sent the transfer-ID, I did not send it to the receiver, but only transmitted the data(.payload) to the receiver. So how to set the tail byte of the data I sent?

```auto
                       uint8_t my_msg[10] = {0};
			canardDSDLSetUxx(&my_msg[0], 0, 10, 8);   
			canardDSDLSetUxx(&my_msg[0], 8, 110, 8);   
			canardDSDLSetUxx(&my_msg[0], 16, 120, 8);   
			canardDSDLSetUxx(&my_msg[0], 24, 87, 8);   
			canardDSDLSetUxx(&my_msg[0], 32, 12, 8);   
			canardDSDLSetUxx(&my_msg[0], 40, 99, 8);   
			canardDSDLSetUxx(&my_msg[0], 48, 0xDEADAA, 24); 
// ----------------------------------- how to set the tail byte ---------------------------------------------------------------------------------   
canardDSDLSetUxx(&my_msg[0], 72, ?????, 8); // how to set the tail byte ?

						
			static uint8_t mymsg_transfer_id;				
			const CanardTransfer mytransfer = {
				.timestamp_usec = 0,      
				.priority = CanardPriorityNominal,
				.transfer_kind = CanardTransferKindMessage,
				.port_id = 32080, // This is the subject-ID.
				.remote_node_id = CANARD_NODE_ID_UNSET, // Messages cannot be unicast, so use UNSET.
				.transfer_id = mymsg_transfer_id,
				.payload_size = 10,   
				.payload = &my_msg[0], 
			};
			++mymsg_transfer_id;  
			int32_t myresult = canardTxPush(&ins, &mytransfer); 
                        ……………………(omit)
                        	
		uint8_t fail_count;
		FDCAN_TxHeaderTypeDef *txmsg = NULL;

		for (const CanardFrame* txf = NULL; (txf = canardTxPeek(&ins)) != NULL;) // Look at the top of the TX queue.
		{
			printf("enter txmsg:\n");
			uint8_t sendbuf[64] = {0};

			txmsg->Identifier = txf->extended_can_id; //32085txf->extended_can_id
	txmsg->DataLength = (txf->payload_size-1) << 16 & 0x000F0000U; //to set the stm32 FDCAN_TxHeaderTypeDef
			txmsg->IdType = FDCAN_EXTENDED_ID;
			txmsg->FDFormat = FDCAN_FD_CAN;
			txmsg->TxFrameType = FDCAN_DATA_FRAME;
			txmsg->BitRateSwitch = FDCAN_BRS_OFF;
			txmsg->TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
			txmsg->ErrorStateIndicator = FDCAN_ESI_ACTIVE;
			txmsg->MessageMarker = 0x01;

			memcpy(sendbuf,txf->payload,(txf->payload_size-1)); 

//-------------use stm32 fdcan send to the receiver ,only send buf, do not send transfer-id to receiver------------------------------
HAL_StatusTypeDef ret = HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, txmsg, sendbuf); 
		HAL_FDCAN_Start(&hfdcan1); /

```

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 19, 2020, 3:14am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/37 "2020-09-19T03:14:09Z")

</div>

> [@newcomer](#):
>
> when I sent the transfer-ID, I did not send it to the receiver, but only transmitted the data(.payload) to the receiver. So how to set the tail byte of the data I sent?

Replace this:

```auto
txmsg->DataLength = (txf->payload_size-1) << 16 & 0x000F0000U;

```

With this:

```auto
txmsg->DataLength = convertDataLengthToFDCANDLC(txf->payload_size);

```

Where `convertDataLengthToFDCANDLC` is defined as:

```c
uint32_t convertDataLengthToFDCANDLC(const size_t length)
{
    static const uint32_t Lookup[65] = { // TODO Please carefully check these.
        // 0-8
        FDCAN_DLC_BYTES_0,
        FDCAN_DLC_BYTES_1,
        FDCAN_DLC_BYTES_2,
        FDCAN_DLC_BYTES_3,
        FDCAN_DLC_BYTES_4,
        FDCAN_DLC_BYTES_5,
        FDCAN_DLC_BYTES_6,
        FDCAN_DLC_BYTES_7,
        FDCAN_DLC_BYTES_8,
        // 9-12
        FDCAN_DLC_BYTES_12,
        FDCAN_DLC_BYTES_12,
        FDCAN_DLC_BYTES_12,
        FDCAN_DLC_BYTES_12,
        // 13-16
        FDCAN_DLC_BYTES_16,
        FDCAN_DLC_BYTES_16,
        FDCAN_DLC_BYTES_16,
        FDCAN_DLC_BYTES_16,
        // 17-20
        FDCAN_DLC_BYTES_20,
        FDCAN_DLC_BYTES_20,
        FDCAN_DLC_BYTES_20,
        FDCAN_DLC_BYTES_20,
        // 21-24
        FDCAN_DLC_BYTES_24,
        FDCAN_DLC_BYTES_24,
        FDCAN_DLC_BYTES_24,
        FDCAN_DLC_BYTES_24,
        // 25-32
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        FDCAN_DLC_BYTES_32,
        // 33-48
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        FDCAN_DLC_BYTES_48,
        // 49-64
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
        FDCAN_DLC_BYTES_64,
    };
    // TODO Check the array bounds.
    return Lookup[length];
}

```

You are not supposed to do anything with the tail byte yourself. The library does it automatically, just let it do its job.

Note that I did not test any of this.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 3:24am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/38 "2020-09-19T03:24:45Z")

</div>

> [@pavel.kirienko](#):
>
> You are not supposed to do anything with the tail byte yourself. The library does it automatically, just let it do its job.

Does that mean I can just write my data?Don’t I have to deliberately modify the last byte in the data?

```auto
            uint8_t my_msg[10] = {0};
			canardDSDLSetUxx(&my_msg[0], 0, 10, 8);   
			canardDSDLSetUxx(&my_msg[0], 8, 110, 8);   
			canardDSDLSetUxx(&my_msg[0], 16, 120, 8);   
			canardDSDLSetUxx(&my_msg[0], 24, 87, 8);   
			canardDSDLSetUxx(&my_msg[0], 32, 12, 8);   
			canardDSDLSetUxx(&my_msg[0], 40, 99, 8);   
			canardDSDLSetUxx(&my_msg[0], 48, 0xDEADAA, 24); 
// ----------------------------------- how to set the tail byte ---------------------------------------------------------------------------------   
canardDSDLSetUxx(&my_msg[0], 72, ?????, 8); // how to set the tail byte ?

```

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 19, 2020, 3:25am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/39 "2020-09-19T03:25:47Z")

</div>

Of course, that’s what the library is for.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 3:27am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/40 "2020-09-19T03:27:10Z")

</div>

But i found i do that , i can not receive anything . 😭

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 3:34am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/41 "2020-09-19T03:34:28Z")

</div>

When i send single frame, make the last data “0xff” , i can receive once . If do not do that ,i can not receive anything. 😑

```auto
			uint8_t my_msg[4] = {0};
			canardDSDLSetUxx(&my_msg[0], 0, 10, 8); // msg1
			canardDSDLSetUxx(&my_msg[0], 8, 110, 8); // msg2
			canardDSDLSetUxx(&my_msg[0], 16, 120, 8); // msg1
			canardDSDLSetUxx(&my_msg[0], 24, 0xff, 8); // msg2

```

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [September 19, 2020, 3:45am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/42 "2020-09-19T03:45:42Z")

</div>

This is because you are truncating the tail byte in your `txmsg->DataLength = (txf->payload_size-1) << 16 & 0x000F0000U;`.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 3:52am UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/43 "2020-09-19T03:52:25Z")

</div>

OK, thank you very much. I try it again.

---

<div class="post-metadata">

**Author:** ![newcomer](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/n/e5b9ba/32.png) [@newcomer](https://forum.opencyphal.org/u/newcomer)\
**Post date:** [September 19, 2020, 5:05pm UTC](https://forum.opencyphal.org/t/various-questions-about-libcanard/928/44 "2020-09-19T17:05:43Z")

</div>

When i receive data , the receive data length is set to "received\_frame.payload\_size = RxHeader.DataLength \>\> 16 ;  
If the data i send is 10 bytes , it can not receive anything. How can i set the received\_frame.payload\_size correctly?  
Thanks.

```auto

				FDCAN_RxHeaderTypeDef RxHeader={0};

				uint8_t recdata[64] = {0};  
				uint8_t payload_recdata[64] = {0}; 
				CanardFrame received_frame = {0};
			   	received_frame.payload = &payload_recdata;

				 if(HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, recdata) == HAL_OK) 
				{
					 
				CanardTransfer receive={0}; 
				received_frame.extended_can_id = RxHeader.Identifier ;
				received_frame.payload_size = RxHeader.DataLength ; 

				memcpy(payload_recdata,recdata,received_frame.payload_size)

				uint8_t result = canardRxAccept(&ins,
										&received_frame, // The CAN frame received from the bus.
										0, // If the transport is not redundant, use 0.
										&receive);
				if (result < 0)
				{
					// An error has occurred: either an argument is invalid or we've ran out of memory.
					// It is possible to statically prove that an out-of-memory will never occur for a given application if
					// the heap is sized correctly; for background, refer to the Robson's Proof and the documentation for O1Heap.
					// Reception of an invalid frame is NOT an error.
					printf("RxAccept failure\n");
					printf("An error has occurred: either an argument is invalid or we've ran out of memory.\n");
					abort();
				}
				else if (result == 1) 
				{
					uint8_t final_data[64] = {0};
					memcpy( final_data,receive.payload,receive.payload_size);
					uint8_t mode = canardDSDLGetU8(final_data, receive.payload_size, 34, 3);
					uint32_t uptime = canardDSDLGetU32(final_data, receive.payload_size, 0, 32);
					uint32_t vssc = canardDSDLGetU32(final_data, receive.payload_size, 37, 19);
					uint8_t health = canardDSDLGetU8(final_data, receive.payload_size, 32, 2);

					printf("mode = %d\n",mode);
					printf("health = %d\n",health);
					printf("uptime = 0x%x\n",uptime);
					printf("vssc = 0x%x\n",vssc);

					ins.memory_free(&ins, (void*)receive.payload); // Deallocate the dynamic memory afterwards.
				}
				else
				{

					// Nothing to do.
					// The received frame is either invalid or it's a non-last frame of a multi-frame transfer.
					// Reception of an invalid frame is NOT reported as an error because it is not an error.
					printf("nothing to do \n");

				}

```

[Previous page](https://forum.opencyphal.org/t/various-questions-about-libcanard/928.md?page=1)

[Next page](https://forum.opencyphal.org/t/various-questions-about-libcanard/928.md?page=3)
