How to target specific int (bits) in an int array into Uint16 or 32? - flutter

I have a list of int like the following.
List<int> data = [52, 24, 40, 0, 198, 7, 98, 0, 0, 0, 40, 223, 30, 0, 203, 244, 0, 0]
I would like to generate 8/16/32 Uint so that I can process them. For example, bytes 2 & 3 is actually a 16 bit value, so both bytes need to be added, in the right order which in this case is 00000000 00101000 .
Question: How can I target specific index to add to a specific Uint type?
eg.. Uint16 powerValue = data[2] data[3];

Presuming that your List<int> is meant to be a list of bytes, convert your List<int> into a Uint8List with Uint8List.fromList. Note that your List<int> might already be a Uint8List; if so, just cast it with as Uint8List to avoid an unnecessary copy.
Access the Uint8List.buffer getter to obtain the underlying ByteBuffer.
You then can use methods such as ByteBuffer.asUint16List, ByteBuffer.asUint32List, etc. These methods allow you to specify a starting offset and length.
Alternatively, if you need more control (for example, if you want to interpret bytes using the non-native endianness), then you can use ByteBuffer.asByteData to obtain a ByteData view that provides methods such as getUint16, getUint32, etc.
Putting it all together, for your specific example:
import 'dart:typed_data';
void main() {
List<int> data = [
52,
24,
40,
0,
198,
7,
98,
0,
0,
0,
40,
223,
30,
0,
203,
244,
0,
0
];
var bytes = Uint8List.fromList(data);
var powerValue = bytes.buffer.asByteData().getUint16(2, Endian.little);
print(value); // Prints: 40
}
Of course, if this is just something you need to do as a one-off case, you also could just do bitwise operations yourself:
var powerValue = (data[3] << 8) | data[2];

Related

how to convert Decimal numbers to ASCII?

Hello i want to convert a decimal number to ASCII so this the code i parse my string to int then i call the function String.fromCharCode to convert the int to decimal . But it doesn't work any help ! thanks
String payload ="47, 50, 48, 50, 50, 59, 49, 52, 58, 51, 52, 59, 48, 55, 47, 58, 5";
print (payload);
for (var i = 0; i < payload.length; i++)
{
print (payload[i]);
data = String.fromCharCode(int. parse(payload[i])) + data ;
}
print(data);
Try this one:
for(int i=65; i<=90; i++){
print("${String.fromCharCode(i)}");
}
You first need to split your String into tokens, parse those individually, and then create a String from the parsed integer values.
void main() {
String payload =
"47, 50, 48, 50, 50, 59, 49, 52, 58, 51, 52, 59, 48, 55, 47, 58, 5";
var s = String.fromCharCodes(payload.split(',').map(int.parse));
print(s);
}
I'll also point out that an ASCII value of 5 (ENQ) is very suspect.
okay so this how it works for me
String payload ="47, 50, 48, 50, 50, 59, 49, 52, 58, 51, 52, 59, 48, 55, 47, 58, 5";
final splitted = payload.split(',');
for (var i = 0; i < splitted.length ; i++)
{
print (splitted[i]);
data = String.fromCharCode(int.parse(splitted[i])) + data ;
}
print(data);

I am working with BLE in dart, where I need to send 9 bytes to the specific characteristic , where first byte is 5 and remaining is epoch

Hi I trying to send 9 bytes to specific characteristic, where first byte is 0x05 , i.e 5 ,and next 8 bytes as epoch in seconds,
I tried this,
List<int> timeDataForBLEWrite = [0x5, 0, 0, 0, 0, 0, 0, 0, 0 ]; // here 0 will be replaced by 8 bytes of epoch
to get epoch in seconds, I tried this,
int timestampEpochInSeconds = DateTime.now().millisecondsSinceEpoch ~/ 1000; // 1623331779
to convert epoch into bytes I have tried this,
List<int> bytes = utf8.encode(timestampEpochInSeconds.toString());
but here I am getting 10 bytes because timestampEpochInSeconds is 1623331779 // 10 digits
print(bytes); // [49, 54, 50, 51, 51, 51, 49, 55, 55, 57]
how can I get 8 integers from the seconds epoch so that I can send total 9 bytes to the characteristic. like below,
characteristic.write(timeDataForBLEWrite);
I am assuming that you don't want the string in bytes but the values in bytes.
Most data in Bluetooth is in Little Endian so I have made that assumption about the timestamp as bytes.
I did the following as an example on DartPad:
import 'dart:typed_data';
List<int> epoch() {
var timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
var sendValueBytes = ByteData(9);
sendValueBytes.setUint8(0, 5);
// setUint64 not implemented on some systems so use setUint32 in
// those cases. Leading zeros to pad to equal 64 bit.
// Epoch as 32-bit good until 2038 Jan 19 # 03:14:07
try {
sendValueBytes.setUint64(1, timestamp.toInt(), Endian.little);
} on UnsupportedError {
sendValueBytes.setUint32(1, timestamp.toInt(), Endian.little);
}
return sendValueBytes.buffer.asUint8List();
}
void main() {
print('Epoch Bytes (plus 0x05): ${epoch()}');
}
Which gave the following output:
Epoch Bytes (plus 0x05): [5, 167, 60, 194, 96, 0, 0, 0, 0]

