recvfrom for storing in 2D Char array - udp

trying to collect 1261 UDP packet in 2D Char array using recvfrom function
define RxBuffSize 1514
define TotalPacket 1261
char RxBuff[RxBuffSize] = {0};
and the code i am trying to use is:
for (Count =0; Count <= TotalPacket; Count++)
{
recvfrom(sock, RxBuff[Count],RxBuffSize,0,(struct sockaddr *)&Sender_addr, &Sender_addrlen);
}
or no idea how to start just wanted to store all 1261 packets into RxBuff so that I can access packet data by its packet number for getting the data from packet by its packet number.
printf("%x ",Payload[packetno][data]);

You'll need enough space to store all of the packets contiguously. You can either statically allocate a 2D array
char RxBuff [RxBuffSize][1261];
or use calloc
char *RxBuff = calloc(RxBuffSize, 1261);
Then loop over recvfrom 1261 times just like in your question:
for (Count = 0; Count <= TotalPacket; Count++)
{
recvfrom(sock, RxBuff[Count],RxBuffSize,0,(struct sockaddr *)&Sender_addr, &Sender_addrlen);
}

Related

STM32 reading variables out of Received Buffer with variable size

I am not really familiar with programming in STM32. I am using the micro controller STM32F303RE.
I am receiving data via a UART connection with DMA.
Code:
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RxBuf, RxBuf_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
I am writing the value into a Receiving Buffer and then transfer it into a main buffer. This function and declaration is down before the int main(void).
#define RxBuf_SIZE 100
#define MainBuf_Size 100
uint8_t RxBuf[RxBuf_SIZE];
uint8_t MainBuf[MainBuf_Size];
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart,uint16_t Size){
if( huart -> Instance == USART2){
memcpy (MainBuf, RxBuf, Size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, RxBuf, RxBuf_SIZE);
}
for (int i = 0; i<Size; i++){
if((MainBuf[i] == 'G') && (MainBuf[i+1] == 'O')){
RecieveData();
HAL_UART_DMAStop(&huart2);
}
}
}
I receive know the data into a buffer and it stops as soon as "GO" is transmitted. Until this point it is working. The function ReceiveData() should then transform this buffer to the variables. But it isn't working for me.
Now I want to transform this received data with "breakpoints" into variables.
So I want to send: "S2000S1000S1S10S2GO".
I always have 5 variables. (in this case: 2000, 1000, 1, 10, 2) I want to read the data out of the string and transform it into an uint16_t to procude. The size/ length of the variables could be changed. That's why I tried to use like some breakpoint.

Unpack hex-encoded NSData

