BLE文件传输和BLE升级协议

综合技术 2017-05-28

BLE具有距离远,功耗低等优点,广泛应用于智能家居通信,测距,定位,升级管理等方面。

使用BLE对智能家居因件升级。

根据Bluetooth 4.0 BLE部分协议:

BLE中物理层physical layer的传输速率是1Mbps,除了这个外,数据传输速率与包大小、CPU处理时间相关。

包结构:

1.总体结构:

preamble(1 Byte)+Access Address(4 Bytes)+ PDU +CRC(3 Bytes)

preamble = 10101010 or 01010101

Access Address = 0x8e89bedd6

2. 广播包

PDU = Header(2 Bytes)+ Payload (37 Bytes max.)

Header: 1)0000 - connected undirected advertising event 可连接非定向广播事件

2)0001- connected directed advertising event 可连接定向广播事件

3)0010 -non-connected undirected advertising event 不可连接非定向广播事件

4)0011 - response to scan requestform scanner扫描请求响应

5)0101 - connect request by initiator连接请求

6)0110 -connected directed advertisingevent 可发现非定向广播事件

  • 非定向广播包(Undirected advertising packets)

Payload = AdvA (6 Bytes) + AdvData (31 Bytes max.);

// AdvA contains advertiser‘s public addressif TxAdd = 1, or a random address if TxAdd = 0;

// AdvData advertising data;

  • 定向广播包(Directed advertising packets)

Payload = AdvA (6 Bytes) + InitA(6 Bytes) ;

// AdvA contains advertiser‘s public addressif TxAdd = 1, or a random address if TxAdd = 0;

// InitA contains initiator's address if RxAdd = 1,or a random address if RxAdd = 0;

3. 扫描请求及扫描响应

PDU = Header(2 Bytes)+ Payload (37 Bytes max.)

Header: 1)0011 - scan request for further informationfrom advertiser 扫描请求

2)0100- response to scan request from scanner 扫描响应

  • 扫描请求

Payload = ScanA (6 Bytes) + AdvA(6 Bytes) ;

// ScanA contains Scanner's public address if TxAdd= 1, or a random address if TxAdd = 0;

// AdvA contains advertiser‘s public addressif TxAdd = 1, or a random address if TxAdd = 0;

  • 扫描响应

Payload = AdvA(6 Bytes) + ScanRspData(0~31Bytes);

// ScanRspData data from advertiser’s host;

// AdvA contains advertiser‘s public addressif TxAdd = 1, or a random address if TxAdd = 0;

3. 连接请求

PDU = Header(2 Bytes)+ Payload (34 Bytes)

Header:0101 - connect request by initiator

Payload =InitA(6 Bytes)+ AdvA(6bytes)+LLData(22 Bytes)

LLData 包含连接信息,详细结构参考bluetooth 4.0 协议。

4. LL 数据通道及控制包

PDU = Header(2 Bytes)+ Payload (27 Bytes max.)

Header:详细说明参考bluetooth 4.0 协议;

  • LL 数据通道

Payload = 0~27 bytes

  • LL 控制包

Payload = 1~23 Bytes

若只考虑蓝牙设备连接之后,评估数据传输速率

  • 最大包长度:preamble(1 Byte)+ Access Address(4 Bytes)+ PDU(29 Bytes) + CRC(3 Bytes)= 41 Bytes
  • 射频PHY传输速率 1Mbps

则传输有效payload 27字节耗时:41*8/1 = 328us

一个27字节的传输周期 :328 + 150 + 80 + 150 = 708 us,若能持续传输,即传输速度:38KB/s,这样显然功耗不会低,也不符合BLE协议规范,真正的传输速度受连接事件间隔和间隔内能传输数据包数目相关。

如果连接时间间隔设置到7.5ms(协议规定最小值),一个连接事件传输3个包,则传输速率大约是10.8kB/s,一个连接事件能传输几个包与连 接设备密切相关,看到很多CC2540实测数据,时间间隔7.5ms和一个传输时间3个包以上很多都达不到,51内核是其重要原因之一,在
http://processors.wiki.ti.com/index.php/CC2540_Data_Throughput

