android Ble가 개발한 것들 (3) - Ble 데이터 패키지 처리

4960 단어
안드로이드 블루가 개발한 것들 (하나) 안드로이드 블루가 개발한 것들 (둘) 안드로이드 블루가 개발한 것들 (셋) - 블루 데이터 패키지 처리 안드로이드 블루가 개발한 것들 (넷) - OTA 업그레이드는 최근에 일이 좀 생겨서 더 느려졌다.그럼 데이터 관련 처리부터 끝내자.처음에 데이터를 처리할 때도 오랫동안 생각했는데 그 전에는 바탕이 좋지 않았기 때문에 일시적으로 반응을 하지 못했는데 나중에 납득이 돼서 문제가 쉽게 풀렸다.
프로젝트 실제 문제
우선, 내 프로젝트에서 겪은 실제 문제를 이야기해 봅시다.우리ble설비는 notify를 켜면 자동으로 데이터를 휴대전화에 보냅니다. 이 데이터의 길이는 길고 짧으며 서로 다른 의미를 의미합니다(예를 들어 배터리 전량, 채취한 데이터...).하드웨어의 디자인은 위챗 쪽과 관련된 디자인을 참고했다. ble가 전송하는 데이터의 길이가 제한되어 있기 때문에 ble의 데이터 발송을 네트워크와 유사한 하도급 과정으로 설계했다. 완전한 데이터를 보낼 때 ble설비는 먼저 데이터의 길이, 유형 등 정보를 데이터 헤더에 두었다.그리고 나머지 상세한 데이터 내용까지 최대 길이로 나누어 하나씩 방송해 보낸다.
앱이 해야 할 일은 이 데이터를 모두 받아서 하도급으로 해석하면 된다.그럼 어떻게 나눠요?
해결책
1. BluetoothBuffer 도구 클래스
처음에 저는 Byte Buffer로 실현하려고 했지만 프로젝트에서 사용하기에 특별히 편리하지 않다고 느꼈고 나중에 비슷한 도구류를 썼습니다. (이 도구류의 일부 방법은 시스템api에서 대체할 방법이 있을 것입니다. 자신이 쓰기에 비교적 편리하다고 느꼈기 때문에 시스템api를 사용하지 않았습니다. 여러분도 시스템과 관련된api로 대체할 수 있습니다.)
이 도구 종류는 주로 다음과 같은 몇 가지 방법이 있다. (1) append 버퍼(byte[] 버퍼) 추가 버퍼
public  void appendBuffer(byte[] buffer) {
    if (null == buffer || 0 == buffer.length) return;
    int size = buffer.length + this._rawBufferSize;
    if (size <= this._rawBuffer.length) {
        System.arraycopy(buffer, 0, this._rawBuffer, this._rawBufferSize, buffer.length);
        this._rawBufferSize += buffer.length;
    } else {
        int newSize = this._rawBuffer.length;
        while (newSize <= size) {
            newSize *= 1.5;
        }
        byte[] newRawBuffer = new byte[newSize];
        System.arraycopy(this._rawBuffer, 0, newRawBuffer, 0, this._rawBufferSize);
        this._rawBuffer = newRawBuffer;
        System.arraycopy(buffer, 0, this._rawBuffer, this._rawBufferSize, buffer.length);
        this._rawBufferSize += buffer.length; 
   }
}

(2) getFrontBuffer (int size) 이전 크기 버퍼
public  byte[] getFrontBuffer(int size) {
    if (0 >= size || size > this._rawBufferSize) return null;
    byte[] buffer = new byte[size];
    System.arraycopy(this._rawBuffer, 0, buffer, 0, size);
    return buffer;
}

(3) releaseFrontBuffer (int size) 앞 크기 버퍼 방출
public  void releaseFrontBuffer(int size) {
    if (0 >= size || size > this._rawBufferSize) return;
    System.arraycopy(this._rawBuffer, size, this._rawBuffer, 0, this._rawBufferSize - size);
    this._rawBufferSize -= size;
}

2. 데이터 수신 및 하도급
(1) 수신 데이터의 수신은LiteBle Gatt Callback의 onCharacteristic Changed 리셋 함수에서 수신되기 때문에 하도급 처리도 이 리셋 함수에서 해야 한다.
private void  connect(final BluetoothDevice device){
    liteBluetooth.connect(device, false, new LiteBleGattCallback() {
        ......
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            //  notify  ,             。
            //      
            btBuffer.appendBuffer(characteristic.getValue());
            while (true){
                boolean ret = subPackageOnce(btBuffer);
                if (false == ret) break;
            }
            super.onCharacteristicChanged(gatt, characteristic);
        }
    });
}

보시다시피 먼저 메시지를 받으면 저는 append에 올라가서subPackageOnce () 하도급 함수를 순환해서 하도급이false로 돌아가지 못할 때까지 이 순환을 끝내면 효율도 훨씬 빨라집니다.
(2) 데이터 하도급 데이터 하도급, 즉 데이터를 하나하나 떼어내는 것이다. 하도급을 하려면 데이터의 길이가 도대체 얼마인지 알고 길이가 얼마인 데이터를 떼어내면 된다.그래서 첫 번째 단계는 먼저 데이터 헤더를 얻은 다음에 가방 길이의 pkgSize를 얻은 다음에 pkgSize에 따라 데이터를 벗겨내고 끊임없이 순환하는 것이다...
private boolean subPackageOnce(BluetoothBuffer buffer) {
        if (null == buffer) return false;
        if (buffer.getBufferSize() >= 14) {
            byte[] rawBuffer =  buffer.getBuffer();
            //   
            if (isHead(rawBuffer)){
                pkgSize = byteToInt(rawBuffer[2], rawBuffer[3]);
            }else {
                pkgSize = -1;
                for (int i = 0; i < rawBuffer.length-1; ++i){
                    if (rawBuffer[i] == -2 && rawBuffer[i+1] == 1){
                        buffer.releaseFrontBuffer(i);
                        return true;
                    } 
               }
                return false;
            }
          //    
            if (pkgSize > 0 && pkgSize <= buffer.getBufferSize()) {
                byte[] bufferData = buffer.getFrontBuffer(pkgSize);
                long time = System.currentTimeMillis();
                buffer.releaseFrontBuffer(pkgSize);
                //      
                deal something。。。。。
                return true;
            }
        }
        return false;
    }

이를 통해 알 수 있듯이 데이터 패키지의 길이를 얻고 데이터를 성공적으로 박리한 후에 데이터 분류의 표지 위치에 따라 서로 다른 데이터 처리 방법을 취할 수 있다.예를 들어 채집한 데이터에 대해 나는 이 데이터와 시간 스탬프를 서버에 올릴 것이다.관련 설정 정보를 앱에 선택적으로 표시합니다.
자, ble와 관련된 데이터 하도급 처리는 끝났습니다. 간단하지 않습니까? 이것은 단지 제 처리 방식일 뿐입니다. 만약에 더 좋은 생각이 있거나 잘못된 점이 있으면 지적을 환영하고 서로 교류하고 공부합니다.다음 편에서는 Ble 펌웨어 공중 업그레이드 이야기를 시작하겠습니다. 빨리 더욱.
오리지널 작품은 전재할 필요가 있으면 작가에게 연락하십시오. 그렇지 않으면 법적 책임을 추궁할 것입니다.

좋은 웹페이지 즐겨찾기