on peripheral:didReceiveWriteRequest a CBATTRequest returns hex-encoded NSData via request.value.
This is what I have tried
// Define struct
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt16 userPayload; // how to store 15 octets?
} Packet;
// Unpack
Packet *packet = (Packet *)request.value.bytes;
if (packet) {
UInt8 pktNo = packet->pktNo;
UInt8 cmd = packet->ctrlCmd;
UInt8 tx = packet->txPowerRequest;
UInt16 uuid = packet->uuid;
UInt16 payload = packet->userPayload;
NSLog(#"pktNo: %hhu, cmd: %hhu, tx: %hhu, uuid: %hu, payload: %hu", pktNo, cmd, tx, uuid, payload);
}
Console
pktNo: 121, cmd: 202, tx: 130, uuid: 48321, payload: 21421
First, these numbers look inaccurate, and I'm uncertain about what format this is even in, since the following analogous values I got from debugging tool don't seem to match.
Default: raw strings?
packet Packet * 0x281af0cc0 0x0000000281af0cc0
pktNo UInt8 'y'
ctrlCmd UInt8 '\xca'
txPowerRequest UInt8 '\x82'
uuid UInt16 48321
userPayload UInt16 21421
The hex string representation of your NSData is apparently:
<79ca82c1 bcad530e 016a1435 127993ee 01ef7579>
That translates to:
The 0x79 is the PKT, 121 in decimal
The 0xca is the CMD, 202 in decimal
The 0x82 is the TXP, 130 in decimal
The 0xbcc1 is the UUID, 48321 in decimal
The PAYLOAD is ad 53 0e 01 6a 14 35 12 79 93 ee 01 ef 75 79
So, you can use:
typedef struct __attribute__((packed)) {
UInt8 pktNo;
UInt8 ctrlCmd;
UInt8 txPowerRequest;
UInt16 uuid;
UInt8 userPayload[15];
} Packet;
Which you can populate with:
Packet packet = {};
assert(data.length == sizeof(Packet));
memcpy(&packet, data.bytes, sizeof(Packet));
Note, I didn’t just set the packet to a pointer to the bytes of the NSData, because if the NSData is deallocated, you don’t want to use a pointer to that deallocated memory. Instead, copy the bytes to your packet struct (perhaps checking to make sure the two match in size).
In the interest of full disclosure, the above makes a somewhat cavalier assumption that endianness of the payload matches that of device running your app. You theoretically might want to make the UUID a UInt8 uuid[2], instead, and then if you need the UUID value, recalculate it from those two octets.

How do I send a payload to an XBee

I have implemented the following code on an embedded platform that attempts to communicate with an XBee. The embedded platform that executes the code below is not an xbee:
int main()
{
char payload[12] = {0x61,0x88,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0xEC,0x00,0x00}
payload[2] = 0x10;
payload[9] = 0x01;
char data = 'H'; // Send simple ASCII character to XBee
payload[11]= data;
while (1)
sendByteofData(payload,12);
}
void sendByteOfData(char * payload, int len)
{
int x;
for (x=0;x<4;x++)
// This function sends IEEE 802.15.4 frames, and I know it
// works because they are detected in the [sniffer][3].
send_IEEE_802_15_4_frame(payload,len);
}
payload[2] = payload[2] % 256 + 1;
payload[9] = payload[9] % 256 + 1;
if (payload[9] % 256 == 0 )
payload[9] = 0x01;
else
payload[9] %= 256;
}
To my surprise the above code actually sent one byte from the embedded platform to the XBee successfully. however, the infinite loop at the end of main() should have produced a stream of bytes.
My suspicion is I need to set payload[2] and payload[9] correctly, and there is probably a flaw in the incremental modulo 256 algorithm shown above.
How do I get a continuous stream of bytes?
A few thoughts...
Make your payload an array of unsigned char or, even better, uint8_t.
To update payload[2] and payload[9], simplify your code:
++payload[2];
++payload[9];
if (payload[9] == 0) payload[9] = 1;
Add a delay between sends. You might even need to wait for a response before sending the next character.
Since it's a payload of unsigned 8-bit values, they'll automatically roll from 255 to 0. I assume your special case code for payload[9] is trying to roll from 255 to 1 (instead of 0).
Make sure your payload doesn't need to include a checksum of some sort. Updating those two bytes would have an affect on a checksum byte.

NSSwapInt from byte array

