C array assign & access - c

I'm writing C code in a PIC16F1824, and are using UART.
I had this for receiving:
for(int i = 0; i < 9; i++){
while(!PIR1bits.RCIF);
RX_arr[i] = RCREG;
while(PIR1bits.RCIF);
}
RX_arr is an array declared as int RX_arr[9];
RCREG is the UART receving register and is supposed to have
0xFF 86 00 00 00 00 00 00 47;
Question1:
When i = 1, RX_arr[0]'s value(0xFF in this case) also changes when RX_arr[1] = RCREG is executed(Both postion 0 and 1 have 0x86).
Later I found using this segment of code instead of the for loop above will successfully assign one byte into each position:
if(!RCSTAbits.FERR && !RCSTAbits.OERR){
RX_arr[0] = RCREG;
}
However, the byte saved is wrong, only the 0xFF is always correct, other bytes are some other values. I found the OERR bit is set, which indicates an overrun error(2 byte FIFO buffer is full before accessed). How can I receive all the bytes in RCREG?
Question2:
After I get the response in question1, I read the useful information in it, which is in byte 2 and 3, and I made a variable called data. In my case the data is a sampled temperature, and I want to collect 20 samples,and save them in an array called ppm_array. sum_ppm is supposed to be the sum of all 20 samples, and will add the new sampled temperature to it every time a new sample is collected. When I run sum_ppm += ppm_array[i](sum_ppm = 0, ppm_array[0] = 1616, and the rest of the positions are 0),I got sum_ppm = 4508160. Why isn't it 1616??? Am I adding the address of them?
data = RX_arr[2] * 256 + RX_arr[3];
ppm_array[i] = data;
sum_ppm += ppm_array[i]
Many thanks.

Related

ESP32 - Extract Manufacturer Specific Data from advertisement

