Get all packet(uint) from byte array - android

I am working on one BLE project
I am getting following data(In Byte array while scanning BLE device) as an advertising data 0x02011A09094F6E65506C757332020AF9 you can see in the screenshot there is three packet, can anyone help me how can get all three packet by java code.

You can try this :
public SparseArray<byte[]> parseAdvertisingData(byte[] rawData) {
final SparseArray<byte[]> parsedData = new SparseArray<>();
for (int index = 0; index < rawData.length; ) {
final byte dataLength = rawData[index++];
if (dataLength == 0) {
break;
}
final int dataType = rawData[index];
if (dataType == 0) {
break;
}
byte[] data = Arrays.copyOfRange(rawData, index + 1, index + dataLength);
parsedData.put(dataType, data);
index += dataLength;
}
return parsedData;
}
Here is a simple example:
final byte[] rawData = Utils.parseHexBinary("02011A09094F6E65506C757332020AF9");
final SparseArray<byte[]> parsed = parseAdvertisingData(rawData);
for (int i = 0; i < parsed.size(); i++) {
final int type = parsed.keyAt(i);
final byte[] data = parsed.valueAt(i);
Log.d(TAG, String.format("type: 0x%02x, value: 0x%s", type,
new BigInteger(1, data).toString(16)));
}
result:
type: 0x01, value: 0x1a
type: 0x09, value: 0x4f6e65506c757332
type: 0x0a, value: 0xf9

Related

Mixing two16-bit encoded stereo PCM samples causing noise and distortion in the resulting audio