I'm trying to implement a function that will read from a byte array (which is a char* in my code) a 32bit int stored with different endianness. I was suggested to use NSSwapInt, but I'm clueless on how to go about it. Could anyone show me a snippet?
Thanks in advance!
Heres a short example:
unsigned char bytes[] = { 0x00, 0x00, 0x01, 0x02 };
int intData = *((int *)bytes);
int reverseData = NSSwapInt(intData);
NSLog(#"integer:%d", intData);
NSLog(#"bytes:%08x", intData);
NSLog(#"reverse integer: %d", reverseData);
NSLog(#"reverse bytes: %08x", reverseData);
The output will be:
integer:33619968
bytes:02010000
reverse integer: 258
reverse bytes: 00000102
As mentioned in the docs,
Swaps the bytes of iv and returns the resulting value. Bytes are swapped from each low-order position to the corresponding high-order position and vice versa. For example, if the bytes of inv are numbered from 1 to 4, this function swaps bytes 1 and 4, and bytes 2 and 3.
There's also a NSSwapShort and NSSwapLongLong.
There is a potential of a data misalignment exception if you solve this problem by using integer pointers - e.g. some architectures require 32-bit values to be at addresses which are multiples of 2 or 4 bytes. The ARM architecture used by the iPhone et al. may throw an exception in this case, but I've no iOS device handy to test whether it does.
A safe way to do this which will never throw any misalignment exceptions is to assemble the integer directly:
int32_t bytes2int(unsigned char *b)
{
int32_t i;
i = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24; // little-endian, or
i = b[3] | b[2] << 8 | b[1] << 16 | b[0] << 24; // big-endian (pick one)
return i;
}
You can pass this any byte pointer and it will assemble 4 bytes to make a 32-bit int. You can extend the idea to 64-bit integers if required.

Reading Binary File

so I am trying to read a filesystem disk, which has been provided.
So, what I want to do is read the 1044 byte from the filesystem. What I am currently doing is the following:
if (fp = fopen("filesysFile-full", "r")) {
fseek(fp, 1044, SEEK_SET); //Goes to 1024th byte
int check[sizeof(char)*4]; //creates a buffer array 4 bytes long
fread(check, 1, 4, fp); //reads 4 bytes from the file
printf("%d",check); //prints
int close = fclose(fp);
if (close == 0) {
printf("Closed");
}
}
The value that check should be printing is 1. However I am getting negative values which keep changing everytime I run the file. I don't understand what I am doing wrong. Am I taking the right approach to reading bytes of the disk, and printing them.
What I basically want to do is read bytes of the disk, and read the values at certain bytes. Those bytes are fields which will help me understand the structure/format of the disk.
Any help would be appreciated.
Thank you.
This line:
int check[sizeof(char)*4];
allocates an array of 4 ints.
The type of check is therefore int*, so this line:
printf("%d",check);
prints the address of the array.
What you should do it allocate it as an int:
int check;
and then fread into it:
fread(&check, 1, sizeof(int), fp);
(This code, incidentally, assumes that int is 4 bytes.)
int check[sizeof(char)*4]; //creates a buffer array 4 bytes long
This is incorrect. You are creating an array of four integers, which are typically 32 bits each, and then when you printf("%d",check) you are printing the address of that array, which will probably change every time you run the program. I think what you want is this:
if (fp = fopen("filesysFile-full", "r")) {
fseek(fp, 1044, SEEK_SET); //Goes to 1024th byte
int check; //creates a buffer array the size of one integer
fread(&check, 1, sizeof(int), fp); //reads an integer (presumably 1) from the file
printf("%d",check); //prints
int close = fclose(fp);
if (close == 0) {
printf("Closed");
}
}
Note that instead of declaring an array of integers, you are declaring just one. Also note the change from fread(check, ...) to fread(&check, ...). The first parameter to fread is the address of the buffer (in this case, a single integer) into which you want to read the data.
Keep in mind that while integers are probably 32 bits long, this isn't guaranteed. Also, in most operating systems, integers are stored with the least significant byte first on the disk, so you will only read 1 if the data on the disk looks like this at byte 1044:
0x01 0x00 0x00 0x00
If it is the other way around, 0x00 00 00 01, that will be read as 16777216 (0x01000000).
If you want to read more than one integer, you can use an array as follows:
if (fp = fopen("filesysFile-full", "r")) {
fseek(fp, 1044, SEEK_SET); //Goes to 1024th byte
int check[10]; //creates a buffer of ten integers
fread(check, 10, sizeof(int), fp); //reads 10 integers into the array
for (int i = 0; i < 10; i++)
printf("%d ", check[i]); //prints
int close = fclose(fp);
if (close == 0) {
printf("Closed");
}
}
In this case, check (without brackets) is a pointer to the array, which is why I've changed the fread back to fread(check, ...).
Hope this helps!

Categories