Decode Ble data raw flutter

I'm developing a flutter app using the flutter_blue library to interface a BlueNRG-tile from STMicroelectronics. I'm receiving the the raw data from the desired caracteristics then i'm note able ble to convert them to string using the utf8.decode() function.
This is the received data as a list and the issue.
I/flutter (32277): Teste conversion : [121, 85, 0, 0, 209, 133, 1, 0, 5, 10, 237, 0, 0, 0]
E/flutter (32277): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: FormatException: Missing extension byte (at offset 11).
the code from the in the st board:
tBleStatus Environmental_Update(int32_t Press,int32_t Press2,uint16_t Hum, int16_t Temp,int16_t Temp2) {
uint8_t BuffPos = 0;
STORE_LE_16(buff, (getTimestamp()));
BuffPos = 2;
STORE_LE_32(buff + BuffPos, Press);
BuffPos += 4;
STORE_LE_16(buff + BuffPos, Hum);
BuffPos += 2;
STORE_LE_16(buff + BuffPos, Temp);
BuffPos += 2;
STORE_LE_16(buff + BuffPos, Temp2);
return aci_gatt_update_char_value(HWServW2STHandle, EnvironmentalCharHandle, 0, EnvironmentalCharSize, buff);
}
Environmental_Update(PressToSend,PressToSend2, HumToSend, TempToSend,TempToSend2);
Thank You.
You are not able to convert your RAW data to string because you are not sending it as string but in form of bytes.
Take your temperature for example:
You receive the temperature as int16_t, a 16-bit number storing values from –32768 to 32767. This number needs two bytes to be stored, that's why you used BuffPos += 2; and increased the position by 2 bytes.
You need to extract the values from your received array the same way, bytewise. Have a look at this example:
import 'dart:typed_data';
int fromBytesToInt16(int b1, int b0) {
final int8List = new Int8List(2)
..[1] = b1
..[0] = b0;
return ByteData.sublistView(int8List).getInt16(0);
}
void main() {
var received = [121, 85, 0, 0, 209, 133, 1, 0, 5, 10, 237, 0, 0, 0];
var temp = fromBytesToInt16(received[8], received[9]) / 100;
print('temperature: $temp');
}
The temperature was stored as a int16 at index 8 and 9 so I converted it the same way. This results in a temp value of 2565, which divided by 100 would give a pretty nice temperature of 25.65 degree

The ten's digit and unit's digit of numbers