TL;DR: One ESP32 broadcasts via BLE (already working), another ESP32 listens. I am unable to parse the received advertisements correctly, i.e. can't extract the manufacturer specific data!
Goal: One ESP32 (call A) broadcasts an advertisement containing manufacturer specific data (MSD), which is received by another ESP32 (call B) who prints that data to the console.
I am using the new RISC-V based ESP32C3 which supports Bluetooth 5.0, though everything I do is based on Bluetooth 4.2.
Where I am:
A can broadcast a valid advertisement (checked with an Ubertooth/Wireshark)
B receives something from A, though the packet only very loosely corresponds to the (correct) packet received by the Ubertooth.
Code:
Structs used to set up A:
// Struct defining advertising parameters
static esp_ble_adv_params_t ble_adv_params = {
.adv_int_min = 0x0800,
.adv_int_max = 0x0900,
.adv_type = ADV_TYPE_NONCONN_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, // NO IDEA ABOUT THAT ONE, ESPECIALLY GIVEN THAT WE SEND NONCONNECTABLE AND NONSCANNABLE ADVERTISEMENTS!
};
Struct used to define the payload of the advertisement:
esp_ble_adv_data_t ble_adv_data =
{
.set_scan_rsp = false,
.include_name = true, // "Name" refers to the name passed as an argument within "esp_ble_gap_set_device_name()"
.include_txpower = false,
.min_interval = 0xffff, // Not sure what those are for, as the chosen advertisement packets are non-connectable...
.max_interval = 0xFFFF,
.appearance = 64, // 64 is appearance ID of phone. Only to maybe be able to find it on my Galaxy phone
.manufacturer_len = ble_adv_payload_len,
.p_manufacturer_data = (uint8_t *) ble_adv_payload, // Currently just some human-readable string used for debugging
.service_data_len = 0,
.p_service_data = NULL,
.service_uuid_len = 0,
.p_service_uuid = NULL,
.flag = 0
};
As the Ubertooth receives correct packets sent by A, I reckon A has been set up correctly.
Struct used to define scanning behavior of B:
// Struct defining scanning parameters
static esp_ble_scan_params_t ble_scan_params = {
.scan_type = BLE_SCAN_TYPE_PASSIVE, // Don't send scan requests upon receiving an advertisement
.own_addr_type = BLE_ADDR_TYPE_PUBLIC, // Use (static) public address, makes debugging easier
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ONLY_WLST, // Consider all advertisements
.scan_interval = 0x50, // Time between each scan window begin
.scan_window = 0x30, // Length of scan window
.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE // Filters out duplicate advertisements, e.g. if an advertisement received k times, it is only reported once
};
The majority of the remaining code is just boilerplate, the only really relevant part is the callback function of B, which gets called whenever a GAP-Event occurs (GAP-Events can be found in esp_gap_ble_api.h, beginning on line 138).
B's callback function:
void esp_ble_callback_fun(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
// Do a case split on the different events. For now, only "ESP_GAP_BLE_SCAN_RESULT_EVT" is of interest
switch (event) {
case ESP_GAP_BLE_SCAN_RESULT_EVT:
if ((param->scan_rst).search_evt != ESP_GAP_SEARCH_INQ_RES_EVT) {
printf(
"B: Callback function received a non-\"ESP_GAP_SEARCH_INQ_RES_EVT\" event!\n");
return;
}
// Copy the parameter UNION
esp_ble_gap_cb_param_t scan_result = *param;
// Create a POINTER to the "bda" entry, which is accessed by interpreting the scan_result UNION as a scan_rst STRUCT
// Note that "esp_bd_addr_t" is a typedef for a uint8_t array!
esp_bd_addr_t *ble_adv_addr = &scan_result.scan_rst.bda;
printf("\n-------------------------\nMessage: \n");
uint8_t adv_data_len = scan_result.scan_rst.adv_data_len;
uint8_t *adv_data = scan_result.scan_rst.ble_adv;
printf("Message length: %i\n", adv_data_len);
printf("Message body:\n"); // NOT SO SURE ABOUT THIS!
for(int i = 0; i < adv_data_len; ++i)
{
printf("%X", adv_data[i]);
}
printf("\n-------------------------\n");
break; // #suppress("No break at end of case")
default:
// NOT SUPPORTED! JUST IGNORE THEM!
break;
}
}
Sample output:
Serial output by B:
Message:
Message length: 22
Message body:
31940069414C4943454FF486579512FFFFFFFF
Packet as received in Wireshark:
Frame 78135: 61 bytes on wire (488 bits), 61 bytes captured (488 bits) on interface /tmp/pipe, id 0
PPI version 0, 24 bytes
Version: 0
Flags: 0x00
.... ...0 = Alignment: Not aligned
0000 000. = Reserved: 0x00
Header length: 24
DLT: 251
Reserved: 36750c0000620900e05b56b811051000
Bluetooth
Bluetooth Low Energy Link Layer
Access Address: 0x8e89bed6
Packet Header: 0x1c22 (PDU Type: ADV_NONCONN_IND, ChSel: #2, TxAdd: Public)
.... 0010 = PDU Type: ADV_NONCONN_IND (0x2)
...0 .... = RFU: 0
..1. .... = Channel Selection Algorithm: #2
.0.. .... = Tx Address: Public
0... .... = Reserved: False
Length: 28
Advertising Address: Espressi_43:3e:d6 (7c:df:a1:43:3e:d6)
Advertising Data
Appearance: Generic Phone
Device Name: ALICE
Manufacturer Specific
Slave Connection Interval Range: 81918.8 - 81918.8 msec
Connection Interval Min: 65535 (81918.8 msec)
Connection Interval Max: 65535 (81918.8 msec)
CRC: 0x905934
0000 00 00 18 00 fb 00 00 00 36 75 0c 00 00 62 09 00 ........6u...b..
0010 e0 5b 56 b8 11 05 10 00 d6 be 89 8e 22 1c d6 3e .[V........."..>
0020 43 a1 df 7c 03 19 40 00 06 09 41 4c 49 43 45 04 C..|..#...ALICE.
0030 ff 48 65 79 05 12 ff ff ff ff 09 9a 2c .Hey........,
For a packet without MSD, I computed the longest common subsequence between the binary representation of a packet received by B (i.e. content of adv_data) and the packet received by the Ubertooth. They only had 46 bits in common, a weird number for sure!
My questions:
Am I right in assuming that adv_data, i.e. scan_result.scan_rst.ble_adv holds the raw BLE packet? The definition of ble_adv (esp_gap_ble_api.h, line 936) is incredibly confusing IMO, as it is called "Received EIR" despite EIRs only being introduced in Bluetooth 5.0...
How can I extract the MSD from a received BLE advertisement?
EIR was introduced a long time ago and was present in Bluetooth 4.0.
You should use %02X when printing hex strings since that will include leading zeros.
ble_adv contains only the EIR content, not the whole packet.
EIR uses length, type, value encoding. Your manufacturing data is encoded like this:
4 (length)
0xff (manufacturer data)
Hey (content)
Note that the two bytes of the manufacturer data content should be a Bluetooth SIG registered company id.

Aligning 8-bit Integer Array for Message Passing that Requires Long Alignment

I am currently using OpenMP on a processor with a NUMA architecture and using the User Dynamic Network (UDN) that the board provides to route packets from each thread to the master thread. The overall idea of the program is simple: parallelize the subtraction of two 8-bit integer arrays element-wise and store the results into an array (C[i] = A[i] - B[i]).
Due to the NUMA architecture of the processor I'm using, allocating the arrays and then putting a simple OpenMP for loop pragma results in very poor performance. One of the ways I have achieved better performance is to instead allocate arrays of equal size as private arrays to each thread, and have each thread just work on its private data that was allocated by that thread. The idea is to have each thread work on local to get around the overhead of fetching data from other cores.
While this results in a performance increase, I am trying to accumulate the data from each thread into one final thread that can be used by the main program outside of the parallel region. However, when using the UDN to pass messages around, one of the requirements according the data sheet is that the buffer being sent and the buffer used to receive the data must be long-aligned.
Here is the code I have:
int size = 6000;
int threads = 20;
if(tmc_udn_init(NULL) != 0)
{
printf("tmc_udn_init failure\n");
}
alloc_attr_t attrCfinal = ALLOC_INIT;
mspace mspCfinal = create_mspace_with_attr(0,0,&attrCfinal);
uint8_t *C_final = mspace_malloc(mspCfinal, sizeof(uint8_t)*(size*size));
#pragma omp parallel num_threads(threads)
{
int j;
int id = omp_get_thread_num();
if(tmc_cpus_set_my_cpu(id) < 0)
{
printf("tmc_cpus_set_my_cpu failure, thread = %d\n", id);
}
if(tmc_udn_activate() < 0)
{
printf("tmc_udn_activate() failure, threads = %d\n", id);
}
#pragma omp barrier
alloc_attr_t attrA = ALLOC_INIT;
alloc_attr_t attrB = ALLOC_INIT;
alloc_attr_t attrC = ALLOC_INIT;
alloc_set_home(&attrA, ALLOC_HOME_HERE);
alloc_set_home(&attrB, ALLOC_HOME_HERE);
alloc_set_home(&attrC, ALLOC_HOME_HERE);
mspace mspA = create_mspace_with_attr(0,0,&attrA);
mspace mspB = create_mspace_with_attr(0,0,&attrB);
mspace mspC = create_mspace_with_attr(0,0,&attrC);
uint8_t *A_priv = mspace_malloc(mspA, sizeof(uint8_t)*((size*size)/threads));
uint8_t *B_priv = mspace_malloc(mspB, sizeof(uint8_t)*((size*size)/threads));
uint8_t *C_priv = mspace_malloc(mspC, sizeof(uint8_t)*((size*size)/threads));
for(j=0; j<((size*size)/threads); j++)
{
A_priv[j] = 100;
B_priv[j] = omp_get_thread_num();
C_priv[j] = 0;
}
for(j=0; j<((size*size)/threads); j++)
{
C_priv[j] = A_priv[j] - B_priv[j];
}
if(omp_get_thread_num() == 0)
{
int k = 0;
int h = 0;
for(k=1; k<threads; k++)
{
int thread_num = tmc_udn1_receive();
for(h=0; h<((size*size)/threads)/100; h++)
{
tmc_udn0_receive_buffer(&C_final[((thread_num-1)*((size*size)/threads))+(h*100)], 100);
}
}
}
else
{
#pragma omp critical
{
DynamicHeader dest = tmc_udn_header_from_cpu(0);
tmc_udn_send_1(dest, UDN1_DEMUX_TAG, omp_get_thread_num());
int p = 0;
for(p=0; p<((size*size)/threads)/100; p++)
{
tmc_udn_send_buffer(dest, UDN0_DEMUX_TAG, &C_priv[p*100], 100);
}
}
}
}
Some notes about my code that might make it easier to look at:
The send/receive buffer only allows up to 126 words at a time, so I am doing 100 for now just to make everything easily divisible when sending chunks of each array at a time.
I know in my message passing/receiving that I am not including thread 0, this is something I am going to fix later after I figure this issue out, so I am excluding its results from the accumulates array C_final for now
The idea is to break the initial problem size of (6000*6000) into (6000*6000)/20 sized chunks (if I am using 20 threads, for example)
Then I want to send each thread's C array to the master thread and accumulate it into C_final
I send the thread number before I send the data so I can place the received data in the right position to make the final array in order of each thread's data (C_final = [Thread 1's data, Thread 2's data, ...])
So finally, my issue is that even though I can see that the data I am sending and receiving is correct by verifying it before I send it and verifying it when I receive it, because the the array I am sending is of uint8_t and not long, when I check it after all the results are received, I end up getting parts of the array with garbage data while other parts have the correct result. I tried making both C_final and C_priv longs instead of 8-bit integers and verified that the results are correct after receiving everything, but not when I have them as 8-bit integer arrays.
Unfortunately, for this application I need to have the arrays doing the computations as 8-bit integers. Also, I am going to be including the time it takes to accumulate all of the results from the threads into the final C_final array so I am trying to make sure the accumulation doesn't take too much time (so I don't want do something like copying the results of C_final into a long array and then send that new array).
Is there any way to alleviate this problem without just changing my C_priv arrays and C_final array into longs instead of 8-bit integers? Also, I looked into the source code of the message passing, and the functions look this:
// Receive a packet of words from UDN demux 1.
//
// #param buf A long-aligned buffer
// #param words The size of the buffer (in longs)
//
static __inline void
tmc_udn1_receive_buffer(void* buf, unsigned long words)
{
unsigned long i;
unsigned long* ptr = (unsigned long*)buf;
for (i = 0; i < words; i++)
ptr[i] = udn1_receive();
}
...
// Send a packet of words on the UDN
//
// #param dest The destination (with no length)
// #param tag The tag (e.g. UDN0_DEMUX_TAG)
// #param buf A long-aligned buffer
// #param words The size of the buffer (in longs). This function can
// send a maximum of 126 longs
//
static __inline void
tmc_udn_send_buffer(DynamicHeader dest, unsigned long tag,
const void* buf, unsigned long words)
{
unsigned long i;
const unsigned long* ptr = (const unsigned long*)buf;
__tmc_udn_send_header_with_size_and_tag(dest, words, tag);
for (i = 0; i < words; i++)
udn_send(ptr[i]);
}
Edit:
For some additional clarity, this is the proper output I am expecting if I were to read the the indexes of C_final after accumulation. These are read at the first index of where each thread placed it's data (I was using 30 threads here but the idea is the same. Also the last one is -1 since I am omitting the master's thread results for now and just placing all the other thread's data in C_final starting at 0):
C_final[0] = 99
C_final[1875000] = 98
C_final[3750000] = 97
C_final[5625000] = 96
C_final[7500000] = 95
C_final[9375000] = 94
C_final[11250000] = 93
C_final[13125000] = 92
C_final[15000000] = 91
C_final[16875000] = 90
C_final[18750000] = 89
C_final[20625000] = 88
C_final[22500000] = 87
C_final[24375000] = 86
C_final[26250000] = 85
C_final[28125000] = 84
C_final[30000000] = 83
C_final[31875000] = 82
C_final[33750000] = 81
C_final[35625000] = 80
C_final[37500000] = 79
C_final[39375000] = 78
C_final[41250000] = 77
C_final[43125000] = 76
C_final[45000000] = 75
C_final[46875000] = 74
C_final[48750000] = 73
C_final[50625000] = 72
C_final[52500000] = 71
C_final[54375000] = -1
However, this is the result I am getting:
C_final[0] = 99
C_final[1875000] = -16
C_final[3750000] = 97
C_final[5625000] = 96
C_final[7500000] = 95
C_final[9375000] = -16
C_final[11250000] = -16
C_final[13125000] = 92
C_final[15000000] = -16
C_final[16875000] = 90
C_final[18750000] = -16
C_final[20625000] = 88
C_final[22500000] = -16
C_final[24375000] = -16
C_final[26250000] = 85
C_final[28125000] = -16
C_final[30000000] = -16
C_final[31875000] = 82
C_final[33750000] = -16
C_final[35625000] = -16
C_final[37500000] = -16
C_final[39375000] = 78
C_final[41250000] = -16
C_final[43125000] = 76
C_final[45000000] = -16
C_final[46875000] = -16
C_final[48750000] = 73
C_final[50625000] = 72
C_final[52500000] = -16
C_final[54375000] = -16
As for which results are accurate and which results are not, that changes every time I run it. It is not always the same indexes that have the correct results. The incorrect numbers that can be seen also are not consistent.

understanding a bitwise calculation

I'm reading some code that performs bitwise operations on an int and stores them in an array. I've worked out the binary representation of each step and included this beside the code.
On another computer, the array buff is received as a message and displayed in hex as [42,56,da,1,0,0]
Why question is, how could you figure out what the original number was from the hex number. I get that 42 and 56 are the ASCII equivalent of 'B' and 'V'. But how do you get the number 423 from da '1' '0' '0'?
Thanks
DA 01 00 00 is the little endian representation of 0x000001DA or just 0x1DA. This, in turn, is 256 + 13 * 16 + 10 = 474. Maybe you had this number and changed the program later and forgot to recompile?
Seen it from the other side, 423 is 0x1a7…
as glgl says it should be a7, you can see where that comes from
buff[2] = reading&0xff; // 10100111 = 0xa7
buff[3] = (reading>>8)&0xff; //00000001 = 1
buff[4] = (reading>>16)&0xff; //00000000 = 0
buff[5] = (reading>>24)&0xff; ////00000000 = 0

unable to loop through data in c pos

I am new to POS programming using C language. I want to loop through the returned hex data and also print it to the screen after sending the APDU command and getting a response. Here is my main problem requirements.
First I elect the EMV Application using PSE method 1PAY.SYS.DD01
I read the record of the PSE which returns me the AID
I select the AID currently I'm using cards with VISA AIDs (A0 00 00 00 03 10 10 and A0 00 00 00 03 20 10)
3.I read the record of the AID interestingly for the first AID, it returns the magnetic stripe info without using GPO command first while the second one for some cards it requires them so I next get the GPO to process it
I then read the records from the card. The problem is I am outputting this byte info so its easy for me to track what's going on but the POS terminal I am using can only output a given number of characters on the screen. First I have space for 18 bytes, then I can have up to maximum of 35 bytes to display after clearing the screen everytime the user presses the arrow down button.
To do this, I used some variables below
int variab = 0,
offset = 18,
remainingBytes = apduResp.LenOut - 18,
limit = apduResp.LenOut,
AIDChooser = 0; // To track output data scroll
// option
if (apduResp.LenOut == 0)
{
offset = 0;
remainingBytes = 0;
limit = 0;
}
else if (apduResp.LenOut > 0)
{
int variab = 0,
offset = 18,
remainingBytes = apduResp.LenOut - 18,
limit = apduResp.LenOut,
AIDChooser = 0;
}
Then I put the code below in a loop that runs while the arrow down key is pressed I read all the data and this is what it is supposed to do
i) Read all response bytes and the length
ii) check if the remaining bytes are more than 35, add 35 to the loop offset and then print the next 35 up to the limit which is (offset + 35). and if the remaining bytes are less than 35, print them out and stop.
The problem is when the intial data length is 0, pressing the scroll button doesn't show subsequent data but if the initial response data is greater than zero, the function works as required, can anyone figure out what I'm doing wrong?
if (remainingBytes > 35)
{
limit = offset + 35;
for (i_sn = offset; i_sn < limit; i_sn++)
{
sn_display += sprintf(sn_display, "%02X ", `apduResp.DataOut[i_sn]);
TP_LcdPrintf(" %s", te);
}
offset = limit; // Change
// offset
remainingBytes = apduResp.LenOut - limit; // Reduce
// remaining bytes
}
else if (remainingBytes == 0)
{
TP_LcdPrintf(" %s", " No more data\n Press Cancel to\n return");
}
else if (remainingBytes > 0 && remainingBytes < 35)
{
for (i_sn = offset; i_sn < apduResp.LenOut; i_sn++)
{
sn_display += sprintf(sn_display, "%02X ", apduResp.DataOut[i_sn]);
TP_LcdPrintf(" %s", te);
}
offset = limit;
remainingBytes = apduResp.LenOut - limit;
}
////indent: Standard input:32: Error:Stmt nesting error.
}
… in the first block of code you have under #5, you have some variables you are initializing in the else part of an if statement that are declared, initialized, but then never used. So their values will not be "seen" outside of that if statement block because their scope is all inside else { ... } – lurker

extract coap query

I need your help in extracting the query value in a coap message.The coap message looks like
coap://[ff08:90:5001:0:0:0:0:1]:12345/c?a=4
decoded packet is 52 02 00 00 91 63 63 61 3d 34 . Here 63 61 3d 34 is the query part ?a=4 . There is a data after query. I have pointed my buffer pointer to 63(?), now I'm struck in getting the value 34(4). How do I go to the value and extract it?
coap_h *hdr = (coap_h *)(buf);
buf = (uint8_t *)(hdr + 1);
len = buf[0] & 0xf;
buf += len + 1;
buf points to 52 initially and then I move the buf to the options field 91 and check for length then increment the buf which points to 63 (?). hope i'm clear this time.
I don't have the time at the moment to parse your packet by hand, but you should know that the way options work has changed dramatically in CoAP-12. I have implemented some functions to encode and parse options, which you might find useful:
https://github.com/darconeous/smcp/blob/master/src/smcp/coap.c
https://github.com/darconeous/smcp/blob/master/src/smcp/coap.h

Resources