When error frame generate, How does relate to Trasmit Error Count? - can-bus

enter image description hereI have a question. I am using CANoe Simulation tool.
I know when a Error frame occurs. I heard that Error Frame condition is Transmit Error Count Should be
greater than 127.But first of all, On Screen Capture, An error frame occurs even though it is less than
What is the reason? and, Transmit Error Count 7 means consecutive dominant value error?
I want to clarify that ECU can't receive HU_DATC_E_03 Message because of Error Frame.
Please Help me
enter image description here

You got it backwards: functioning CAN nodes are always allowed to send error frames. Until the counter reaches 127, the node is in "error active" mode. Which means that the node is allowed to actively send error frames.
Beyond 127 it goes "error passive". This means that it is no longer allowed to send error frames, because the node is considered broken and should not be allowed to disrupt bus traffic any longer. It may still listen to the bus but not actively participate.
I don't know this specific tool, but tx error count supposedly just means that the tx error counter has reached the value 7 - that is, there have been 7 failed attempts to send a frame, for whatever reason. It shouldn't have anything necessarily have anything to do with bit stuffing (and CAN bit stuffs after 5 data bits, not 6 as some other networks do).

Related

What does CBATTError Code insufficientResources really mean?

I'm trying to send data over BLE from my iPhone to an ESP32 board. I'm developing in flutter platform and I'm using flutter_reactive_ble library.
My iPhone can connect to the other device and it can also send 1 byte using writeCharacterisiticWithResponse function. But when I try to send my real data which is large (>7000 bytes), it then gives me the error:
flutter: Error occured when writing 9f714672-888c-4450-845f-602c1331cdeb :
Exception: GenericFailure<WriteCharacteristicFailure>(
code: WriteCharacteristicFailure.unknown,
message: "Error Domain=CBATTErrorDomain Code=17
"Resources are insufficient."
UserInfo={NSLocalizedDescription=Resources are insufficient.}")
I tried searching for this error but didn't find additional info, even in Apple Developer website. It just says:
Resources are insufficient to complete the ATT request.
What does this error really means? Which resources are not sufficient and how to work around this problem?
This is almost certainly larger than this characteristic's maximum value length (which is probably on the order of 10s of bytes, not 1000s of bytes). Before writing, you need to call maximumWriteValueLength(for:) to see how much data can be written. If you're trying to send serial data over a characteristic (which is common, but not really what they were designed for), you'll need to break your data up into chunks and reassemble them on the peripheral. You will likely either need an "end" indicator of some kind, or you will need to send the length of the payload first so that the receiver knows how much to excpect.
First of all, a characteristic value cannot be larger than 512 bytes. This is set by the ATT standard (Bluetooth Core Specification v5.3, Vol 3, Part F (ATT), section 3.2.9). This number has been set arbitrarily by the protocol designers and does not map to any technical limitation of the protocol.
So, don't send 7000 bytes in a single write. You need to keep it at most 512 to be standard compliant.
If you say that it works with another Bluetooth stack running on the GATT server, then I guess CoreBluetooth does not enforce/check the maximum length of 512 bytes on the client side (I haven't tested). Therefore I also guess the error code you see was sent by the remote device rather than by CoreBluetooth locally as a pre-check.
There are three different common ways of writing a characteristic on the protocol level (Bluetooth Core Specification v5.3, Vol 3, Part G (GATT), section 4.9 Characteristic Value Write):
Write Without Response (4.9.1)
Write Characteristic Value (4.9.3)
Write Long Characteristic Values (4.9.4)
Number one is unidirectional and does not result in a response packet. It uses a single ATT_WRITE_CMD packet where the value must be at most ATT_MTU-3 bytes in length. This length can be retrieved using maximumWriteValueLength(for:) with .withoutResponse. The requestMtu method in flutter_reactive_ble uses this method internally. If you execute many writes of this type rapidly, be sure to add flow control to avoid CoreBluetooth dropping outgoing packets before they are sent. This can be done through peripheralIsReadyToSendWriteWithoutResponse by simply always waiting for this callback after each write, before you write the next packet. Unfortunately, it seems flutter_reactive_ble does not implement this flow control mechanism.
Number two uses a single ATT_WRITE_REQ where the value must be at most ATT_MTU-3 bytes in length, just as above. Use the same approach as above to retrieve that maximum length (note that maximumWriteValueLength with .withResponse always returns 512 and is not what you want). Here however, either an ATT_WRITE_RSP will be returned on success or an error packet will be received with an error code. Only one ATT transaction can be outstanding at a time, which significantly lowers throughput compared to Write Without Response.
Number three uses a sequence of multiple ATT_PREPARE_WRITE_REQ packets (containing offset and value) followed by an ATT_EXECUTE_WRITE_REQ. The maximum length of the value in each each chunk is ATT_MTU-5. Each _REQ packet also requires a corresponding _RSP packet before it can continue (alternatively, an error code could be sent by the remote device). This approach is used when the characteristic value to be written is too long to be sent using a single ATT_WRITE_REQ.
For any of the above write methods, you are always also limited by the maximum attribute size of 512 bytes as per the specification.
Any Bluetooth stack I know of transparently chooses between "Write Characteristic Value" and "Write Long Characteristic Values" when you tell it to write with response, depending on the value length and MTU. Server side it's a bit different. Some stacks put the burden on the user to combine all packets but it seems nimble handles that on its own. From what I can see in the source code (https://github.com/apache/mynewt-nimble/blob/26ccb8af1f3ea6ad81d5d7cbb762747c6e06a24b/nimble/host/src/ble_att_svr.c#L2099) it can return the "Insufficient Resources" error code when it tries to allocate memory but fails (most likely due to too much buffered data). This is what might happen for you. To answer your first actual question, the standard itself does not say anything else about this error code than simply "Insufficient Resources to complete the request".
The error has nothing to do with LE Data Length extension, which is simply an optimization for a lower layer (BLE Link Layer) that does not affect the functionality of the host stack. The L2CAP layer will take care of the reassembling of smaller link layer packets if necessary, and must always support up to the negotiated MTU without overflowing any buffers.
Now, to answer your second question, if you send very large amounts of data (7000 bytes), you must divide the data in multiple chunks and come up with a way to correctly be able to combine them. Each chunk is written as a full characteristic value. When you do this, be sure to send values at most of size ATT_MTU-3 (but never larger than 512 bytes), to avoid the inefficient overheads of "Write Long Characteristic Values". It's then up to your application code to make sure you don't run out of memory in case too much data is sent.

Why would SQS ApproximateNumberOfMessagesVisible & ApproximateAgeOfOldestMessage go up even when Received/Deleted metrics match Sent metrics?

In the CloudWatch Metrics graph below, the purple line is ApproximateNumberOfMessagesVisible and red line is ApproximateAgeOfOldestMessage. They are trending up even when NumberOfMessagesReceived (orange)/NumberOfMessagesDeleted (green) match NumberOfMessagesSent (blue).
How is this possible?
In my code, I process the message in a new thread and therefore the message is almost immediately deleted from the queue. (This is not good practice in production but this is a load testing script so I don't expect or care about exceptions)
sqsClient.receiveMessage(queueUrl).getMessages().forEach(msg -> {
pool.execute(() -> handleSqsMessage(msg));
sqsClient.deleteMessage(queueUrl, msg.getReceiptHandle());
});
If the approximateAgeOfOldestMessage is increasing then it indicates that there is a poison pill. A poison pill is a malformed message which is unable to get processed by the consumer.
What is your redrive policy ? You will have to set the max-receive-count to a smaller value (say 3 for example). After the message is received 3 times by the consumer, if it was not able to process/delete it will be moved to dead letter queue. You can then analyze this poison pill.
If the number of visible messages are increasing consistently, it indicates that your consumer is unable to catch up and messages are piling up in the queue. This is not necessarily a bad sign but shouldn't be very large. Seems ok to me. You can increase the number of consumers to bring it down.
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html#sqs-dead-letter-queues-when-to-use
https://aws.amazon.com/message-queue/features/

dispatch_io_read a socket will wait for more data if receiving data size is smaller than length

Hi I am using dispatch_io_read with a socket in swift 2 on Xcode 7 Beta3. It looks like the read action will hold there when the expected receiving data size is smaller than the length I specified. For example,
If I do
dispatch_io_read(channel!, 0, 1000, inputQueue!, myReadHandler)
and the data from the server is less than 1000 bytes, myReadHandler will never get called.
To solve this, I have to do read bytes one by one, is there a better solution?
Thanks.
This probably is a little late, but for anyone who has the same problem
apple's documentation shows that..
"The length parameter indicates the number of bytes that should be read from the I/O channel. Pass SIZE_MAX to keep reading until EOF is encountered (for a channel created from a disk-based file this happens when reading past the end of the physical file)."
So, simply using SIZE_MAX will read all the available data attached to the file descriptor.
Unfortunately, this seems to not work due to a bug in Swift 3 with DispatchIO.read().

CAN Network With Single Node (CAN protocol)

I am new to CAN protocol, going through the Robert Bosch's CAN Specification ver2.0 Part B. I can't understand the following lines on page 63
" Note:
Start up / Wake up:
if during startup only one node is online, and if this node transmits some message, it will get no acknowledgement, detect an error and repeats the message. It can become 'error passive' but not 'bus off' due to this reason."
As far as I understand when a transmitter detects an error(like Acknowledgement error) it retransmits the message and also increments the transmit error count (TEC) by 8. So if there is only one node then its TEC should increase by 8 everytime it transmits a message and should go into 'bus off' condition once TEC goes above 255.
Can someone please explain why the specification says it can only go 'Error Passive' but not 'Bus off'?
I think you missed this part of the specification:
"Exception 1:
If the TRANSMITTER is 'error passive' and detects an ACKNOWLEDGEMENT ERROR because of not detecting a 'dominant' ACK and does not detect a 'dominant' bit while sending its PASSIVE ERROR FLAG.
"
In this case, the TEC is not changed!
So, in your case, when the only node in the network re-transmits every time and the TEC becomes >= 128, it becomes 'error passive'. Then the above exception case becomes valid! And the TEC is no more changed! Hence no 'bus off'.
Yes, that is correct as if the Tx ECU is not receiving any ACK from any ECU in the CAN network then it will stay in Error passive state.
Because the Networking protocol needs when more than one systems are available in CAN network and if no ECU available in the network, then it is not meaning as the ECU is having an issue, so instead of going to CAN bus off state it should stay in Error passive state.
To know more about CAN error, you can follow the below link:

CAN 2.0 - fault confinement - modification of error counters

There's one thing in CAN 2.0B specification which I'm not sure if I understand correctly.
In chapter 8 - Fault Confinement - there are following rules regarding modification of error counters:
Rule2: When a RECEIVER detects a 'dominant' bit as the first bit after sending an ERROR FLAG the RECEIVE ERROR COUNT will be increased by 8.
And
Rule6: Any node tolerates up to 7 consecutive 'dominant' bits after sending an ACTIVE ERROR FLAG, PASSIVE ERROR FLAG or OVERLOAD flag. After detecting the 14th consecutive 'dominant' bit 9in case of ACTIVE ERROR FLAG or an OVERLOAD FLAG) or after detecting the 8th consecutive 'dominant' bit following a PASSIVE ERROR FLAG, and after each sequence of additional eight consecutive 'dominant' bits every TRANSMITTER increases its TRANSMIT ERROR COUNT by 8 and every RECEIVER increases its RECEIVE ERROR COUNT by 8.
So does rule2 mean that if node A sends an error frame and after sending 6 dominant bits (error flag) it detects that next bit is dominant it should increase its RECEIVE ERROR COUNTER? I thought it's OK that there might be more than 6 dominant bits in error flag (6 to 12 to be precise)... Also, rule6 says " Any node tolerates up to 7 consecutive 'dominant' bits after (...) "
Rule6 also says about sequence of 8 consecutive dominant bits. But for what exactly is this rule applying? Only for such sequences which comes after initial transmission of an error frame?
Let's have an example:
Node A sends an error frame, other nodes start to send their own error frames.
Node A sends 6 bits of its error flag, then detects 7th dominant bit (increase counter? - rule2)
Then we have another 6 dominant bits and after the 14th dominant bit node A increase its error counter again (first part of rule6).
Then we have another 8 dominant bits - node A increases its error counter again (second part of rule6).
Am I correct? I'm so confused with these rules and I need to understand them thoroughly. Hope somebedy will help me :)

Resources