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

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);

Related

POS bluetooth printer leaving some margin at start and then starts printing in Android App

I am implementing POS bluetooth printer with ESC/POS commands and trying to print bitmap image.
Image is getting printing but always it is printing some white space at start and then printing an image,because of which i am not able to print 1 image per label.
following is my code for printing and image
int bmpNewWidth = bmp.getWidth();
int bmpNewHeight = bmp.getHeight();
byte[] printBMPPackageHead = ESCUtil.bmpCmdHead(bmpMode,bmpNewWidth);
int bmpBlockHeight = 0;
int bmpBlockNums =0;
if((bmpMode == 0) || (bmpMode ==1))
{
bmpBlockHeight = 8;
}
else if((bmpMode == 32) || (bmpMode ==33))
{
bmpBlockHeight = 24;
}
else
{
Log.d(TAG,"****bmpMode set error!!*****");
return (new byte[1]);
}
bmpBlockNums = ((bmpNewHeight % bmpBlockHeight) == 0)? (bmpNewHeight/bmpBlockHeight) : (bmpNewHeight/bmpBlockHeight +1);
int bmpBlockCMDSize = printBMPPackageHead.length + bmpNewWidth*bmpBlockHeight/8;
byte[] bmpPrintData = new byte[bmpBlockNums*bmpBlockCMDSize];
for(int n = 0; n < bmpBlockNums; n++)
{
byte[] bmpBlockPxBytes = getBitmapBlockData(n,bmpNewWidth,bmpBlockHeight,bmp);
byte[][] bmpBlockPrintData = {printBMPPackageHead,bmpBlockPxBytes};
System.arraycopy(ESCUtil.byteMerger(bmpBlockPrintData),0,bmpPrintData,n*bmpBlockCMDSize,bmpBlockCMDSize);
}
return bmpPrintData;
}
and
public static byte[] bmpCmdHead(int mode, int bitmapWidth)
{
//byte[] result = new byte[]{ESC,42,0,0,0};
byte[] result = new byte[]{ESC,42,0,0,0};
result[2] = (byte)mode;
result[3] = (byte)(bitmapWidth%256);
result[4] = (byte)(bitmapWidth/256);
return result;
}
public static byte[] getBitmapBlockData(int blocknum, int bmpWidth, int bmpBlockHeight, Bitmap bmp)
{
int blockHeightBytes = bmpBlockHeight/8;
byte[] blockData = new byte[bmpWidth*blockHeightBytes];
for (int i = 0;i < bmpWidth; i++)
{
for(int j = 0;j < blockHeightBytes;j++)
{
for(int p = 0; p < 8; p++)
{
byte px = px2Byte(i,blocknum * bmpBlockHeight+j*8+p,bmp);
blockData[i*blockHeightBytes+j] |= (px << (7-p));
}
}
}
return blockData;
}
this is it.Before calling this function i have called only init printer command that's it.
Please help me. Thanks in advance.

Get all packet(uint) from byte array

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

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 send data to ble?

I have use mBluetoothGatt.writeDescriptor(descriptor) or writeCharacteristic(characteristic)
to send data to ble devices.
but the devices can't received.I don't konw why?
This is my code :
public void writeDataToBel() {
if ((gattCharacteristics_send.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
System.out.println("have permission");
}
String send_data = "d300000000060000000000000000d900";
gattCharacteristics_send.setValue(send_data);
gattCharacteristics_send
.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
boolean sendStatus = mBluetoothGatt
.writeCharacteristic(gattCharacteristics_send);
System.out.println("status-->" + sendStatus);
}
Make sure that the characterisitic you are writing to has a write permission. you can perform the check in the following way:
if((gattCharacteristics_send.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE ) > 0) {
gattCharacteristics_send.setValue(send_data);
boolean sendStatus = mBluetoothGatt.writeCharacteristic(gattCharacteristics_send);
}
I have resolved it:
"d300000000060000000000000000d900" chageTo byte[]
public static byte[] changeToByte(String sendData) {
byte[] myByte = new byte[16];
int[] myInt = new int[16];
for (int i = 0; i < myByte.length; i++) {
myInt[i]=Integer.valueOf(sendData.substring(i*2, (i+1)*2), 16);
}
for (int i = 0; i < myByte.length; i++) {
myByte[i] = (byte) myInt[i];
}
return myByte;
}

Convert hex string to byte []

I've got a String like this:
init_thread = "2b11020000ed"
I have to send this string via bluetooth, for what I do this:
byte[] init = init_thread.getBytes();
GlobalVar.mTransmission.write(init);
What I need is to define that the init_thread string is an hex string before converting it to bytes, because if I do this way, it is getting it wrong:
What is doing now = 2(1byte), b(1byte), 1(1byte), 1(1byte)...
What must do = 2b(1byte), 11(1byte), 02(1byte)...
Convert hex to byte and byte to hex.
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;
}
final protected static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
public static String byteArrayToHexString(byte[] bytes) {
char[] hexChars = new char[bytes.length*2];
int v;
for(int j=0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j*2] = hexArray[v>>>4];
hexChars[j*2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
If we want to convert hex to byte array, we should make sure that hex string length should be of even length. Below method handles this
public static byte[] hexToByteArray(String hex) {
hex = hex.length()%2 != 0?"0"+hex:hex;
byte[] b = new byte[hex.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(hex.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}

Categories

Resources