I get two different audio samples from two sources.
For microphone sound:
audioRecord =
new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT,
(AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT)*5));
For Internal sound:
audioRecord = new AudioRecord.Builder()
.setAudioPlaybackCaptureConfig(config)
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(44100)
.setChannelMask(AudioFormat.CHANNEL_IN_STEREO)
.build())
.setBufferSizeInBytes((AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT)*5))
.build();
For reading from the audioRecord object we create individual frame objects(Custom objects called frame)-
private ByteBuffer pcmBuffer = ByteBuffer.allocateDirect(4096);
private Frame read() {
pcmBuffer.rewind();
int size = audioRecord.read(pcmBuffer, pcmBuffer.remaining());
if (size <= 0) {
return null;
}
return new Frame(pcmBuffer.array(),
pcmBuffer.arrayOffset(), size);
}
We create two separate LL(Linked List) for adding these frames that we get from read function.
private LinkedList internalAudioQueue = new LinkedList<>();
private LinkedList microphoneAudioQueue = new LinkedList<>();
public void onFrameReceived(Frame frame, boolean isInternalAudio) {
if (isInternalAudio) {
internalAudioQueue.add(frame);
} else {
microphoneAudioQueue.add(frame);
}
checkAndPoll();
}
Every time we add a frame in the respective LL we call the following checkAndPoll() function and depending upon the case pass the frame to the audioEncoder.
public void checkAndPoll() {
Frame frame1 = internalAudioQueue.poll();
Frame frame2 = microphoneAudioQueue.poll();
if (frame1 == null && frame2 != null) {
audioEncoder.inputPCMData(frame2);
} else if (frame1 != null && frame2 == null) {
audioEncoder.inputPCMData(frame1);
} else if (frame1 != null && frame2 != null) {
Frame frame = new Frame(PCMUtil.mix(frame1.getBuffer(), frame2.getBuffer(), frame1.getSize(), frame2.getSize(), false), frame1.getOrientation(), frame1.getSize());
audioEncoder.inputPCMData(frame);
}
}
Now we mix the audio samples in form of ByteBuffer from the two sources in this way taking Hendrik's help from this link.
public static byte[] mix(final byte[] a, final byte[] b, final boolean bigEndian) {
final byte[] aa;
final byte[] bb;
final int length = Math.max(a.length, b.length);
// ensure same lengths
if (a.length != b.length) {
aa = new byte[length];
bb = new byte[length];
System.arraycopy(a, 0, aa, 0, a.length);
System.arraycopy(b, 0, bb, 0, b.length);
} else {
aa = a;
bb = b;
}
// convert to samples
final int[] aSamples = toSamples(aa, bigEndian);
final int[] bSamples = toSamples(bb, bigEndian);
// mix by adding
final int[] mix = new int[aSamples.length];
for (int i=0; i<mix.length; i++) {
mix[i] = aSamples[i] + bSamples[i];
// enforce min and max (may introduce clipping)
mix[i] = Math.min(Short.MAX_VALUE, mix[i]);
mix[i] = Math.max(Short.MIN_VALUE, mix[i]);
}
// convert back to bytes
return toBytes(mix, bigEndian);
}
private static int[] toSamples(final byte[] byteSamples, final boolean bigEndian) {
final int bytesPerChannel = 2;
final int length = byteSamples.length / bytesPerChannel;
if ((length % 2) != 0) throw new IllegalArgumentException("For 16 bit audio, length must be even: " + length);
final int[] samples = new int[length];
for (int sampleNumber = 0; sampleNumber < length; sampleNumber++) {
final int sampleOffset = sampleNumber * bytesPerChannel;
final int sample = bigEndian
? byteToIntBigEndian(byteSamples, sampleOffset, bytesPerChannel)
: byteToIntLittleEndian(byteSamples, sampleOffset, bytesPerChannel);
samples[sampleNumber] = sample;
}
return samples;
}
private static byte[] toBytes(final int[] intSamples, final boolean bigEndian) {
final int bytesPerChannel = 2;
final int length = intSamples.length * bytesPerChannel;
final byte[] bytes = new byte[length];
for (int sampleNumber = 0; sampleNumber < intSamples.length; sampleNumber++) {
final byte[] b = bigEndian
? intToByteBigEndian(intSamples[sampleNumber], bytesPerChannel)
: intToByteLittleEndian(intSamples[sampleNumber], bytesPerChannel);
System.arraycopy(b, 0, bytes, sampleNumber * bytesPerChannel, bytesPerChannel);
}
return bytes;
}
// from https://github.com/hendriks73/jipes/blob/master/src/main/java/com/tagtraum/jipes/audio/AudioSignalSource.java#L238
private static int byteToIntLittleEndian(final byte[] buf, final int offset, final int bytesPerSample) {
int sample = 0;
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
final int aByte = buf[offset + byteIndex] & 0xff;
sample += aByte << 8 * (byteIndex);
}
return (short)sample;
}
// from https://github.com/hendriks73/jipes/blob/master/src/main/java/com/tagtraum/jipes/audio/AudioSignalSource.java#L247
private static int byteToIntBigEndian(final byte[] buf, final int offset, final int bytesPerSample) {
int sample = 0;
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
final int aByte = buf[offset + byteIndex] & 0xff;
sample += aByte << (8 * (bytesPerSample - byteIndex - 1));
}
return (short)sample;
}
private static byte[] intToByteLittleEndian(final int sample, final int bytesPerSample) {
byte[] buf = new byte[bytesPerSample];
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
buf[byteIndex] = (byte)((sample >>> (8 * byteIndex)) & 0xFF);
}
return buf;
}
private static byte[] intToByteBigEndian(final int sample, final int bytesPerSample) {
byte[] buf = new byte[bytesPerSample];
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
buf[byteIndex] = (byte)((sample >>> (8 * (bytesPerSample - byteIndex - 1))) & 0xFF);
}
return buf;
}
The mixed samples that I am getting have both distortion and noise. Not able to figure out what needs to be done to remove it. Any help here is appreciated.
Thanks in Advance!
I think if you're mixing, you should take the (weighted) average of both.
If you've got a sample 128 and 128, the result would be still 128, not 256, which could be out-of-range.
So just change your code to:
// mix by adding
final int[] mix = new int[aSamples.length];
for (int i=0; i<mix.length; i++) {
// calculating the average
mix[i] = (aSamples[i] + bSamples[i]) >> 1;
}
Does that work for you?

How to write a hash function in Android similar to the Python function?

