Reading an incoming/received Lora frame with I-Cube End-node sample code - stm32

I'm using the ST I-Cube End-node sample code (in C) embedded on the B-L072Z-LRWAN1 discovery kit board and transmitting a LoRaWAN packet to my End-node device.
I'm seeing that the packet has been received by the end device because it prints:
"PACKET RECEIVED ON PORT 1"
But I don't know how or where the received packet is stored.
How can I print and access the packet data/payload that I have transmitted to my node?
Appreciate the help!

A function with the signature void LORA_RxData(lora_AppData_t *AppData) has been declared and defined wherein the lora_AppData_t contains the downlink LoRaWAN payload.
The available member variables are:
message buffer: AppData->Buff
Size of the message buffer: AppData->BuffSize
Port of the received message: AppData->Port
This all can be found in the files lora.h and lora.c. These files contain ST's implemenentation of the LoRaMac-node
The function is defined with __weak so you can define your own LORA_RxData to process the data on your own terms. If you don't redefine it it will use the default.

Related

How socketcan get send failure status?

As we all know, in the CAN bus communication protocol, sender know whether the data was successfully sent. I send socketcan data as follows.
ret = write (socket, frame, sizeof (struct can_frame));
However, even if the CAN communication cable is disconnected, the return value of ret is still 16(=sizeof (struct can_frame)).I queried the information and found that the problem was due to the tx_queue of the network stack used by socketcan. When write is called multiple times, the buffer is full and the return value of ret is -1.
But this is not the behavior I expect, I hope that every frame of data sent will immediately get the status of success or failure.
By
echo 0> / sys / class / net / can0 / tx_queue_len
I want to cancel the tx_queue, but it does not work.
What I want to ask is, is there a way to cancel the tx_queue of socketcan, or to get the status of the each sending frame about controller through the API (such as libsocketcan).
Thanks.
You cannot use write() itself to discover whether a CAN frame was successfully put on the bus, because all it does is write the frame to the in-kernel socket buffer. The kernel then moves the frame to the transmit queue of the SocketCAN network interface, followed by the driver moving it to the transmit buffer of the CAN controller, which finally puts the frame on the bus. What you want is a direct write which bypasses all those buffers, but that's not possible with SocketCAN, even if you set the transmit queue length to 0.
However, there is another way to get confirmation. If you enable the CAN_RAW_RECV_OWN_MSGS socket option (see section 4.1.4 and 4.1.7 in the SocketCAN documentation), you will receive frames that were successfully sent. You'll need to use recvmsg() so you get the message flags. msg_flags will have the MSG_CONFIRM bit set for a frames that was successfully sent by the same socket on which it is received. You won't be informed of failures, but you can detect them by using a timeout for the confirmation.
It's not an ideal solution because it mixes the read and write logic in your application. One way to avoid this would be to use two sockets. One for writing and reading MSG_CONFIRM frames, the other for reading all other frames. You could then create a (blocking) write function that does a write() followed by multiple calls to recvmsg() with an appropriate timeout.
Finally, it is useful to enable error frames (through the CAN_RAW_ERR_FILTER socket option). If you send a frame on a socket with a disconnected cable, this will typically result in a bus off state, which will be reported in an error frame.

How Can I Manipulate Some/IP Message Content On Run Time?

I was trying to manipulate SOME/IP messages by falsifying their content(Payload) sent between 2 ECUs at run time.
After setting up the Hardware VN6510A MAC Bypassing and integrating it in the data traffic path between those 2 ECUs to monitor and control all Ethernet data streams.
ECU A ---> eth1 interface --VN6510A-- eth2 interface ---> ECU B
I successfully catch our target SOME/IP messages and I also succefully manipulate their paylod.
But at the end we got 2 SOME/IP messages: the real coming message and the falsified message forwarded at the same time.
How could we bound those 2 SOME/IP messages, the real message and the falsified message together, so that we could have just one falsified SOME/IP message, knowing that I am using the same SOME/IP message handle.
I used the callback function void OnEthPacket(LONG channel, LONG dir, LONG packet) to register a received Ethernet packet.
Probably by setting your VN.... to "Direct" and not "MAC Bypassing"
Well we could not manipulate Messages at run time using the vector box VN6510A Solution because simply their box doesn't support this feature.

Single channel gateway only detect first message