I have this code
int[,] array = new int[,]{ {34, 21, 32, 41, 25},
{14 ,42, 43, 14, 31},
{54, 45, 52, 42, 23},
{33, 15, 51, 31, 35},
{21, 52, 33, 13, 23} };
for (int i = 0; i < array.GetLength(1); i++)
{
for (int j = 0; j < array.GetLength(0); j++)
{
Console.Write(array[i, j] + " ");
}
Console.WriteLine();
}
and i need to find a specific number ( the treasure ).
For each value the ten's digit represents the row number and the unit's digit represents the column number of the cell containing the next clue.
Starting in the upper left corner (at 1,1), i have to use the clues to guide me search of the array. (The first three clues are 11, 34, 42).
The treasure is a cell whose value is the same as its coordinates.
The program should output the cells it visits during its search.
I did the simply way:
Console.WriteLine("The next clue is: {0}", array[0, 0]);
Console.WriteLine("The next clue is: {0}", array[2, 3]);
Console.WriteLine("The next clue is: {0}", array[3, 2]);
Console.WriteLine("The next clue is: {0}", array[0, 4]);
and so on, but the problem is, that if I change the array to set another route the program will output the wrong way. So the solution needs to be dynamic and find the treasure regardless of the array content.
My problem is that i don't know how to do to find the ten's digit of the numbers and the unit's digit.
Can anyone please help me with this?
To illustrate my comment: code below and Fiddle
(I've added a HashSet<int> to track which cells have already been visited and avoid ending up with an infinite loop)
int[,] array = new int[,]
{
{34, 21, 32, 41, 25},
{14 ,42, 43, 14, 31},
{54, 45, 52, 42, 23},
{33, 15, 51, 31, 35},
{21, 52, 33, 13, 23}
};
int currentCoordinates = 11;
bool treasureFound = false;
var visitedCells = new HashSet<int>();
while (!treasureFound && !visitedCells.Contains(currentCoordinates))
{
int currentRowIndex = currentCoordinates / 10;
int currentColumnIndex = currentCoordinates % 10;
int nextCoordinates = array[currentRowIndex - 1, currentColumnIndex - 1];
if (nextCoordinates == currentCoordinates)
{
treasureFound = true;
}
else
{
visitedCells.Add(currentCoordinates);
currentCoordinates = nextCoordinates;
}
}
if (treasureFound)
{
Console.WriteLine($"Treasure found in cell {currentCoordinates}");
}
else
{
Console.WriteLine("No treasure");
}

Invalid MIT magic cookie when connecting to X server

I'm trying to write my own code to connect to an X server. I ran xauth to get the magic cookie I needed and wrote the following code to try and test out establishing a connection:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int main()
{
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un serv_addr;
memset((void*)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, "/tmp/.X11-unix/X0");
int servlen = 17 + sizeof(serv_addr.sun_family);
int err = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);
char arr[] = {108, 0, // 'l' for little-endian
11, 0, // X version
0, 0, // X minor version
18, 0, // length of auth protocol name
16, 0, // length of auth protocol data
0, 0, // padding
77, 73, 84, 45, 77, 65, 71, 73, 67, 45, 67, 79, 79, 75, 73, 69, 45, 49, // MIT-MAGIC-COOKIE-1
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223, 88, 218, 121, 215, 6, 185, 105, 137, 80, 105, 252, 49, 109, 38, 200, // data from .Xauthority
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ssize_t bytes_written = write(sockfd, arr, sizeof(arr));
printf("%d\n", bytes_written);
uint8_t buf[5000];
ssize_t bytes_read = read(sockfd, buf, 5000);
printf("%d\n", bytes_read);
unsigned char k;
for(k = 0; k < 40; k++) {
printf("%c", buf[k]);
}
return 0;
}
The X server responds all right but it gives me an authentication failed message with "Invalid MIT-MAGIC-COOKIE-1 key" as the reason. The key I'm giving is the same as the one in my .Xauthority file (df58da79d706b969895069fc316d26c8, in case anyone wants to check!) Is there something else I'm missing?
you have too much of padding zeroes. should be:
char arr[] = {108, 0, // 'l' for little-endian
11, 0, // X version
0, 0, // X minor version
18, 0, // length of auth protocol name
16, 0, // length of auth protocol data
0, 0, // padding
77, 73, 84, 45, 77, 65, 71, 73, 67, 45, 67, 79, 79, 75, 73, 69, 45, 49, // MIT-MAGIC-COOKIE-1
0, 0, // two bytes to pad 18-byte MIT-MAGIC-COOKIE-1 to factor of 4 - 20
223, 88, 218, 121, 215, 6, 185, 105, 137, 80, 105, 252, 49, 109, 38, 200 // data from .Xauthority
}; // no need for more padding, auth data is 16 bytes long, factor of 4
From page 140 of X11 protocol:
Information sent by the client at connection setup:
1 byte-order
▶x42 MSB first
▶x6C LSB first
1 unused
2 CARD16 protocol-major-version
2 CARD16 protocol-minor-version
2 n length of authorization-protocol-name
2 d length of authorization-protocol-data
2 unused
n STRING8 authorization-protocol-name
p unused, p=pad(n)
d STRING8 authorization-protocol-data
q unused, q=pad(d)