I am currently developing a distributed system application. I want to verify a Python generated hash in the Android application. I have a python method to do hashing in given string variables.
This is the python function and it works well.
hash_value = hashlib.sha1("PARAMETER123".encode("UTF-8")).hexdigest()
I want to implement the same function in my Android application. I hope some expert can help as soon as possible.
You can try the following code snippet,
String text = "PARAMETER123";
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] textBytes = text.getBytes("UTF-8");
md.update(textBytes, 0, textBytes.length);
byte[] sha1hash = md.digest();
String encrypted_text = = convertToHex(sha1hash);
and the convertToHex() method
private static String convertToHex(byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
This will convert a UTF-8 based text into a SHA1 hex.
Reference: https://stackoverflow.com/a/5980789/2506025
Here is a simple SHA1 method for Java:
String sha1Hash( String toHash )
{
String hash = null;
try
{
MessageDigest digest = MessageDigest.getInstance( "SHA-1" );
byte[] bytes = toHash.getBytes("UTF-8");
digest.update(bytes, 0, bytes.length);
bytes = digest.digest();
// This is ~55x faster than looping and String.formating()
hash = bytesToHex( bytes );
}
catch( NoSuchAlgorithmException e )
{
e.printStackTrace();
}
catch( UnsupportedEncodingException e )
{
e.printStackTrace();
}
return hash;
}
// http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex( byte[] bytes )
{
char[] hexChars = new char[ bytes.length * 2 ];
for( int j = 0; j < bytes.length; j++ )
{
int v = bytes[ j ] & 0xFF;
hexChars[ j * 2 ] = hexArray[ v >>> 4 ];
hexChars[ j * 2 + 1 ] = hexArray[ v & 0x0F ];
}
return new String( hexChars );
}
You can include those methods and call sha1hash.

How to aproach this in android? signed byte

I have a piece of problem that I want to achieve in android.
The formula is
Server Seed + Client Seed (->byte[4]) + Bet Number (->byte[4])
Double SHA2-512 hash the result
Keep taking groups of 3 bytes and converting to an integer, until a value less than 16 million is found. If you run out of bytes, hash it
again and start over.
Find the value's modulus of 1 million
The modulus is the bet result!
Which have an example code in C#
static bool VerifyBetResult(string serverSeed, int clientSeed, int betNumber,
long betResult, string serverSeedHash = null)
{
Func<string, byte[]> strtobytes = s => Enumerable
.Range(0, s.Length / 2)
.Select(x => byte.Parse(s.Substring(x * 2, 2), NumberStyles.HexNumber))
.ToArray();
byte[] server = strtobytes(serverSeed);
byte[] client = BitConverter.GetBytes(clientSeed).Reverse().ToArray();
byte[] num = BitConverter.GetBytes(betNumber).Reverse().ToArray();
byte[] serverhash = serverSeedHash == null ? null : strtobytes(serverSeedHash);
byte[] data = server.Concat(client).Concat(num).ToArray();
using (SHA512 sha512 = new SHA512Managed())
{
if (serverhash != null)
using (SHA256 sha256 = new SHA256Managed())
if (!sha256.ComputeHash(server).SequenceEqual(serverhash))
throw new Exception("Server seed hash does not match server seed");
byte[] hash = sha512.ComputeHash(sha512.ComputeHash(data));
while (true)
{
for (int x = 0; x <= 61; x += 3)
{
long result = (hash[x] << 16) | (hash[x + 1] << 8) | hash[x + 2];
if (result < 16000000)
return result % 1000000 == betResult;
}
hash = sha512.ComputeHash(hash);
}
}
}
Using these values
serverSeed = e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be;
clientSeed = 443944;
betNumber = 0;
serverHash = ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f;
I want to find the (result % 1000000) which should be = 563383
But I got -25564 and the serverHash does not match the serverSeed when hashing the seed to sha256
Update
This is my code:
private byte[] reverse(byte[] b){
int i = b.length - 1;
byte newB[] = new byte[4];
for(int x = 0; x < b.length; x++){
newB[x] = b[i];
i--;
}
return newB;
}
private byte[] strToByte(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
private long verifyBet(){
//MessageDigest md256 = null;
MessageDigest md512 = null;
try {
//md256 = MessageDigest.getInstance("SHA-256");
md512 = MessageDigest.getInstance("SHA-512");
} catch (Exception e) {
e.printStackTrace();
}
String //res = "ServerSeed = ",
sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
//sHash = "ca90022ac66a6a77d8b5072e101bff505c2bff552b1b9a0785f0c438d5b6228f";
int cSeed = 443944,
num = 0;
byte serverSeed[] = strToByte(sSeed),
//serverHash[] = strToByte(sHash),
clientSeed[] = reverse(ByteBuffer.allocate(4).putInt(cSeed).array()),
betNumber[] = reverse(ByteBuffer.allocate(4).putInt(num).array());
byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
.put(serverSeed).put(clientSeed).put(betNumber).array();
data = md512.digest(data);
data = md512.digest(data);
long secret = 0;
boolean found = false;
while(!found){
for(int x = 0; x <= 61; x += 3){
long result = (data[x] << 16 | data[x+1] << 8) | data[x+2];
if (result < 16000000){
secret = result % 1000000;
found = true;
}
}
data = md512.digest(data);
}
return secret;
}
After much more research I found that byte in java is signed while the code I am basing from is calculating in unsigned byte which is why I am getting result in negative..
How can I get set of bytes in 'unsigned' form?
After so much research and testing. I finally got it. This is the code.
private byte[] strToByte(String s) {
int len = s.length();
byte[] data = new byte[len/2];
for(int i = 0; i < len; i+=2){
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
}
return data;
}
private long verifyBet(int _num){
MessageDigest md512 = null;
try {
md512 = MessageDigest.getInstance("SHA-512");
} catch (Exception e) {
e.printStackTrace();
}
String sSeed = "e600f76aa6c520dff7db34559bd05cb1048b1830a07cd81844147a19048fc9be";
int cSeed = 443944,
num = _num;
byte serverSeed[] = strToByte(sSeed),
clientSeed[] = ByteBuffer.allocate(4).putInt(cSeed).array(),
betNumber[] = ByteBuffer.allocate(4).putInt(num).array();
byte data[] = ByteBuffer.allocate(serverSeed.length + clientSeed.length + betNumber.length)
.put(serverSeed).put(clientSeed).put(betNumber).array();
data = md512.digest(data);
data = md512.digest(data);
long secret = 0;
boolean found = false;
while(!found){
for(int x = 0; x <= 61; x += 3){
long result = ((data[x] & 0xFF) << 16 | (data[x+1] & 0xFF) << 8) | data[x+2] & 0xFF;
if (result < 16000000){
secret = result % 1000000;
found = true;
x = 62;
}
}
data = md512.digest(data);
}
return secret;
}

How to restore base64 encoded opencv java matrix to C++ cv::Mat?

I'm extracting ORB descriptors of an image in android using opencv which is then sent to a C++ server using a socket. To send it via the socket I'm encoding the opencv mat of descriptors to base64 using the below java code.
public static String matToJson(Mat mat){
JsonObject obj = new JsonObject();
if(mat.isContinuous()){
int cols = mat.cols();
int rows = mat.rows();
int elemSize = (int) mat.elemSize();
byte[] data = new byte[cols * rows * elemSize];
mat.get(0, 0, data);
obj.addProperty("rows", mat.rows());
obj.addProperty("cols", mat.cols());
obj.addProperty("type", mat.type());
// We cannot set binary data to a json object, so:
// Encoding data byte array to Base64.
String dataString = new String(Base64.encode(data, Base64.DEFAULT));
obj.addProperty("data", dataString);
Gson gson = new Gson();
String json = gson.toJson(obj);
return json;
} else {
Log.e(TAG, "Mat not continuous.");
}
public static Mat matFromJson(String json){
JsonParser parser = new JsonParser();
JsonObject JsonObject = parser.parse(json).getAsJsonObject();
int rows = JsonObject.get("rows").getAsInt();
int cols = JsonObject.get("cols").getAsInt();
int type = JsonObject.get("type").getAsInt();
String dataString = JsonObject.get("data").getAsString();
byte[] data = Base64.decode(dataString.getBytes(), Base64.DEFAULT);
Mat mat = new Mat(rows, cols, type);
mat.put(0, 0, data);
return mat;
}
The output from matToJson() looks like below:
{"rows":26,"cols":32,"type":0,"data":"aSbt5TQabzJ9qv7s3ymQchrEfSyp8OWO5v8nkG6oUiFAMLFkAExBEGCgJggSF0AyAFRoCAlgsADJ\niAUwQCBGImQwuWSATEEQYrAiCNY3QToBVGgYAWDxAMmIRTTAYEYibDS4YqltU5o7v68Y3/9JOpHX\n/RAaZvsiy991f8JzxnNJJ33lNB5vMn3ofkzfP5BwlkR/LKnw4c7n/yOQTuhTcUAwOWAATFEQYCAg\nCBYXADCAFFAIAWCwAMGJADBAAEYyYCAxQABNQQBgpCQIFhdAMgBUQAgAYLAAwYgBMEACRiJgMLFk\nAEhBAGKkJAgWF0AyAVRIGABgsADJiAUwwABGImwwuXW4bVGaM/+mGJ+3QTqV3v0YK3b5As/fNX3A\n4EZzQTCRZABMRQBgoiIIVjdAMgBUaBgBYLEAyagFMMBgRiJJPj33NJ57N33ofky/O5Bwhi5+DKm4\n4e7n/zKQSojDKXw0vHW4b1Gas7+2GNc3QzuF33wYKGT5AMvbdTTA8EZzQCCRZABIAQBgoCIIFhdA\nMgBUaBgBYKAAiYAFMEBgRiBpLv33NI9pN30p/1z/KZBwgqZ8DLn44S7G/zKQSoDDKUAhEUAQSEEA\nYAAgCBYXADAQVEBAASCgACGIABBAAEYgdDC8dahsURLiv7YYlzdAOofWfRiLRfsAy8t1NODgRnNA\nIJFEAEgAAGCgIAgWE0AyAFRIAABgoACJgAUwQCBGIEAikEQgCAACYKggaBITwDIAVEwAAGCAAImA\nJTBAIAIhYDC5dGhtURJzvzYYl7dAOofWfRgLePMA34t1cODARnNAIBFAEEgAAGAAIAgSEwAwEFxA\nYEEggAwhiAAQQAJGIHEy1WQoDEEQ4KiyTJcTwDIExGwMiWHRAMCpIbBogEIhcapb+iytSRfzGbNY\nt4PQeEuubByba8Ix2vkwWOiIwil4oLhwie1RjqK3rhiXtUIagdbsEBpr4wDb5XV54EDGYnAwuXSI\nbVEb4rekGBe3QDoB1mwYGm/6EtundT3g4MZicaBb+qytSZb+GbFct8PYeKGObBybbdox2ekyePiB\nwij1oBl6rKxJm/IRoVi300g4gYpsHDtr2jPZqzR42MDCIA\u003d\u003d\n"}
the encoded base64 string in the "data" key is the Matrix data.
The above json string is sent to the server via socket.
Now, I need to convert the "data" value of the json string back to cv::Mat in C++, so how do i get back the matrix from the above base64 string ?
Assuming that you read the data from the JSON, you can create the Mat like this:
int rows = 26;
int cols = 32;
int type = 0;
string data = "aSbt5TQabz...";
string decoded_data = base64_decode(data);
Mat m(rows, cols, type, (void*)decoded_data.data());
Code for base64_decode is from here
NOTE
I needed to manually convert the characted \u003D to = to make it work. You can avoid to escape HTML characters using Gson gson = new GsonBuilder().disableHtmlEscaping().create();. See here.
Code:
#include <opencv2\opencv.hpp>
#include <vector>
#include <string>
using namespace std;
using namespace cv;
// Code from: http://www.adp-gmbh.ch/cpp/common/base64.html
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++)
char_array_4[j] = 0;
for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
int main()
{
// Read your JSON here...
int rows = 26;
int cols = 32;
int type = 0;
//string data(L"aSbt5TQabzJ9qv7s3ymQchrEfSyp8OWO5v8nkG6oUiFAMLFkAExBEGCgJggSF0AyAFRoCAlgsADJ\niAUwQCBGImQwuWSATEEQYrAiCNY3QToBVGgYAWDxAMmIRTTAYEYibDS4YqltU5o7v68Y3/9JOpHX\n/RAaZvsiy991f8JzxnNJJ33lNB5vMn3ofkzfP5BwlkR/LKnw4c7n/yOQTuhTcUAwOWAATFEQYCAg\nCBYXADCAFFAIAWCwAMGJADBAAEYyYCAxQABNQQBgpCQIFhdAMgBUQAgAYLAAwYgBMEACRiJgMLFk\nAEhBAGKkJAgWF0AyAVRIGABgsADJiAUwwABGImwwuXW4bVGaM/+mGJ+3QTqV3v0YK3b5As/fNX3A\n4EZzQTCRZABMRQBgoiIIVjdAMgBUaBgBYLEAyagFMMBgRiJJPj33NJ57N33ofky/O5Bwhi5+DKm4\n4e7n/zKQSojDKXw0vHW4b1Gas7+2GNc3QzuF33wYKGT5AMvbdTTA8EZzQCCRZABIAQBgoCIIFhdA\nMgBUaBgBYKAAiYAFMEBgRiBpLv33NI9pN30p/1z/KZBwgqZ8DLn44S7G/zKQSoDDKUAhEUAQSEEA\nYAAgCBYXADAQVEBAASCgACGIABBAAEYgdDC8dahsURLiv7YYlzdAOofWfRiLRfsAy8t1NODgRnNA\nIJFEAEgAAGCgIAgWE0AyAFRIAABgoACJgAUwQCBGIEAikEQgCAACYKggaBITwDIAVEwAAGCAAImA\nJTBAIAIhYDC5dGhtURJzvzYYl7dAOofWfRgLePMA34t1cODARnNAIBFAEEgAAGAAIAgSEwAwEFxA\nYEEggAwhiAAQQAJGIHEy1WQoDEEQ4KiyTJcTwDIExGwMiWHRAMCpIbBogEIhcapb+iytSRfzGbNY\nt4PQeEuubByba8Ix2vkwWOiIwil4oLhwie1RjqK3rhiXtUIagdbsEBpr4wDb5XV54EDGYnAwuXSI\nbVEb4rekGBe3QDoB1mwYGm/6EtundT3g4MZicaBb+qytSZb+GbFct8PYeKGObBybbdox2ekyePiB\nwij1oBl6rKxJm/IRoVi300g4gYpsHDtr2jPZqzR42MDCIA\u003d\u003d\n");
string data = "aSbt5TQabzJ9qv7s3ymQchrEfSyp8OWO5v8nkG6oUiFAMLFkAExBEGCgJggSF0AyAFRoCAlgsADJ\niAUwQCBGImQwuWSATEEQYrAiCNY3QToBVGgYAWDxAMmIRTTAYEYibDS4YqltU5o7v68Y3/9JOpHX\n/RAaZvsiy991f8JzxnNJJ33lNB5vMn3ofkzfP5BwlkR/LKnw4c7n/yOQTuhTcUAwOWAATFEQYCAg\nCBYXADCAFFAIAWCwAMGJADBAAEYyYCAxQABNQQBgpCQIFhdAMgBUQAgAYLAAwYgBMEACRiJgMLFk\nAEhBAGKkJAgWF0AyAVRIGABgsADJiAUwwABGImwwuXW4bVGaM/+mGJ+3QTqV3v0YK3b5As/fNX3A\n4EZzQTCRZABMRQBgoiIIVjdAMgBUaBgBYLEAyagFMMBgRiJJPj33NJ57N33ofky/O5Bwhi5+DKm4\n4e7n/zKQSojDKXw0vHW4b1Gas7+2GNc3QzuF33wYKGT5AMvbdTTA8EZzQCCRZABIAQBgoCIIFhdA\nMgBUaBgBYKAAiYAFMEBgRiBpLv33NI9pN30p/1z/KZBwgqZ8DLn44S7G/zKQSoDDKUAhEUAQSEEA\nYAAgCBYXADAQVEBAASCgACGIABBAAEYgdDC8dahsURLiv7YYlzdAOofWfRiLRfsAy8t1NODgRnNA\nIJFEAEgAAGCgIAgWE0AyAFRIAABgoACJgAUwQCBGIEAikEQgCAACYKggaBITwDIAVEwAAGCAAImA\nJTBAIAIhYDC5dGhtURJzvzYYl7dAOofWfRgLePMA34t1cODARnNAIBFAEEgAAGAAIAgSEwAwEFxA\nYEEggAwhiAAQQAJGIHEy1WQoDEEQ4KiyTJcTwDIExGwMiWHRAMCpIbBogEIhcapb+iytSRfzGbNY\nt4PQeEuubByba8Ix2vkwWOiIwil4oLhwie1RjqK3rhiXtUIagdbsEBpr4wDb5XV54EDGYnAwuXSI\nbVEb4rekGBe3QDoB1mwYGm/6EtundT3g4MZicaBb+qytSZb+GbFct8PYeKGObBybbdox2ekyePiB\nwij1oBl6rKxJm/IRoVi300g4gYpsHDtr2jPZqzR42MDCIA==\n";
string decoded_data = base64_decode(data);
Mat m(rows, cols, type, (void*)decoded_data.data());
cout << m << endl;
return 0;
}

How to covert String to byte for BLE mBluetoothGatt.writeCharacteristic?

I am developing in Android BLE.
I try to send string to BLE device(like TI CC2541) , and it seems can not send string direct to BLE device.
It need to convert the String to Byte.
I have search some information , there has someone use URLEncoder.encode.
But I am not sure which is the answer what I need.
But how to convert the String to Byte?
The following code is writeCharacteristic for BLE
public void writeString(String text) {
// TODO Auto-generated method stub
BluetoothGattService HelloService = mBluetoothGatt.getService(HELLO_SERVICE_UUID);
BluetoothGattCharacteristic StringCharacteristic = HelloService.getCharacteristic(UUID_HELLO_CHARACTERISTIC_WRITE_STRING);
mBluetoothGatt.setCharacteristicNotification(StringCharacteristic , true);
int A = Integer.parseInt(text);
//How to convert the String to Byte here and set the Byte to setValue ?????
StringCharacteristic .setValue(A, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
mBluetoothGatt.writeCharacteristic(StringCharacteristic );
Log.d(TAG, "StepCount Characteristic End!");
}
How to convert the String to Byte?
Where you get your String:
byte[] strBytes = text.getBytes();
byte[] bytes = context.yourmWriteCharacteristic.getValue();
Please add a null check too like:
if (bytes == null) {
Log.w("Cannot get Values from mWriteCharacteristic.");
dismiss();// equivalent action
}
if (bytes.length <= strBytes.length) {
for(int i = 0; i < bytes.length; i++) {
bytes[i] = strBytes[i];
}
} else {
for (int i = 0; i < strBytes.length; i++) {
bytes[i] = strBytes[i];
}
}
Now, something like:
StepCount_Characteristic.setValue(bytes);
mBluetoothGatt.writeCharacteristic(StepCount_Characteristic);
I found the following code help me convert the string.
private byte[] parseHex(String hexString) {
hexString = hexString.replaceAll("\\s", "").toUpperCase();
String filtered = new String();
for(int i = 0; i != hexString.length(); ++i) {
if (hexVal(hexString.charAt(i)) != -1)
filtered += hexString.charAt(i);
}
if (filtered.length() % 2 != 0) {
char last = filtered.charAt(filtered.length() - 1);
filtered = filtered.substring(0, filtered.length() - 1) + '0' + last;
}
return hexStringToByteArray(filtered);
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
private int hexVal(char ch) {
return Character.digit(ch, 16);
}
If you want to convert string value. you just need to call like the following:
String text;
byte[] value = parseHex(text);

Categories

Resources