My gateway uses the Raspi and RFM95 configuration and operates at 915 MHz. I am using the single channel packet forwarder code by tfelkamp (https://github.com/tftelkamp/single_chan_pkt_fwd).
My gateway only the detects the first message it received and ignores the all messages afterwards. It is still connected to the TTN server but does not receive any more messages.
Can anyone explain what might be the cause of this? Might it because the RFM95 sleeping or the code no longer forwarding the message from the transceiver.
Thanks
I experienced a similar issue. Please note your sender is using different channels, but starts with channel(0). This is the first successful message you receive. Your single channel receiver is just able to receive channel(0). There is a work around for this issue for your sender explained here
This sounds like your transmitter sends the messages using frequency-hopping, while your receiver does not handle it correctly (or the other way around).
Definition of frequency-hopping found in chapter 4.1.1.8 of Semtech's SX1272 datasheet:
Frequency hopping spread spectrum (FHSS) is typically employed when
the duration of a single packet could exceed regulatory requirements
relating to the maximum permissible channel dwell time. This is most
notably the case in US operation where the 902 to 928 MHz ISM band
which makes provision for frequency hopping operation. [...]
If you're using the LMIC-Arduino library for your node then yes, by default it is transmitting in a range and the single_chan_pkt_fwd gateway is only receiving on the frequency you specify in the global_conf.json or the .cpp source (depending on your chosen library).
With the assumption that you're using the arduino-lmic library, make the changes/additions mentioned in the this TTN forum post linked by Rainer which is the same I ran into.
Also... you'll find this further down the thread: in src > lmic > lmic.c edit the following:
void LMIC_disableChannel (u1_t channel) {
if( channel < 72+MAX_XCHANNELS )
//LMIC.channelMap[channel>>4] &= ~(1<<(channel&0xF)); // comment this one
LMIC.channelMap[channel/16] &= ~(1<<(channel&0xF)); // add this one
}
Then pick a frequency on channel 0 and set that for both node and packet forwarder. Here's a table snip from this page. I went with 902300000 and it's working fine.
"freq": 902300000,
"spread_factor": 7,

read() on a NON-BLOCKING tun/tap file descriptor gets EAGAIN error

I want to read IP packets from a non-blocking tun/tap file descriptor tunfd
I set the tunfd as non-blocking and register a READ_EV event for it in libevent.
when the event is triggered, I read the first 20 bytes first to get the IP header, and then
read the rest.
nr_bytes = read(tunfd, buf, 20);
...
ip_len = .... // here I get the IP length
....
nr_bytes = read(tunfd, buf+20, ip_len-20);
but for the read(tunfd, buf+20, ip_len-20)
I got EAGAIN error, actually there should be a full packet,
so there should be some bytes,
why I get such an error?
tunfd is not compatible with non-blocking mode or libevent?
thanks!
Reads and writes with TUN/TAP, much like reads and writes on datagram sockets, must be for complete packets. If you read into a buffer that is too small to fit a full packet, the buffer will be filled up and the rest of the packet will be discarded. For writes, if you write a partial packet, the driver will think it's a full packet and deliver the truncated packet through the tunnel device.
Therefore, when you read a TUN/TAP device, you must supply a buffer that is at least as large as the configured MTU on the tun or tap interface.

Examine data at in callout driver for FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 layer in WFP

I am writing the callout driver for Hyper-V 2012 where I need to filter the packets sent from virtual machines.
I added filter at FWPM_LAYER_EGRESS_VSWITCH_TRANSPORT_V4 layer in WFP. Callout function receive packet buffer which I am typecasting it to NET_BUFFER_LIST. I am doing following to get the data pointer
pNetBuffer = NET_BUFFER_LIST_FIRST_NB((NET_BUFFER_LIST*)pClassifyData->pPacket);
pContiguousData = NdisGetDataBuffer(pNetBuffer, NET_BUFFER_DATA_LENGTH(pNetBuffer), 0, 1, 0);
I have simple client-server application to test the packet data. Client is on VM and server is another machine. As I observed, data sent from client to server is truncated and some garbage value is added at the end. There is no issue for sending message from server to client. If I dont add this layer filter client-server works without any issue.
Callback function receives the metadata which incldues ipHeaderSize and transportHeaderSize. Both these values are zero. Are these correct values or should those be non-zero??
Can somebody help me to extract the data from packet in callout function and forward it safely to further layers?
Thank You.
These are the TCP packets. I looked into size and offset information. It seems the problem is consistent across packets.
I checked below values in (NET_BUFFER_LIST*)pClassifyData->pPacket.
NET_BUFFER_LIST->NetBUfferListHeader->NetBUfferListData->FirstNetBuffer->NetBuffe rHeader->NetBufferData->CurrentMdl->MappedSystemVa
First 24 bytes are only sent correctly and remaining are garbage.
For example total size of the packet is 0x36 + 0x18 = 0x4E I don't know what is there in first 0x36 bytes which is constant for all the packets. Is it a TCP/IP header? Second part 0x18 is the actual data which i sent.
I even tried with API NdisQueryMdl() to retrieve from MDL list.
So on the receiver side I get only 24 bytes correct and remaining is the garbage. How to read the full buffer from NET_BUFFER_LIST?