socketcan Candump - How Can I extend CAN ID? - linux

I would like to receive the vehicle's CAN data to the socket CAN and send it to the server. (raw data)
Accordingly, CAN ID is very important in post-processing raw data sent to the server.
The CAN data ID received by Candump and wireshark is only 3 digits, so it is difficult to distinguish which data it is.
For example, although the CAN ID I need to receive is 0x1f532d10, only d10 is received and displayed from socketcan.
Is there any way to get the ID length as a whole?

If you're using SocketCAN to send frames you need to set the "Extended Frame Format" bit in the can_id field of the can_frame struct, e.g.:
frame.can_id |= CAN_EFF_FLAG;

Related

Multiplex connection over a single TCP socket

Let's assume I have two machines, A and B, which run two programs each:
A.1 needs to talk to B.1 (duplex)
A.2 needs to talk to B.2 (duplex)
A TCP socket (duplex) connects A to B.
Upon reception of a message from A, B needs to know where to dispatch the message: should it go to B.1, or B.2 ? And vice versa.
A naive idea could be to prefix each message with a kind of header identifying the program to map to. Instead of sending "message to B.1", A could send "1: message to B.1". Upon reception, B sees the header "1: ", and knows to send "message to B.1" to B.1.
The problem is that messages can be split and when A sends "1: message to B.1", B could very well receive several chunks:
"1: me"
"ssage"
" to B"
".1"
If the chunks all have the same length, I can split the original messages in small chunks, each prefixed with a header. That adds some overhead, but that's fine.
The problem is: I am not sure I can configure the chunk size. Chunks may be of random lengths. If both A.1 and A.2 write to B.1 and B.2 respectively, I am not sure how B can know how to properly dispatch the chunks to the right recipients.
I'm using nodejs by the way. I'll look into the readableHighWaterMark and writableHighWaterMark options of the Duplex module to see if I can fix the chunk size, but I'm not sure this is how it works.
Any tips / ideas?
Header should be fixed size and contain both target program id and current chunk data size.
On receiving size - read fixed size header, then read exactly nnn bytes of data as specified in header (you have to call read/recv repeatly until entire chunk received) and dispatch that data to corresponging program. Then read next header etc etc etc

Distinction Between Manufacturing Data, Service Data and Advertising Data in Bluetooth LE

In terms of BLE, I'm getting a little confused between the terms and their usage in BlueZ:
Manufacturer Data
Service Data
Advertising Data
I'm going to try to sum up what I understand and where that falls apart.
From here there is a payload in the Advertising Packet that is 31 bytes long that can be used for User Defined Data.
However, BlueZ in its advertising API have a different notion of data. It takes a dict which is of <type> <byte array> from the docs.
Looking a little more you can come across this table which seems to be of the same two byte type and data structure.
It has user defined payload in terms of:
0xFF «Manufacturer Specific Data» Bluetooth Core Specification:Vol. 3, Part C, section 8.1.4 (v2.1 + EDR, 3.0 + HS and 4.0)Vol. 3, Part C, sections 11.1.4 and 18.11 (v4.0)Core Specification Supplement, Part A, section 1.4
So I downloaded the spec to try to read up on the distinction, which leads me to this sentence that I don't quite follow:
The data is sent in advertising or periodic advertising events. Host Advertising
data is placed in the AdvData field of ADV_IND, ADV_NONCONN_IND,
ADV_SCAN_IND, AUX_ADV_IND, and AUX_CHAIN_IND PDUs. Additional
Controller Advertising Data is placed in the ACAD field of AUX_ADV_IND,
AUX_SYNC_IND, and AUX_SCAN_RSP PDUs. Periodic Advertising data is
placed in the AdvData field of AUX_SYNC_IND and AUX_CHAIN_IND PDUs.
Scan Response data is sent in the ScanRspData field of SCAN_RSP PDUs or
the AdvData field of AUX_SCAN_RSP PDUs. If the complete data cannot fit in
the AdvData field of an AUX_ADV_IND, AUX_SYNC_IND, or
AUX_SCAN_RSP PDU, AUX_CHAIN_IND PDUs are used to send the
remaining fragments of the data. An AD Structure may be fragmented over two
or more PDUs
Also when I look in the BlueZ implementation of their own DBUS API, I see they provide a way to fill in manufacturing data but no way to change the type of advertising (ADV_NONCONN vs ADV_CONN)
.
They also do have an adv_data type but it's only 25 bytes? Why can I not get the full 31 bytes?
https://github.com/bluez/bluez/blob/cbbb0c2ead89ed19280ecd94e8a2fb0d22216bb6/client/advertising.c#L55
Actual Questions:
When implementing a BT peripheral using BlueZ do I have 31 or 25 bytes. Can I fill in both Service Data and Manufacturer Data for a total of 50 bytes??
Is Manufacturer Data an abstraction over Advertising Data? If so how can I access the underlying Advertising Data? If not, can I theoretically fill in both Advertising and Manufacturer data?
The image below created by Jos Ryke might be helpful to visualise what is happening.
As shown in the image, ADV FLAGS and Advertisement data make up the 31 bytes advertising payload, but there are only 26 bytes for data available. The image contains examples of Manufacturer Data (type = FF) and Service Data (type = 16)
In the D-Bus API, to change the type of advertising (ADV_NONCONN vs ADV_CONN) use the type property:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertising-api.txt#n37
broadcast = ADV_NONCONN
You can have both service and manufacturer data in the same advertisement (see example https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-advertisement#n141) but it cannot be longer than 31 bytes. With BlueZ, you can register (if I remember correctly) up to four advertisements that will be sent as different packets.
So in summary, service data and manufacturer data are sub elements types within advertising payload. BlueZ allows you to build up the different data types you want in your advertisement and then register it for broadcast.

How to receive data into other locations

I want to know how to receive data into another variable, not the APDU buffer.
It is possible call the method setIncomingAndReceive() or receiveBytes() to receive data into the APDU buffer. But I want for card to receive data into another variable, not the APDU buffer.
In case of sending a reponse APDU, the method sendBytesLong(byte[] outData, short bOff, short len) supports sending data from other array variables, not APDU buffer. But it seems that there is no method which supports receiving data into other variables.
I hope somebody knows the method or the sample code to receive the data into the other variable.
There is no way to do that. If you need to copy the incoming data to another buffer, simply copy it using Util.arrayCopyNonAtomic().
Side note: APDU.sendBytesLong() copies the data from your buffer into the APDU buffer and then sends it out. This API is provided just so that you don't have to do the copy in your applet.

Best way to store data using APDU's?

I have bunch of records in my offcard application and I want to save them all in javacard,
The question is:
What is the best way of transferring data to Java Card?
Should I transfer all data record by record (each one with a APDU) or send all the records in just one APDU?
Of course I know the limitation size of APDU and I'm using extended APDU in order to send all data just in one extended APDU which is more than 255 bytes..
It does not matter much if you send your data in one extended length APDU or one single APDU security wise. It is however much better to send unrelated information using separate APDU's. This would make your application much more modular. Note that if you send related information using separate APDU's, you may need to keep state between those APDU's for validation purposes (e.g. you may have to send either none or all of them, or send the APDU's in specific order).
Furthermore, ISO 7816-4 only defines 2 byte status words to send back to the sender, e.g. 8A80 to indicate any error in the command data. This means that it is impossible to tell from the status word which of the records contains failure information.
Finally, there are certainly still readers and software out there that have issues handling extended length APDU's. So if your software is going to be used by other parties you may want to stick to normal length APDU's.