有5.9KB/s,也有在论坛看到有40ms间隔,2个包,即1.4KB/s成功的案例,以后有时间我再实测下速度。

传输txt和字符文本

/******************************************************************************
 *
 *  Copyright (C) 2013 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  The offset of the second SS. For EEPROM, SS can be at 0x00, 0x100, 0x200, 0x400, 0x800, 0x1000 and 0x2000. 
 *  SS1 is almost always 0x00. So SS2 can be any of the others. Default SS2 we will use is 0x100. You may use any of the others if you want the EEPROM layout to be different.
 *  We will 'allocate' 256 bytes for SS1 (even though it takes up only 40 bytes leaving a 216 byte hole) and set up 
 *  SS2 at 0x100. Since we know that SS2 will be 40 bytes long, we can set up VS at 0x2C0 and of length 0x200 bytes,
 *  DS1 at 0x4C0 and DS2 at 0x84C0 leaving 0x8000 bytes for DS1 and 0x7B40 (about 31.5KB) for DS2.
 *  So, the layout in EEPROM will be as follows with the following offsets:

 *   # 0-----0x100-------0x2C0-----------0x4C0----------------------------0x84C0----------------------X
 *   # |  SS1  |     SS2   |       VS      |              DS1                |          DS2           |
 *   # X----------------------------------------------------------------------------------------------X


 * These are more or less constants of the OTAFU protocol. If you changed these IDs in the FW, use the ones the FW uses.
 **********************************************************************************************************************/

package com.broadcom.app.ota_sample;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Arrays;
import java.util.UUID;
import android.util.Log;
import android.bluetooth.BluetoothGattCharacteristic;


public class B20732_OtaService {
	private static final String TAG = "OTA_UPdate";

	private static final int maxOtaDataSize = 16;               // That is the max size of data in the OTA PDU. 
	private short maxSSLen = 0x28;                              // The static section is always 40 bytes long.
	private short secondSSOffset = 0x100;   
	private short firstSSDsOffset = 0x4C0;

	
	private static final int eeprom_address = 0xFF0004C0;
	private int offset = 0, pack_id = 0, patch_size = 0;
	
	private String burnimg_path;   // The path of the burn image that will be generated when updating.
	
	private GattAppService mGattService = null;
    private BluetoothGattCharacteristic mUpdateValueCharact = null;
    private BluetoothGattCharacteristic mUpdateResultCharact = null;
	
	private BufferedReader  image_file_reader = null;
	private short last_length = 0;

	private static final byte ID_ENABLE_OTAFU = 0x70;
	private static final byte ID_SETUP_READ   = 0x71;
	private static final byte ID_READ         = 0x72;
	private static final byte ID_ERASE        = 0x73;
	private static final byte ID_WRITE        = 0x74;
	private static final byte ID_LAUNCH       = 0x75;
	
	public static final short UPDATE_STATUS_CONTINUE = 0x00;
	public static final short UPDATE_STATUS_COMPLETE_SUCCESS  = 0x01;
	public static final short UPDATE_STATUS_ENABLE_FAIL = 0x02;
	public static final short UPDATE_STATUS_WRITE_FAIL = 0x03;
	public static final short UPDATE_STATUS_LAUNCH_FAIL = 0x04;

	
    public static final UUID OTA_SERVICE_UUID          = UUID.fromString("0000E010-0000-1000-8000-00805f9b34fb");
    public static final UUID OTA_WRITE_CHARACTER_UUID  = UUID.fromString("0000E011-0000-1000-8000-00805f9b34fb");
    public static final UUID OTA_RESULT_CHARACTER_UUID = UUID.fromString("0000E012-0000-1000-8000-00805f9b34fb");
    
    private boolean data_send_error = false;
    private short fail_packet_num = 0;
    private short[] array_fail_packet;
	
	
	
