iT邦幫忙

0

ble封包擷取資料與上個封包進行比對, 檢查是否相同, 程式碼修 輸出改了,可執行

最近想做個小實驗,比對藍芽接收上個封包擷取資料是否與下個封包擷取的一樣, 一直有問題, 大約知道是兩個暫存的array比較判斷位置放的不對, 但一直嘗試後仍是無效,不同的資料一直跑相同的輸出,故上來發問,想問問大家的邏輯.

測資:

final static byte[] PATTERN_04a = {0x02, 0x01, 0x04, 0x03
            , 0x01, 0x00, 0x00, 0x00
            , (byte) 0x0C, 0x00, 0x00, 0x00
            , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
    };

    final static byte[] PATTERN_04b = {
            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
            , 0x02, 0x01, 0x04, 0x03
            , 0x02, 0x00, 0x00, 0x00
            , (byte) 0x14, 0x00, 0x00, 0x00
            , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02
    };

    final static byte[] PATTERN_04c = {
            0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00
            , (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
            , 0x02, 0x01, 0x04, 0x03
            , 0x03, 0x00, 0x00, 0x00
            , (byte) 0x1C, 0x00, 0x00, 0x00
            , 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00
            , (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF
    };

全域變數:

    int len = 0;
    int len2 = 0;
    int len3 = 0;
    int len4 = 0;
    int dataLen = 0;
    int size = 0;
    int stickCount = 0;
    byte[] tak = new byte[24];
    byte[] check = new byte[24];
    int methodCount =0;
    ArrayList<Byte> rawDataList = new ArrayList<>();

主程式碼:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        byte[] increaseCapacity = new byte[PATTERN_04a.length];

        System.arraycopy(PATTERN_04a, 0, increaseCapacity, 0, PATTERN_04a.length);

        Byte[] byteObjects = new Byte[increaseCapacity.length];

        int i = 0;

        for (byte b : increaseCapacity) {
            byteObjects[i++] = b;  // Autoboxing.....
        }

        byte[] increaseCapacity2 = new byte[PATTERN_04b.length];

        System.arraycopy(PATTERN_04b, 0, increaseCapacity2, 0, PATTERN_04b.length);

        Byte[] byteObjects2 = new Byte[increaseCapacity2.length];

        int y = 0;

        for (byte a : increaseCapacity2) {
            byteObjects2[y++] = a;  // Autoboxing.....
        }

        byte[] increaseCapacity3 = new byte[PATTERN_04c.length];

        System.arraycopy(PATTERN_04c, 0, increaseCapacity3, 0, PATTERN_04c.length);

        Byte[] byteObjects3 = new Byte[increaseCapacity3.length];

        int t = 0;

        for (byte c : increaseCapacity3) {
            byteObjects3[t++] = c;  // Autoboxing.....
        }

//      System.out.println("原始資料暫存器放入資料前 "+ rawDataList);
        rawDataList.addAll(Arrays.asList(byteObjects));
        rawDataList.addAll(Arrays.asList(byteObjects2));
        rawDataList.addAll(Arrays.asList(byteObjects3));

//        System.out.println("listData " + rawDataList);

        byte[] result = new byte[rawDataList.size()];
        for(int a = 0; a < rawDataList.size(); a++) {
            result[a] = rawDataList.get(a).byteValue();
        }

//        StringBuilder stringBuilder2 = new StringBuilder(result.length);
//        for (byte byteChar : result)
//            stringBuilder2.append(String.format("%02X ", byteChar));
//        System.out.println(stringBuilder2.toString());

        size = result.length;

        for (int m = 0; m < size; m++) {
            if (m + 1 < size && m + 2 < size && m + 3 < size) {
                if ((result[m] & 0xFF) == 2 && (result[m+1] & 0xFF) == 1 && (result[m+2] & 0xFF) == 4 && (result[m+3] & 0xFF) == 3) {

//                  System.out.println("跑檢查標頭判斷後原始資料暫存器資料 "+ rawDataList);
                    len = (result[m+8] & 0xFF);
                    len2 = (result[m+9] & 0xFF);
                    len3 = (result[m+10] & 0xFF);
                    len4 = (result[m+11] & 0xFF);

                    dataLen = len + len2 + len3 + len4 - 4;

                    if (m+dataLen+12 < size && m+dataLen+13 < size && m+dataLen+14 < size && m+dataLen+15 < size) {
                        if (result[m+dataLen+12] == -1 && result[m+dataLen+13] == -1 && result[m+dataLen+14] == -1 && result[m+dataLen+15] == -1)
                        {
//                          testCount++;
//                          System.out.println("擷取方法呼叫次數 " + testCount);
//                          System.out.println("跑檢查標尾判斷後原始資料暫存器資料 "+ rawDataList);
                            stickCount++;
                        }
                    }
                }
            }
        }

        if( stickCount/stickCount == 1 && stickCount > 0) {
            findHeadTail(result);
        }

    }

擷取方法:

public void findHeadTail(byte[] array) {
        int length = 0;
        int length2 = 0;
        int length3 = 0;
        int length4 = 0;
        int dataLength = 0;
        int size = array.length;

        for (int k = 0; k < size; k++) {
            if (k + 1 < size && k + 2 < size && k + 3 < size) {
                if ((array[k] & 0xFF) == 2 && (array[k+1] & 0xFF) == 1 && (array[k+2] & 0xFF) == 4 && (array[k+3] & 0xFF) == 3) {
//                        headCount++;
//                        System.out.println("headCount " + headCount);
//                        System.out.println("跑尋找標頭判斷後原始資料暫存器資料 "+ rawDataList);

                    length = (array[k+8] & 0xFF);
                    length2 = (array[k+9] & 0xFF);
                    length3 = (array[k+10] & 0xFF);
                    length4 = (array[k+11] & 0xFF);

                    dataLength = length + length2 + length3 + length4 - 4;

                    if (k+dataLength+12 < size && k+dataLength+13 < size && k+dataLength+14 < size && k+dataLength+15 < size) {
                        if (array[k+dataLength+12] == -1 && array[k+dataLength+13] == -1 && array[k+dataLength+14] == -1 && array[k+dataLength+15] == -1)
                        {
//                                System.out.println("跑尋找標尾判斷後原始資料暫存器資料 "+ rawDataList);
//                                System.out.println("正確資料暫存器擷取資料前 "+ realDataList);
//                                tailCount++;
//                                System.out.println("tailCount "+ tailCount);

                            System.arraycopy(array,k+12,tak,0,dataLength);

                            System.arraycopy(array,k+12,check,0,dataLength);

//                                System.out.println("正確資料暫存器擷取資料後 "+ realDataList);

//                                StringBuilder stringBuilder = new StringBuilder(temp.length);
//                                for (byte byteChar : temp)
//                                    stringBuilder.append(String.format("%02X ", byteChar));
//                                System.out.println(stringBuilder.toString());
//                                printCount++;
//                                System.out.println("printCount "+ printCount);
                        }
                    }
                }
            }
        }

//        methodCount++;
//            System.out.println("methodCount "+ methodCount);

        StringBuilder sbTemp = new StringBuilder(tak.length);
        for (byte byteChar : tak) {
            sbTemp.append(String.format("%02X ", byteChar));
        }
        System.out.println(sbTemp.toString());

        StringBuilder sbCheck = new StringBuilder(check.length);
        for (byte byteChar : check) {
            sbCheck.append(String.format("%02X ", byteChar));
        }
        System.out.println(sbCheck.toString());

//            if(Arrays.equals(tak,check)){
//                System.out.println("資料相同 ");
//            }
//            else {
//                System.out.println("資料不相同 ");
//            }

    }

輸出:
https://ithelp.ithome.com.tw/upload/images/20211125/20143658LWhhexNLZh.png

habb2930 iT邦新手 5 級 ‧ 2021-11-25 10:31:51 檢舉
這裡沒辦法上傳source code???
habb2930 iT邦新手 5 級 ‧ 2021-11-25 13:58:45 檢舉
程式碼調整了

1 個回答

0
海綿寶寶
iT邦大神 1 級 ‧ 2021-11-25 10:38:15
Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. In other words, two arrays are equal if they contain the same elements in the same order. Also, two array references are considered equal if both are null.2018年5月30日

Java.util.Arrays.equals() in Java with Examples - GeeksforGeeks

依據以上說明,Arrays.equals有兩種可能
1.兩陣列「項目數」及「內容值」均相同
2.兩陣列都是 null

你可以在 Arrays.equals 之前將 temp,check 都顯示出來即可確定

StringBuilder sbTemp = new StringBuilder(temp.length);
for (byte byteChar : temp) {
    sbTemp.append(String.format("%02X ", byteChar));
}
System.out.println(sbTemp.toString());

StringBuilder sbCheck = new StringBuilder(check.length);
for (byte byteChar : check) {
    sbCheck.append(String.format("%02X ", byteChar));
}
System.out.println(sbCheck.toString());

另外
如果要貼程式碼,就要貼「完整」的程式碼
「完整」指的是只要複製貼上就可以直接執行,不需要另外手動補破洞

看更多先前的回應...收起先前的回應...
habb2930 iT邦新手 5 級 ‧ 2021-11-25 10:54:05 檢舉

我可能調整一下程式碼, 換個方式貼上來, 剛剛突然發現直接貼完整的ble程式碼,版上各位好像也無法執行

如果無法執行,像這列
byte[] temp = characteristic.getValue();
那就只能用想的
也就比較沒人會幫你看
你就自己debug

habb2930 iT邦新手 5 級 ‧ 2021-11-25 12:01:33 檢舉

如果這論壇能夾帶檔案就好了,比較方便

habb2930 iT邦新手 5 級 ‧ 2021-11-25 13:59:43 檢舉

程式碼調整完畢了

habb2930 iT邦新手 5 級 ‧ 2021-11-25 14:46:28 檢舉

那就怪了,應該要不一樣才對

除了「宣告」和「顯示內容」之外
只有以下這地方有用到 tak 和 check

System.arraycopy(array,k+12,tak,0,dataLength);
System.arraycopy(array,k+12,check,0,dataLength);

當然會一樣了

我要發表回答

立即登入回答