How get data from glucometers in J2ME using serial port?

I have to do an application for a GPRS modem JAVA (J2ME) programmable that must interface with an electromedical device (glucometer).
I have an input buffer and an output buffer on the serial port of the device.
When the application starts, I listen on the serial port and I receive from the glucometer one byte with the decimal code "5" which corresponds, to the ASCII table, the symbol of Enquiry and after 15 seconds I get the bytes "4" that corresponds to the End of Transmission.
To receive data from the glucometer I need to send an ACK signal (acknowledge) which corresponds to the byte "6".
I tried the following forms:
outBuffer.write("ACK\r\n".getBytes()); //first without setting the charset and after I trying to set all the charset.
I tried to send a byte buffer like this:
byte[] bSend = new byte[] { 6 };
outBuffer.write(bSend); //(I tried also with the byte 10 (LF) and 13 (CR)).
The result is that I can not receive data but I get ​​cyclically but only the values 5 and 4.
With all the software that can comunicate with serial port (like Serial Monitor) if I send an ACK message I receive data from glucometer correctly.
I think my problem is due to the value of the ACK coding in Java, someone can indicate any solution?
As this seems to be a pretty low-level interface that uses ASCII control characters to do its communication I think you need to send these byte values verbatim, and without extra stuff like newlines or whatever. This means that
byte[] bSend = new byte[] { 6 };
outBuffer.write(bSend);
Is the correct approach. Now, this protocol looks a lot like ASTM E1381, so I checked here and paragraph 6.1.2 might be related to your problem:
When the meter initiates the Establishment Phase, the meter determines
if the computer is connected by initially sending an <ENQ> character.
If the computer responds within 15 seconds by sending an <ACK>
character, the meter proceeds with Data Transfer Mode. If the computer
responds within 15 seconds with a <NAK> character, the meter sends an
<EOT> then attempts to enter Remote Command Mode, by looking for an
<ENQ> character from the computer. Also see "Section 6.2 Remote
Command Mode Protocol". Any response within 15 seconds to the meter’s
<ENQ> other than an <ACK> or <NAK> character causes the meter to send
an <EOT>, delay one second, then send another <ENQ>. If the computer
does not respond within 15 seconds, then the meter sends an <EOT>,
delays one second, then sends another <ENQ> and waits again for a
response from the computer. Note: One second after sending an <ENQ>,
the meter may enter a low power mode. Thus, there is a possibility
that the first <ACK> sent by the computer is not read correctly. In
this case, the meter responds with an <EOT>, delays one second, then
sends another <ENQ>.
Emphasis mine, I guess that that's what's happening. So, you should repeat sending another ENQ to get it into data transfer mode, assuming that that's what you want.
it should be
byte bSend=(byte)0x6;
outBuffer.write(bSend);

Resources