	public B20732_OtaService( GattAppService Service, BluetoothGattCharacteristic Characteristic )
	{
		mGattService = Service;
		mUpdateValueCharact = Characteristic;

		if( mGattService != null  )
		{
            mUpdateResultCharact = mGattService.getCharacteristic( OTA_SERVICE_UUID, OTA_RESULT_CHARACTER_UUID );
        }
		
		array_fail_packet = new short[2000];
		for (short i=0;i 0 )
		    	data = new byte[length];
		    
		    operation_id = 0;
		    operation_result = 0;
		    len = length;
		    checksum = 0;
		}
		
		private String ByteArrayToDataString( byte[] data )
		{
			String out = null;
			
			if( data != null )
		        out = Arrays.toString( data );
			
			return out;
		}

		public byte Checksum()
		{
		    int tst_sum = 0;
		    int i = 0;

		    tst_sum = operation_id + operation_result + (len&0xFF) + (( len>>8)&0xFF);

		    if( len > 0 )
		    {
		        for( i=0;i<len;i++) {="" tst_sum="" +="data[i];" }="" return="" (byte)="" ((~tst_sum+1)&0xff);="" *##############################################################="" #="" print="" a="" report="" (the="" hash="" returned="" by="" rxreport="" getreport)="" ##############################################################*="" public="" void="" printreport(="" )="" log.v(tag,="" "device="" otafu="" update="" result:="" operation=" + " result=" + operation_result + operation_id + " ,="" len=" + len + " ,data="+ ByteArrayToDataString(data) +" checksum=" + checksum + " n");="" receive="" an="" report,="" decode="" it="" into="" private="" otareport_t="" rxupdatereport(="" byte[]="" data="" report;="" short="" i="0;" length="(short)(((0x000000FF" &="" ((int)data[3]))< 0 )
	    {
	    	for( i=0;i<length;i++) 64="" {="" report.data[i]="data[4+i];" }="" and="" ensure="" that="" the="" received="" checksum="=" computed="" report.checksum="data[length+4];" if="" (="" report.checksum()="" !="data[length+4]" )="" log.v(="" tag,="" "report="" is="" inconflict="" n");="" report.printreport();="" return="" report;="" private="" boolean="" sendacldata(="" byte[]="" data="" result="false;" if(="" (mgattservice="" &&="" (mupdatevaluecharact="" mupdatevaluecharact.setvalue(data)="" mupdatevaluecharact.setwritetype(="" bluetoothgattcharacteristic.write_type_no_response="" );="" result;="" openimagefile(="" string="" filepath="" ret="false;" try="" file="" patch_file="new" file(filepath="" image_file_reader="new" bufferedreader(new="" filereader(="" ));="" null="" patch_size="(int)" patch_file.length();="" catch="" (exception="" e)="" e.printstacktrace();="" false;="" ret;="" void="" closeimagefile(="" image_file_reader.close();="" int="" readimagedata(="" write_buf,="" length="" read_len="0;" read_str;="" tmp_buf="new" byte[64];="" i,j;="" ((image_file_reader="" write_buf="" ))="" read_str="image_file_reader.readLine();" if((="" closeimagefile();="" else="" log.v(tag,="" "read="" patch:="" "="" +="" "n");="" read_str.getbytes().length=""  '9')
	                    	 {
	                    	      write_buf[j] = (byte) ((tmp_buf[i] - 'a' + 0xA)<<4); }="" else="" {="" write_buf[j]="(byte)" ((tmp_buf[i]="" -="" '0')< '9')
	                    	 {
	                    	      write_buf[j] += tmp_buf[i+1] - 'a' + 0xA;
	                    	      
	                    	 }
	                    	 else
	                    		 write_buf[j] += tmp_buf[i+1] - '0';
	                     }
	                     
	                     read_len = j;
	                 }
	                 offset += read_str.getBytes().length;
	             }
			}  
			catch (Exception e) {
                e.printStackTrace();
            }
	         
		}
		
		return read_len;
	}
	
	/*##############################################################
	# Compute and return a checksum
	##############################################################*/
	private byte Checksum( short id, int addr, short len, byte[] data)
	{
	    int sum = (int)id;
	    short i = 0;
	    
	    sum += addr & 0xFF;
	    sum += (addr>>8) & 0xFF;
	    sum += (addr>>16) & 0xFF;
	    sum += (addr>>24) & 0xFF;

	    sum += len & 0xFF;
	    sum += (len>>8) & 0xFF;

	    if( (len > 0 ) && (data != null))
	    {
		    for(i=0; i >8)&0xFF);
		sreportbytes[3] = (byte) ((addr>>16)&0xFF);
		sreportbytes[4] = (byte) ((addr>>24)&0xFF);
		
		sreportbytes[5] = (byte) (len&0xFF);
		sreportbytes[6] = (byte) (len>>8);
		
		// Put the report bytes together
		if( (len > 0 ) && ( data != null ) )
		{
			short i = 0;
			for( i=0;i 4 )
				{
				    pdu_len = tmp_buffer[0];
				    pdu_offset = (short)(((0x000000FF & ((int)tmp_buffer[1]))<= 0x04C0 )
			        	    pdu_found = true;
			        } 
			        
				}
				else
					break;
			}
			while( !pdu_found );
		}
		
		if( !complete )
		{
			if( pdu_found )
			{
				 int sum = 0;
				 if( pdu_len > maxOtaDataSize  ) pdu_len = 16;
			     data = new byte[pdu_len+4];
			     //System.arraycopy(tmp_buffer.,  0,  data,  0,  pdu_len );
			     //data = Arrays.copyOfRange( tmp_buffer,  4, pdu_len + 4);
			     //WriteMem( eeprom_address + offset, data );
			     //offset += pdu_len;
			     data[0] = ID_WRITE;
			     data[1] = pdu_len;
			     data[2] = (byte)pack_id;
			     for ( int i=0;i<pdu_len;i++) 0="" {="" data[i+3]="tmp_buffer[i+4];" }="" for="" (="" int="" j="0;j<pdu_len+3;" j++)="" sum="" +="data[j];" data[pdu_len+3]="(byte)(~sum+1);" sendacldata(data);="" pack_id++;="" return="" complete;="" public="" boolean="" getlastupdateresult(="" )="" result="false;" if="" mupdateresultcharact="" !="null" );="" result;="" short="" otahandlewriteresult(="" byte[]="" value,="" status="" write_failed="false;" rxupdatereport(="" value="" switch(="" value[0])="" case="" id_enable_otafu:="" if(="" else="" writeimage(false);="" break;="" id_write:="" data_send_error="true;" !data_send_error)="" writeimage(="" ))="" launch(0)="" getlastupdateresult())="" getlastupdateresult();="" id_launch:="" default:="" otahandleupdateresult(="" length="0;" value[1]="" &="" ((int)value[6]))< 0 ) && ( offset > 0 ) && ( patch_size >= offset ) )
	    {
	    	percent = (byte)((float)offset*100/patch_size);
	    }
	    
	    Log.v( TAG, "Update Progress: " + percent );
	    return percent;
	}

}

传输BIN和二进制文件

/******************************************************************************
 *
 *  Copyright (C) 2013 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  The offset of the second SS. For EEPROM, SS can be at 0x00, 0x100, 0x200, 0x400, 0x800, 0x1000 and 0x2000. 
 *  SS1 is almost always 0x00. So SS2 can be any of the others. Default SS2 we will use is 0x100. You may use any of the others if you want the EEPROM layout to be different.
 *  We will 'allocate' 256 bytes for SS1 (even though it takes up only 40 bytes leaving a 216 byte hole) and set up 
 *  SS2 at 0x100. Since we know that SS2 will be 40 bytes long, we can set up VS at 0x2C0 and of length 0x200 bytes,
 *  DS1 at 0x4C0 and DS2 at 0x84C0 leaving 0x8000 bytes for DS1 and 0x7B40 (about 31.5KB) for DS2.
 *  So, the layout in EEPROM will be as follows with the following offsets:

 *   # 0-----0x100-------0x2C0-----------0x4C0----------------------------0x84C0----------------------X
 *   # |  SS1  |     SS2   |       VS      |              DS1                |          DS2           |
 *   # X----------------------------------------------------------------------------------------------X


 * These are more or less constants of the OTAFU protocol. If you changed these IDs in the FW, use the ones the FW uses.
 **********************************************************************************************************************/

package com.broadcom.app.ota_sample;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.UUID;

import android.bluetooth.BluetoothGattCharacteristic;
import android.os.Environment;
import android.util.Log;

public class B20732_OtaServiceBin {
	private static final String TAG = "OTA_UPdate";

	private static final int maxOtaDataSize = 16; // That is the max size of
													// data in the OTA PDU.
	private short maxSSLen = 0x28; // The static section is always 40 bytes
									// long.
	private short secondSSOffset = 0x100;
	private short firstSSDsOffset = 0x4C0;

	private static final int eeprom_address = 0xFF0004C0;
	// private int offset = 0, pack_id = 0, patch_size = 0;

	private String burnimg_path; // The path of the burn image that will be
									// generated when updating.

	private GattAppService mGattService = null;
	private BluetoothGattCharacteristic mUpdateValueCharact = null;
	private BluetoothGattCharacteristic mUpdateResultCharact = null;

	private BufferedReader image_file_reader = null;
	private short last_length = 0;

	private static final byte ID_ENABLE_OTAFU = 0x70;
	private static final byte ID_SETUP_READ = 0x71;
	private static final byte ID_READ = 0x72;
	private static final byte ID_ERASE = 0x73;
	private static final byte ID_WRITE = 0x74;
	private static final byte ID_LAUNCH = 0x75;

	public static final short UPDATE_STATUS_CONTINUE = 0x00;
	public static final short UPDATE_STATUS_COMPLETE_SUCCESS = 0x01;
	public static final short UPDATE_STATUS_ENABLE_FAIL = 0x02;
	public static final short UPDATE_STATUS_WRITE_FAIL = 0x03;
	public static final short UPDATE_STATUS_LAUNCH_FAIL = 0x04;

	public static final UUID OTA_SERVICE_UUID = UUID
			.fromString("0000E010-0000-1000-8000-00805f9b34fb");
	public static final UUID OTA_WRITE_CHARACTER_UUID = UUID
			.fromString("0000E011-0000-1000-8000-00805f9b34fb");
	public static final UUID OTA_RESULT_CHARACTER_UUID = UUID
			.fromString("0000E012-0000-1000-8000-00805f9b34fb");

	private boolean data_send_error = false;
	private short fail_packet_num = 0;
	private short[] array_fail_packet;

	// jia add
	private DataInputStream dis = null;
	private FileInputStream fin = null;
	private DataOutputStream dos = null;
	private long offset = 0, pack_id = 0, patch_size = 0;
	private byte read_max_buf = maxOtaDataSize;

	// private long new_offset = 0, new_pack_id = 0, new_patch_size = 0;

	public B20732_OtaServiceBin(GattAppService Service,
			BluetoothGattCharacteristic Characteristic) {
		mGattService = Service;
		mUpdateValueCharact = Characteristic;

		if (mGattService != null) {
			mUpdateResultCharact = mGattService.getCharacteristic(
					OTA_SERVICE_UUID, OTA_RESULT_CHARACTER_UUID);
		}

		array_fail_packet = new short[2000];
		for (short i = 0; i  0)
				data = new byte[length];

			operation_id = 0;
			operation_result = 0;
			len = length;
			checksum = 0;
		}

		private String ByteArrayToDataString(byte[] data) {
			String out = null;

			if (data != null)
				out = Arrays.toString(data);

			return out;
		}

		public byte Checksum() {
			int tst_sum = 0;
			int i = 0;

			tst_sum = operation_id + operation_result + (len & 0xFF)
					+ ((len >> 8) & 0xFF);

			if (len > 0) {
				for (i = 0; i < len; i++) {
					tst_sum += data[i];
				}
			}

			return (byte) ((~tst_sum + 1) & 0xFF);
		}

		/*
		 * ############################################################## #
		 * Print a report (the hash returned by RxReport/GetReport)
		 * ##############################################################
		 */
		public void PrintReport() {
			Log.v(TAG, "Device OTAFU Update Result: Operation = " + "Result = "
					+ operation_result + operation_id + ", len = " + len
					+ ",data = " + ByteArrayToDataString(data)
					+ ", checksum = " + checksum + "n");
		}
	}
 
	/*
	 * ############################################################## # Receive
	 * an OTAFU report, decode it into returned hash
	 * ##############################################################
	 */
	private OtaReport_T RxUpdateReport(byte[] data) {
		OtaReport_T report;
		short i = 0;

		short length = (short) (((0x000000FF & ((int) data[3])) < 0) {
			for (i = 0; i < length; i++) {
				report.data[i] = data[4 + i];
			}

			// And ensure that the received checksum == computed checksum
			report.checksum = data[length + 4];
			if (report.Checksum() != data[length + 4]) {
				Log.v(TAG, "Report is inconflict n");
			}
		}

		report.PrintReport();

		return report;
	}

	private Boolean SendACLData(byte[] data) {
		Boolean result = false;

		if ((mGattService != null) && (mUpdateValueCharact != null)) {

			if (mUpdateValueCharact.setValue(data)) {
				// mUpdateValueCharact.setWriteType(
				// BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE );
				result = mGattService.writeCharacteristic(mUpdateValueCharact);
			}
		}

		return result;
	}

	/*
	 * private Boolean OpenImageFile( String FilePath ) { Boolean ret = false;
	 * 
	 * try { File patch_file = new File(FilePath ); if( patch_file != null ) {
	 * image_file_reader = new BufferedReader(new FileReader( patch_file )); if(
	 * null != image_file_reader ) { ret = true; patch_size = (int)
	 * patch_file.length(); }
	 * 
	 * } } catch (Exception e) { e.printStackTrace();
	 * 
	 * return false; }
	 * 
	 * return ret; }
	 */
	private Boolean OpenBinFile(String FilePath) {
		Boolean ret = false;

		try {
			// File patch_file = new File(FilePath );
			Log.i("AAAAA", "OpenBinFile FilePath = "+FilePath);
			fin = new FileInputStream(FilePath);
			dis = new DataInputStream(fin);
			if (fin != null) {
				if (dis != null) {
					ret = true;
					patch_size = fin.getChannel().size();
					Log.i("AAAAA", "OpenBinFile patch_size = "+patch_size);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();

			return false;
		}

		return ret;
	}

	/*
	 * private void CloseImageFile( ) { try { if( image_file_reader != null) {
	 * image_file_reader.close(); image_file_reader = null; } } catch (Exception
	 * e) { e.printStackTrace(); } }
	 */
	private void CloseBinFile() {
		try {
			if (dis != null) {
				dis.close();
				fin.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/*
	 * private int ReadImageData( byte[] write_buf, int length ) { int read_len
	 * = 0; String read_str; byte[] tmp_buf = new byte[64]; int i,j;
	 * 
	 * if ((image_file_reader != null) && ( write_buf != null )) { try {
	 * read_str = image_file_reader.readLine();
	 * 
	 * if(( read_str == null )) { CloseImageFile(); } else { Log.v(TAG,
	 * "read patch: " + read_str + "n"); if( read_str.getBytes().length < 64 )
	 * { System.arraycopy(read_str.toLowerCase().getBytes(), 0, tmp_buf, 0,
	 * read_str.getBytes().length ); read_len = read_str.getBytes().length;
	 * 
	 * for( i=1,j=0;i  '9') {
	 * write_buf[j] = (byte) ((tmp_buf[i] - 'a' + 0xA)<<4); *="" }="" else="" {="" write_buf[j]="(byte)" ((tmp_buf[i]="" -="" '0')< '9') { write_buf[j] += tmp_buf[i+1] - 'a' + 0xA;
	 * 
	 * } else write_buf[j] += tmp_buf[i+1] - '0'; }
	 * 
	 * read_len = j; } offset += read_str.getBytes().length; } } catch
	 * (Exception e) { e.printStackTrace(); }
	 * 
	 * }
	 * 
	 * return read_len; }
	 */
	private int ReadBinData(byte[] write_buf) {
		int read_len = 0;
		byte[] tmp_buf = new byte[this.read_max_buf + 4];
		boolean isFinish = false;

		if ((dis != null) && (write_buf != null)) {
			try {
				if ((patch_size - offset) >= this.read_max_buf) {
					read_len = this.read_max_buf;
					tmp_buf[3] = (byte) 0x00;
				} else if ((patch_size - offset) > 0) {
					read_len = (int) (patch_size - offset);
					tmp_buf[3] = (byte) 0x00;
					isFinish = true;
				} else {
					tmp_buf[3] = (byte) 0x01;
				}
				tmp_buf[0] = (byte) read_len;
				tmp_buf[1] = (byte) 0xff;
				tmp_buf[2] = (byte) 0xff;

				for (int i = 0; i > 8) & 0xFF;
		sum += (addr >> 16) & 0xFF;
		sum += (addr >> 24) & 0xFF;

		sum += len & 0xFF;
		sum += (len >> 8) & 0xFF;

		if ((len > 0) && (data != null)) {
			for (i = 0; i > 8) & 0xFF);
		sreportbytes[3] = (byte) ((addr >> 16) & 0xFF);
		sreportbytes[4] = (byte) ((addr >> 24) & 0xFF);

		sreportbytes[5] = (byte) (len & 0xFF);
		sreportbytes[6] = (byte) (len >> 8);

		// Put the report bytes together
		if ((len > 0) && (data != null)) {
			short i = 0;
			for (i = 0; i  4 )
	 * { pdu_len = tmp_buffer[0]; pdu_offset = (short)(((0x000000FF &
	 * ((int)tmp_buffer[1]))<= 0x04C0 )
	 * pdu_found = true; }
	 * 
	 * } else break; } while( !pdu_found ); }
	 * 
	 * if( !complete ) { if( pdu_found ) { int sum = 0; if( pdu_len >
	 * maxOtaDataSize ) { pdu_len = maxOtaDataSize; } data = new
	 * byte[pdu_len+4]; //System.arraycopy(tmp_buffer., 0, data, 0, pdu_len );
	 * //data = Arrays.copyOfRange( tmp_buffer, 4, pdu_len + 4); //WriteMem(
	 * eeprom_address + offset, data ); //offset += pdu_len; data[0] = ID_WRITE;
	 * data[1] = pdu_len; data[2] = (byte)pack_id; for ( int i=0;i<pdu_len;i++) *="" {="" data[i+3]="tmp_buffer[i+4];" }="" for="" (="" int="" j="0;j= 4) {
					pdu_len = tmp_buffer[0];
					pdu_offset = (short) (((0x000000FF & ((int) tmp_buffer[1])) < read_max_buf) {
					pdu_len = read_max_buf;
				}
				data = new byte[pdu_len + 4];

				// offset += pdu_len;
				data[0] = ID_WRITE;
				data[1] = pdu_len;
				data[2] = (byte) pack_id;
				for (int i = 0; i < pdu_len; i++) {
					data[i + 3] = tmp_buffer[i + 4];
				}
				for (int j = 0; j < pdu_len + 3; j++) {
					sum += data[j];
				}

				data[pdu_len + 3] = (byte) (~sum + 1);
				SendACLData(data);
				pack_id++;
				Log.i("AAAAA", "ReadBinData pack_id="+pack_id);
			}
		}
		return complete;
	}

	public Boolean GetLastUpdateResult() {
		Boolean result = false;

		if (mUpdateResultCharact != null) {
			result = mGattService.readCharacteristic(mUpdateResultCharact);
		}

		return result;
	}

	public short OtaHandleWriteResult(byte[] value, int status) {
		short result = UPDATE_STATUS_CONTINUE;
		Boolean write_failed = false;

		// RxUpdateReport( value );

		switch (value[0]) {
		case ID_ENABLE_OTAFU:
			if (0 != status) {
				result = UPDATE_STATUS_ENABLE_FAIL;
			} else {
				// GetLastUpdateResult( );
				// WriteImage(false);
				// jia add
				WriteBin(false);
			}

			break;

		case ID_WRITE:
			if (0 != status) {
				write_failed = true;
				data_send_error = true;
			}

			if (!data_send_error) {

				// if( WriteImage( write_failed ))
				// jia add
				if (WriteBin(write_failed)) {
					// if( Launch(0) )
					// if( GetLastUpdateResult())
					// jia add
					if (LaunchBin(0)) {
						result = UPDATE_STATUS_CONTINUE;
						// GetLastUpdateResult();
					}
				}
			} else
				result = UPDATE_STATUS_LAUNCH_FAIL;

			break;

		case ID_LAUNCH:
			if (0 != status) {
				result = UPDATE_STATUS_LAUNCH_FAIL;
			} else {
				result = UPDATE_STATUS_CONTINUE;
			}
			break;

		default:
			break;
		}

		return result;
	}

	public short OtaHandleUpdateResult(byte[] value) {
		short result = UPDATE_STATUS_CONTINUE;
		Boolean write_failed = false;
		short length = 0;

		RxUpdateReport(value);

		switch (value[0]) {
		case ID_ENABLE_OTAFU:
			if (0 == value[1]) {
				result = UPDATE_STATUS_ENABLE_FAIL;
			}
			// else
			// WriteImage(false);

			break;

		case ID_WRITE:
			if (0 == value[1]) {
				write_failed = true;
			} else {

			}

			length = (short) (((0x000000FF & ((int) value[6])) < 0) && (offset > 0) && (patch_size >= offset)) {
			percent = (byte) ((float) offset * 100 / patch_size);
		}

		Log.v(TAG, "Update Progress: " + percent);
		return percent;
	}

}

您可能感兴趣的

发力新零售,收购全食超市之后!亚马逊下一步或将进入智能家居... 今年6月,亚马逊宣布将以137亿美元的价格收购全食超市。就在这一瞬间,竞争对手克罗格、沃尔玛和塔吉特的市值下降了220亿美元。 近日,亚马逊宣布与西尔斯合作,在亚马逊网站上出售Kenmore的电器。同样,家得宝和劳氏的股价暴跌,市值蒸发了120亿美元。 家电行业在很大程度上不受亚马逊的支配。...
速途研究院:2018年Q1国内智能家居行业研究报告... 智能家居是一个总括的概念,智能家居包括与生活相关的多种智能产品,是以住宅为平台,利用综合布线技术、网络通信技术、安全防范技术、自动控制技术、音视频技术将家居生活有关的设施集成,构建智能化的管理系统。 智能家居与传统的普通家居相比更加的环保节能,在安全性和便捷性上也有着明显的优势。近年来多家互联网巨...
Fujifilm X-E3 woos smartphone users with touchscre... Canon and Nikon recently announced new digital cameras that were clearly aimed at the smartphone generation. Their spiel was to entice them with featu...
高保真德生V5网络收音机,高颜值秒杀艺术品... 高保真德生V5网络收音机,高颜值秒杀艺术品 刘恪宜 20年的折腾经验和深度体验,在音质感受、色彩表现领域有着独特的见解,以散文式的描写体现数码产品之美见长 10分钟前 德生记言 我想我再也写...
Android may soon show remaining Bluetooth battery ... Wireless headphones have improved a great deal over the years, which is a good thing considering so many companies have ditched the 3.5mm headphone j...