let tempTimer = 0;
let client = null;
let util = null;
let mDeviceEvent = null;
let crypto = null;
let md5 = null;
let aesjs = null;
const timeOut = 20; //超时时间
let mac_id;
var timeId = "";
let sequenceControl = 0;
let sequenceNumber = -1;
let self = {
	data: {
		deviceId: null,
		isConnected: false,
		failure: false,
		value: 0,
		desc: "请耐心等待...",
		isChecksum: true,
		isEncrypt: true,
		flagEnd: false,
		defaultData: 1,
		ssidType: 2,
		passwordType: 3,
		meshIdType: 3,
		deviceId: "",
		ssid: "",
		uuid: "",
		serviceId: "",
		password: "",
		meshId: "",
		processList: [],
		result: [],
		service_uuid: "000000FF-0000-1000-8000-00805F9B34FB",
		characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
		characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
		customData: null,
		md5Key: 0
	}
};

function Utf8ArrayToStr(buffer) {
	var out, i, len, c;
	var char2, char3;
	var array = new Uint8Array(buffer)
	// console.log('array',array);
	// console.log('array.ArrayBuffer',array.ArrayBuffer);
	// console.log('array[[Uint8Array]]',array.ArrayBuffer);
	out = "";
	len = array.length;
	i = 0;
	// console.log('len',len);
	while (i < len) {
		c = array[i++];
		switch (c >> 4) {
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
				// 0xxxxxxx
				out += String.fromCharCode(c);
				break;
			case 12:
			case 13:
				// 110x xxxx 10xx xxxx
				char2 = array[i++];
				out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
				break;
			case 14:
				// 1110 xxxx 10xx xxxx 10xx xxxx
				char2 = array[i++];
				char3 = array[i++];
				out += String.fromCharCode(((c & 0x0F) << 12) |
					((char2 & 0x3F) << 6) |
					((char3 & 0x3F) << 0));
				break;
		}
	}
	// console.log('out',out);
	return out;
}






function string2buffer1(str) {
	// 首先将字符串转为16进制
	let val = ""
	for (let i = 0; i < str.length; i++) {
		if (val === '') {
			val = str.charCodeAt(i).toString(16)
		} else {
			val += ',' + str.charCodeAt(i).toString(16)
		}
	}
	// 将16进制转化为ArrayBuffer
	return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
		return parseInt(h, 16)
	})).buffer
}

function string2buffer(str) {
	var bytes = new Array();
	for (var i = 0; i < str.length; i++) {
		var c = str.charCodeAt(i);
		var s = parseInt(c).toString(2);
		if (c >= parseInt('000080', 16) && c <= parseInt('0007FF', 16)) {
			var af = '';
			for (var j = 0; j < (11 - s.length); j++) {
				af += '0';
			}
			af += s;
			var n1 = parseInt('110' + af.substring(0, 5), 2);
			var n2 = parseInt('110' + af.substring(5), 2);
			if (n1 > 127) n1 -= 256;
			if (n2 > 127) n2 -= 256;
			bytes.push(n1);
			bytes.push(n2);
		} else if (c >= parseInt('000800', 16) && c <= parseInt('00FFFF', 16)) {
			var af = '';
			for (var j = 0; j < (16 - s.length); j++) {
				af += '0';
			}
			af += s;
			var n1 = parseInt('1110' + af.substring(0, 4), 2);
			var n2 = parseInt('10' + af.substring(4, 10), 2);
			var n3 = parseInt('10' + af.substring(10), 2);
			if (n1 > 127) n1 -= 256;
			if (n2 > 127) n2 -= 256;
			if (n3 > 127) n3 -= 256;
			bytes.push(n1);
			bytes.push(n2);
			bytes.push(n3);
		} else if (c >= parseInt('010000', 16) && c <= parseInt('10FFFF', 16)) {
			var af = '';
			for (var j = 0; j < (21 - s.length); j++) {
				af += '0';
			}
			af += s;
			var n1 = parseInt('11110' + af.substring(0, 3), 2);
			var n2 = parseInt('10' + af.substring(3, 9), 2);
			var n3 = parseInt('10' + af.substring(9, 15), 2);
			var n4 = parseInt('10' + af.substring(15), 2);
			if (n1 > 127) n1 -= 256;
			if (n2 > 127) n2 -= 256;
			if (n3 > 127) n3 -= 256;
			if (n4 > 127) n4 -= 256;
			bytes.push(n1);
			bytes.push(n2);
			bytes.push(n3);
			bytes.push(n4);
		} else {
			bytes.push(c & 0xff);
		}
	}

	let array = [];
	for (let i = 0; i < bytes.length; i++) {
		array[i] = bytes[i]
	}
	let array_int8 = Uint8Array.from(array)

	return array_int8.buffer;
}
function buf2hex(buffer) {
	return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}

function buf2string(buffer) {
	var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x);
	var str = '';

	for (var i = 0; i < arr.length; i++) {
		str += String.fromCharCode(arr[i]);
	}

	return str;
}

function getSsids(str) {
	var list = [],
		strs = str.split(":");

	for (var i = 0; i < strs.length; i++) {
		list.push(parseInt(strs[i], 16));
	}

	return list;
}

function getCharCodeat(str) {
	var list = [];

	for (var i = 0; i < str.length; i++) {
		list.push(str.charCodeAt(i));
	}

	return list;
} //判断返回的数据是否加密


function isEncrypt(fragNum, list, md5Key) {
	var checksum = [],
		checkData = [];

	if (fragNum[7] == "1") {
		//返回数据加密
		if (fragNum[6] == "1") {
			var len = list.length - 2;
			list = list.slice(0, len);
		}

		var iv = this.generateAESIV(parseInt(list[2], 16));

		if (fragNum[3] == "0") {
			//未分包
			list = list.slice(4);
			self.data.flagEnd = true;
		} else {
			//分包
			list = list.slice(6);
		}
	} else {
		//返回数据未加密
		if (fragNum[6] == "1") {
			var len = list.length - 2;
			list = list.slice(0, len);
		}

		if (fragNum[3] == "0") {
			//未分包
			list = list.slice(4);
			self.data.flagEnd = true;
		} else {
			//分包
			list = list.slice(6);
		}
	}

	return list;
}

function getSecret(deviceId, serviceId, characteristicId, client, kBytes, pBytes, gBytes, data) {
	var obj = [],
		frameControl = 0;
	sequenceControl = parseInt(sequenceControl) + 1;

	if (!util._isEmpty(data)) {
		obj = util.isSubcontractor(data, true, sequenceControl);
		frameControl = util.getFrameCTRLValue(false, true, util.DIRECTION_OUTPUT, false, obj.flag);
	} else {
		data = [];
		data.push(util.NEG_SET_SEC_ALL_DATA);
		var pLength = pBytes.length;
		var pLen1 = pLength >> 8 & 0xff;
		var pLen2 = pLength & 0xff;
		data.push(pLen1);
		data.push(pLen2);
		data = data.concat(pBytes);
		var gLength = gBytes.length;
		var gLen1 = gLength >> 8 & 0xff;
		var gLen2 = gLength & 0xff;
		data.push(gLen1);
		data.push(gLen2);
		data = data.concat(gBytes);
		var kLength = kBytes.length;
		var kLen1 = kLength >> 8 & 0xff;
		var kLen2 = kLength & 0xff;
		data.push(kLen1);
		data.push(kLen2);
		data = data.concat(kBytes);
		obj = util.isSubcontractor(data, true, sequenceControl);
		frameControl = util.getFrameCTRLValue(false, true, util.DIRECTION_OUTPUT, false, obj.flag);
	}

	var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_NEG, frameControl, sequenceControl, obj.len, obj.lenData);
	var typedArray = new Uint8Array(value);
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: typedArray.buffer,
		success: function (res) {
			if (obj.flag) {
				getSecret(deviceId, serviceId, characteristicId, client, kBytes, pBytes, gBytes, obj.laveData);
			}
		},
		fail: function (res) { }
	});
}

function writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, data) {
	// var obj = {},
	// 	frameControl = 0;
	// sequenceControl = parseInt(sequenceControl) + 1;

	// if (!util._isEmpty(data)) {
	// 	obj = util.isSubcontractor(data, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
	// 	frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	// } else {
	// 	obj = util.isSubcontractor([self.data.defaultData], self.data.isChecksum, sequenceControl, true);
	// 	frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	// }

	// var defaultData = util.encrypt(aesjs, self.data.md5Key, sequenceControl, obj.lenData, true);
	// var value = util.writeData(util.PACKAGE_CONTROL_VALUE, util.SUBTYPE_WIFI_MODEl, frameControl, sequenceControl, obj.len,
	// 	defaultData);
	// var typedArray = new Uint8Array(value);
	console.log('data.ssid', data.ssid)
	console.log('data.password', data.password)
	var ssid = string2buffer(data.ssid)
	var password = string2buffer(data.password)
	console.log('ssid', ssid)
	console.log('password', password)
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: ssid,
		success: function (res) {
			uni.writeBLECharacteristicValue({
				deviceId: deviceId,
				serviceId: serviceId,
				characteristicId: characteristicId,
				value: password,
				success: function (res) {
					// if (obj.flag) {
					// 	writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, obj.laveData);
					// } else {
					// 	writeRouterSsid(deviceId, serviceId, characteristicId, null);
					// }
				},
				fail: function (res) { }
			});


			// if (obj.flag) {
			// 	writeDeviceRouterInfoStart(deviceId, serviceId, characteristicId, obj.laveData);
			// } else {
			// 	writeRouterSsid(deviceId, serviceId, characteristicId, null);
			// }
		},
		fail: function (res) { }
	});
}
// #define CMD_IAP_PROM 0x80   // IAP编程命令
// #define CMD_IAP_ERASE 0x81  // IAP擦除命令
// #define CMD_IAP_VERIFY 0x82 // IAP校验命令
// #define CMD_IAP_END 0x83    // IAP结束标志
// #define CMD_IAP_INFO 0x84   // IAP获取设备信息
// #define CMD_IAP_SUM 0x85    // 校验和
// #define CMD_OTHER 0xee      // 校验和

const CMD_IAP_PROM = 0x80;
const CMD_IAP_ERASE = 0x81;
const CMD_IAP_VERIFY = 0x82;
const CMD_IAP_END = 0x83;
const CMD_IAP_INFO = 0x84;
const CMD_IAP_SUM = 0x85;

function write_cmd_erase(deviceId, serviceId, characteristicId, data) {

	var value = util.write_ota_erase(CMD_IAP_ERASE, 4, 0, 0);
	var typedArray = new Uint8Array(value);
	console.log("送擦除数据")
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: typedArray.buffer,
		// value: buffer,
		success: function (res) {
			console.log("送数据成功")
		},
		fail: function (res) { //console.log(257);
		}
	});
}



function send_ota_data(deviceId, serviceId, characteristicId, data) {
	return new Promise(function (resolve, reject) {
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: serviceId,
			characteristicId: characteristicId,
			value: data,
			// value: buffer,
			success: function (res) {
				console.log("送数据成功")
				let obj = {
					'type': mDeviceEvent
						.XBLUFI_TYPE
						.TYPE_RECIEVE_MY_DATA,
					'result': true,
					'data': 99
				};
				mDeviceEvent
					.notifyDeviceMsgEvent(
						obj
					);

				resolve(res)
			},
			fail: function (res) {
				console.log("送数据失败")
				reject(res)
			}
		});
	});
}

function send_ota_data_num(deviceId, serviceId, characteristicId, data, num) {
	return new Promise(function (resolve, reject) {
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: serviceId,
			characteristicId: characteristicId,
			value: data,
			// writeType:'writeNoResponse',
			// value: buffer,
			success: function (res) {
				// console.log("送数据成功")
				// let obj = {
				// 	'type': mDeviceEvent
				// 		.XBLUFI_TYPE
				// 		.TYPE_RECIEVE_MY_DATA,
				// 	'result': true,
				// 	'data': num
				// };
				// mDeviceEvent
				// 	.notifyDeviceMsgEvent(
				// 		obj
				// 	);
				resolve(res)
			},
			fail: function (res) {
				console.log("送数据失败")
				reject(res)
			}
		});
	});
}

function send_end_data(deviceId, serviceId, characteristicId, data) {
	return new Promise(function (resolve, reject) {
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: serviceId,
			characteristicId: characteristicId,
			value: data,
			// value: buffer,
			success: function (res) {
				console.log("送数据成功")
				let obj = {
					'type': mDeviceEvent
						.XBLUFI_TYPE
						.TYPE_RECIEVE_MY_DATA,
					'result': true,
					'data': 100
				};
				mDeviceEvent
					.notifyDeviceMsgEvent(
						obj
					);
				resolve(res)
			},
			fail: function (res) {
				console.log("送数据失败")
				reject(res)
			}
		});
	});
}


function sleep6() {

	return new Promise(function (resolve, reject) {

		setTimeout(function () {

			resolve('ok');

		}, 6000);

	});

}

var StreamBinaryString = function (s) {
	this._p = 0;
	this._s = this.fromBinaryString(s);
};
StreamBinaryString.prototype = {
	constructor: StreamBinaryString,

	fromBinaryString(e) {
		var t = e || '';
		var f = [];
		for (var i = 0; i < t.length; i++) {
			f[i] = String.fromCharCode(t.charCodeAt(i) & 255);
		}
		return f.join('');
	},

	read: function (array, offset, count) {
		if (arguments.length == 1) {
			var result = this._s.substr(this._p, array);
			this._p += array;
			return result;
		} else {
			var result = 0;
			for (var i = 0; i < count; i++) {
				array[i] = this._s.charCodeAt(this._p);
				this._p += 1;
				result++;
			}
			return result;
		}
	},

	readByte: function () {
		var result = this._s.charCodeAt(this._p);
		this._p += 1;
		return result;
	},

	readInt8: function (signed) {
		var result = this._s.charCodeAt(this._p);
		if (signed && result > 127) {
			result -= 256;
		}
		this._p += 1;
		return result;
	},

	readInt16: function () {
		var result = ((this._s.charCodeAt(this._p) << 8) + this._s.charCodeAt(this._p + 1));
		this._p += 2;
		return result;
	},

	readInt32: function () {
		var result = ((this._s.charCodeAt(this._p) << 24) + (this._s.charCodeAt(this._p + 1) << 16) + (this._s
			.charCodeAt(
				this._p + 2) << 8) + this._s.charCodeAt(this._p + 3));
		this._p += 4;
		return result;
	},

	eof: function () {
		return this._p >= this._s.length;
	}
};

function write_cmd_program(deviceId, serviceId, characteristicId, data) {
	var address = 0;
	var len = 0;
	var buf = 0;
	var dv = 0;
	let result;
	console.log("更新122")
	const mtu = 212;
	uni.setBLEMTU({
		deviceId: self
			.data
			.deviceId,
		mtu,
		success: (
			res
		) => {
			console
				.log(
					"setBLEMTU success>>",
					res
				)
		},
		fail: (
			res
		) => {
			console
				.log(
					"setBLEMTU fail>>",
					res
				)
		},
	});

	var value1 = util.write_ota_erase(CMD_IAP_ERASE, 4, 0, 0);
	var typedArray1 = new Uint8Array(value1);
	console.log("送擦除数据", result)
	send_ota_data(deviceId, serviceId, characteristicId, typedArray1.buffer);
	setTimeout(function () {
		uni.request({
			// url: 'https://www.zenghi.com/gj/地升幕.bin', //仅为示例,并非真实接口地址。
			//url: 'https://www.zenghi.com/gj/BLE钉钉.bin', //仅为示例,并非真实接口地址。
			// url: 'https://www.zenghi.com/gj/电子秤.bin', //仅为示例,并非真实接口地址。
			responseType: 'arraybuffer',
			success: (res) => {
				dv = new DataView(res.data);
				var bufferLength = dv.byteLength;
				var sum = 0;
				for (var i = 0; i < bufferLength; i++) {
					sum += dv.getUint8(i)
				}
				result = dv
				console.log(result);
				console.log("content-length", bufferLength);
				console.log("sum", sum);
				len = bufferLength
				var p_data = 0;
				var p_ii = 0;
				while (address <= len) {
					var offst = 176;
					if (address + 176 > len) {
						offst = len - address;
					}
					var value = util.write_ota_program(CMD_IAP_PROM, offst, address, result);
					var typedArray = new Uint8Array(value);
					send_ota_data_num(deviceId, serviceId, characteristicId, typedArray.buffer, (address /
						len));
					address = address + 176;

				}

				// return new Promise
				var value2 = util.write_ota_sum(CMD_IAP_SUM, bufferLength, sum);
				var typedArray2 = new Uint8Array(value2);
				console.log("送结束数据", value2)
				send_ota_data_num(deviceId, serviceId, characteristicId, typedArray2.buffer, 100);
			},
			fail: function (res) {
				console.log("获取失败");
			}
		})
	}

		, "1000");

	// var requestTask =
}

function write_cmd_program_zy(deviceId, serviceId, characteristicId, data) {
	var address = 0;
	var len = 0;
	var buf = 0;
	var dv = 0;
	let result;
	console.log("更新122")
	const mtu = 212;
	uni.setBLEMTU({
		deviceId: self
			.data
			.deviceId,
		mtu,
		success: (
			res
		) => {
			console
				.log(
					"setBLEMTU success>>",
					res
				)
		},
		fail: (
			res
		) => {
			console
				.log(
					"setBLEMTU fail>>",
					res
				)
		},
	});

	var value1 = util.write_ota_erase(CMD_IAP_ERASE, 4, 0, 0);
	var typedArray1 = new Uint8Array(value1);
	console.log("送擦除数据", result)
	send_ota_data(deviceId, serviceId, characteristicId, typedArray1.buffer);
	setTimeout(function () {
		uni.request({
			url: 'https://www.zenghi.com/gj/地升幕.bin', //仅为示例,并非真实接口地址。
			//url: 'https://www.zenghi.com/gj/BLE钉钉.bin', //仅为示例,并非真实接口地址。
			// url: 'https://www.zenghi.com/gj/电子秤.bin', //仅为示例,并非真实接口地址。
			responseType: 'arraybuffer',
			success: (res) => {
				dv = new DataView(res.data);
				var bufferLength = dv.byteLength;
				var sum = 0;
				for (var i = 0; i < bufferLength; i++) {
					sum += dv.getUint8(i)
				}
				result = dv
				console.log(result);
				console.log("content-length", bufferLength);
				console.log("sum", sum);
				len = bufferLength
				var p_data = 0;
				var p_ii = 0;
				while (address <= len) {
					var offst = 176;
					if (address + 176 > len) {
						offst = len - address;
					}
					var value = util.write_ota_program(CMD_IAP_PROM, offst, address, result);
					var typedArray = new Uint8Array(value);
					send_ota_data_num(deviceId, serviceId, characteristicId, typedArray.buffer, (address /
						len));
					address = address + 176;

				}

				// return new Promise
				var value2 = util.write_ota_sum(CMD_IAP_SUM, bufferLength, sum);
				var typedArray2 = new Uint8Array(value2);
				console.log("送结束数据", value2)
				send_ota_data_num(deviceId, serviceId, characteristicId, typedArray2.buffer, 100);
			},
			fail: function (res) {
				console.log("获取失败");
			}
		})
	}

		, "1000");

	// var requestTask =
}

function write_cmd_program_yk(deviceId, serviceId, characteristicId, data) {
	var address = 0;
	var len = 0;
	var buf = 0;
	var dv = 0;
	let result;
	console.log("更新122")
	const mtu = 212;
	uni.setBLEMTU({
		deviceId: self
			.data
			.deviceId,
		mtu,
		success: (
			res
		) => {
			console
				.log(
					"setBLEMTU success>>",
					res
				)
		},
		fail: (
			res
		) => {
			console
				.log(
					"setBLEMTU fail>>",
					res
				)
		},
	});

	var value1 = util.write_ota_erase(CMD_IAP_ERASE, 4, 0, 0);
	var typedArray1 = new Uint8Array(value1);
	console.log("送擦除遥控器数据", result)
	send_ota_data(deviceId, serviceId, characteristicId, typedArray1.buffer);
	setTimeout(function () {
		uni.request({
			url: 'https://www.zenghi.com/gj/遥控器.bin', //仅为示例,并非真实接口地址。
			//url: 'https://www.zenghi.com/gj/BLE钉钉.bin', //仅为示例,并非真实接口地址。
			// url: 'https://www.zenghi.com/gj/电子秤.bin', //仅为示例,并非真实接口地址。
			responseType: 'arraybuffer',
			success: (res) => {
				dv = new DataView(res.data);
				var bufferLength = dv.byteLength;
				var sum = 0;
				for (var i = 0; i < bufferLength; i++) {
					sum += dv.getUint8(i)
				}
				result = dv
				console.log(result);
				console.log("content-length", bufferLength);
				console.log("sum", sum);
				len = bufferLength
				var p_data = 0;
				var p_ii = 0;
				while (address <= len) {
					var offst = 176;
					if (address + 176 > len) {
						offst = len - address;
					}
					var value = util.write_ota_program(CMD_IAP_PROM, offst, address, result);
					var typedArray = new Uint8Array(value);
					send_ota_data_num(deviceId, serviceId, characteristicId, typedArray.buffer, (address /
						len));
					address = address + 176;

				}

				// return new Promise
				var value2 = util.write_ota_sum(CMD_IAP_SUM, bufferLength, sum);
				var typedArray2 = new Uint8Array(value2);
				console.log("送结束数据", value2)
				send_ota_data_num(deviceId, serviceId, characteristicId, typedArray2.buffer, 100);
			},
			fail: function (res) {
				console.log("获取失败");
			}
		})
	}

		, "1000");

	// var requestTask =
}



function write_cmd_program_fg(web, deviceId, serviceId, characteristicId, data) {
	var address = 0;
	var len = 0;
	var buf = 0;
	var dv = 0;
	let result;
	console.log("更新122")
	const mtu = 212;
	uni.setBLEMTU({
		deviceId: self
			.data
			.deviceId,
		mtu,
		success: (
			res
		) => {
			console
				.log(
					"setBLEMTU success>>",
					res
				)
		},
		fail: (
			res
		) => {
			console
				.log(
					"setBLEMTU fail>>",
					res
				)
		},
	});

	var value1 = util.write_ota_erase(CMD_IAP_ERASE, 4, 0, 0);
	var typedArray1 = new Uint8Array(value1);
	console.log("翻盖柜", web)
	send_ota_data(deviceId, serviceId, characteristicId, typedArray1.buffer);
	setTimeout(function () {
		uni.request({
			url: web, //仅为示例,并非真实接口地址。
			//url: 'https://www.zenghi.com/gj/BLE钉钉.bin', //仅为示例,并非真实接口地址。
			// url: 'https://www.zenghi.com/gj/电子秤.bin', //仅为示例,并非真实接口地址。
			responseType: 'arraybuffer',
			success: (res) => {
				dv = new DataView(res.data);
				var bufferLength = dv.byteLength;
				var sum = 0;
				for (var i = 0; i < bufferLength; i++) {
					sum += dv.getUint8(i)
				}
				result = dv
				console.log(result);
				console.log("content-length", bufferLength);
				console.log("sum", sum);
				len = bufferLength
				var p_data = 0;
				var p_ii = 0;
				while (address <= len) {
					var offst = 176;
					if (address + 176 > len) {
						offst = len - address;
					}
					var value = util.write_ota_program(CMD_IAP_PROM, offst, address, result);
					var typedArray = new Uint8Array(value);
					var qq = send_ota_data_num(deviceId, serviceId, characteristicId, typedArray.buffer, (address /
						len))
						
					address = address + 176;
					console.log("送数据", qq)
				}

				// return new Promise
				var value2 = util.write_ota_sum(CMD_IAP_SUM, bufferLength, sum);
				var typedArray2 = new Uint8Array(value2);
				console.log("送结束数据", value2)
				send_ota_data_num(deviceId, serviceId, characteristicId, typedArray2.buffer, 100);
			},
			fail: function (res) {
				console.log("获取失败");
			}
		})
	}

		, "1000");

	// var requestTask =
}



function writeCutomsData(deviceId, serviceId, characteristicId, data) {
	// var obj = {},
	// 	frameControl = 0;
	// sequenceControl = parseInt(sequenceControl) + 1;

	// if (!util._isEmpty(data)) {
	// 	obj = util.isSubcontractor(data, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
	// 	frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	// } else {
	// 	var ssidData = getCharCodeat(self.data.customData);
	// 	obj = util.isSubcontractor(ssidData, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
	// 	frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	// }

	// var defaultData = util.encrypt(aesjs, self.data.md5Key, sequenceControl, obj.lenData, true);
	// var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_CUSTOM_DATA, frameControl, sequenceControl, obj.len,
	// 	defaultData);
	// var typedArray = new Uint8Array(value);
	console.log("开始送数据")
	console.log("deviceId", deviceId)
	console.log("serviceId", serviceId)
	console.log("characteristicId", characteristicId)
	// const buffer = new ArrayBuffer(8);
	console.log("data", data)
	if (data.indexOf("update") != -1 && data.indexOf("all_update") == -1) {
		console.log("送数update据成功")
		write_cmd_program(deviceId, serviceId, characteristicId, data)
	}
	else if (data.indexOf("upzydsm") != -1 ) {
		console.log("送数upzydsm据成功")
		write_cmd_program_zy(deviceId, serviceId, characteristicId, data)
	}
	else if (data.indexOf("upykdate") != -1 ) {
		console.log("送数upykdate据成功")
		write_cmd_program_yk(deviceId, serviceId, characteristicId, data)
	}
	else if (data.indexOf("fgdate") != -1 ) {
		write_cmd_program_fg('https://fg.zenghi.com/gj/翻盖柜.bin',deviceId, serviceId, characteristicId, data)
	}
	
	// else if (data.indexOf("ble_go7p") != -1 ) {
	// 	console.log("送数update据成功")
	// 	write_cmd_program7p(deviceId, serviceId, characteristicId, data)
	// }
	else {
		var buffer = string2buffer(data)
		uni.writeBLECharacteristicValue({
			deviceId: deviceId,
			serviceId: serviceId,
			characteristicId: characteristicId,
			// value: typedArray.buffer,
			value: buffer,
			success: function (res) {
				console.log("送数据成功")
			},
			fail: function (res) { //console.log(257);
			console.log("送数据成功",res)
			}
		});
	}
}

function readCutomsData(deviceId, serviceId, characteristicId) {
	console.log("开始送数据")
	console.log("deviceId", deviceId)
	console.log("serviceId", serviceId)
	console.log("characteristicId", characteristicId)
	// const buffer = new ArrayBuffer(8);
	console.log("buffer", buffer)
	var buffer = string2buffer(data)
	uni.readBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		// value: typedArray.buffer,
		// value: buffer,
		success: function (res) {
			console.log("读数据成功")
		},
		fail: function (res) { //console.log(257);
		}
	});
}

function writeRouterSsid(deviceId, serviceId, characteristicId, data) {
	var obj = {},
		frameControl = 0;
	sequenceControl = parseInt(sequenceControl) + 1;

	if (!util._isEmpty(data)) {
		obj = util.isSubcontractor(data, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
		frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	} else {
		var ssidData = getCharCodeat(self.data.ssid);
		obj = util.isSubcontractor(ssidData, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
		frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	}

	var defaultData = util.encrypt(aesjs, self.data.md5Key, sequenceControl, obj.lenData, true);
	var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_SET_SSID, frameControl, sequenceControl, obj.len,
		defaultData);
	var typedArray = new Uint8Array(value);
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: typedArray.buffer,
		success: function (res) {
			if (obj.flag) {
				writeRouterSsid(deviceId, serviceId, characteristicId, obj.laveData);
			} else {
				writeDevicePwd(deviceId, serviceId, characteristicId, null);
			}
		},
		fail: function (res) { //console.log(257);
		}
	});
}

function writeDevicePwd(deviceId, serviceId, characteristicId, data) {
	var obj = {},
		frameControl = 0;
	sequenceControl = parseInt(sequenceControl) + 1;

	if (!util._isEmpty(data)) {
		obj = util.isSubcontractor(data, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
		frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	} else {
		var pwdData = getCharCodeat(self.data.password);
		obj = util.isSubcontractor(pwdData, self.data.isChecksum, sequenceControl, self.data.isEncrypt);
		frameControl = util.getFrameCTRLValue(self.data.isEncrypt, self.data.isChecksum, util.DIRECTION_OUTPUT, false, obj.flag);
	}

	var defaultData = util.encrypt(aesjs, self.data.md5Key, sequenceControl, obj.lenData, true);
	var value = util.writeData(util.PACKAGE_VALUE, util.SUBTYPE_SET_PWD, frameControl, sequenceControl, obj.len,
		defaultData);
	var typedArray = new Uint8Array(value);
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: typedArray.buffer,
		success: function (res) {
			if (obj.flag) {
				writeDevicePwd(deviceId, serviceId, characteristicId, obj.laveData);
			} else {
				writeDeviceEnd(deviceId, serviceId, characteristicId, null);
			}
		},
		fail: function (res) { }
	});
}

function writeDeviceEnd(deviceId, serviceId, characteristicId) {
	sequenceControl = parseInt(sequenceControl) + 1;
	var frameControl = util.getFrameCTRLValue(self.data.isEncrypt, false, util.DIRECTION_OUTPUT, false, false);
	var value = util.writeData(self.data.PACKAGE_CONTROL_VALUE, util.SUBTYPE_END, frameControl, sequenceControl, 0, null);
	var typedArray = new Uint8Array(value);
	uni.writeBLECharacteristicValue({
		deviceId: deviceId,
		serviceId: serviceId,
		characteristicId: characteristicId,
		value: typedArray.buffer,
		success: function (res) { },
		fail: function (res) { }
	});
}

function init() {
	let mOnFire = require("./other/onfire.js");

	mDeviceEvent = require("./xBlufi.js");
	util = require("./util.js");
	crypto = require("./crypto/crypto-dh.js");
	md5 = require("./crypto/md5.min.js");
	aesjs = require("./crypto/aes.js");
	uni.onBLEConnectionStateChange(function (res) {
		let obj = {
			'type': mDeviceEvent.XBLUFI_TYPE.TYPE_STATUS_CONNECTED,
			'result': res.connected,
			'data': res
		};
		mDeviceEvent.notifyDeviceMsgEvent(obj);
	});
	mDeviceEvent.listenStartDiscoverBle(true, function (options) {
		if (options.isStart) {
			//第一步检查蓝牙适配器是否可用
			uni.onBluetoothAdapterStateChange(function (res) {
				if (!res.available) { }
			}); //第二步关闭适配器,重新来搜索

			uni.closeBluetoothAdapter({
				complete: function (res) 
				{
					// console.log("这里蓝牙数据")
					uni.openBluetoothAdapter({
						success: function (res) {
							uni.getBluetoothAdapterState({
								success: function (res) {
									// console.log("这里蓝牙数据222")
									{
										let devicesList = [];
										let countsTimes = 0;
										uni.onBluetoothDeviceFound(function (devices) {
											//剔除重复设备,兼容不同设备API的不同返回值
											var isnotexist = true;
									
											// console.log('devices',devices);
											if (devices.deviceId) {
												if (devices.advertisData) {
													devices.advertisData = buf2hex(devices.advertisData);
												} else {
													devices.advertisData = '';
												}
									
												for (var i = 0; i < devicesList.length; i++) {
													if (devices.deviceId === devicesList[i].deviceId) {
														isnotexist = false;
													}
												}
									
												if (isnotexist) {
													devicesList.push(devices);
												}
											} else if (devices.devices) {
												// console.log(devices.devices[0])
												// if (devices.devices[0].name != '开发板'
												// 	&& devices.devices[0].name != 'SMART_R2XS'
												// 	&& devices.devices[0].name != 'SMART_R2XS'
												// ) 
												if (devices.devices[0].name.indexOf("BBLE") != -1||devices.devices[0].name.indexOf("CTPO")  != -1){
													// console.log("跳过",devices.devices[0].name)
													// isnotexist = false;
													isnotexist = true;
												}
												else
												{
													isnotexist = false;
												}
												// isnotexist = true;
													
												if (devices.devices[0].advertisData) {
													devices.devices[0].advertisData = buf2hex(devices.devices[0].advertisData);
												} else {
													devices.devices[0].advertisData = '';
												}
									
												for (var i = 0; i < devicesList.length; i++) {
													if (devices.devices[0].deviceId == devicesList[i].deviceId) {
														isnotexist = false;
													}
												}
									
												if (isnotexist) {
													devicesList.push(devices.devices[0]);
												}
											} else if (devices[0]) {
												if (devices[0].advertisData) {
													devices[0].advertisData = buf2hex(devices[0].advertisData);
												} else {
													devices[0].advertisData = '';
												}
									
												for (var i = 0; i < devices_list.length; i++) {
													if (devices[0].deviceId == devicesList[i].deviceId) {
														isnotexist = false;
													}
												}
									
												if (isnotexist) {
													devicesList.push(devices[0]);
												}
											}
									
											let obj = {
												'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS,
												'result': true,
												'data': devicesList
											};
											mDeviceEvent.notifyDeviceMsgEvent(obj);
										});
										
										uni.startBluetoothDevicesDiscovery({
											allowDuplicatesKey: true,
											success: function (res) {
												console.log(res,'true');
												let obj = {
													'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
													'result': true,
													'data': res
												};
												mDeviceEvent.notifyDeviceMsgEvent(obj); //开始扫码,清空列表
									
												devicesList.length = 0;
											}, 
											fail: function (res) {
												console.log(res,'false');
												let obj = {
													'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
													'result': false,
													'data': res
												};
												mDeviceEvent.notifyDeviceMsgEvent(obj);
											}
										});
										
									}
									// uni.stopBluetoothDevicesDiscovery({
									// 	success: function (res)
									// 	fail: function (res) {
									// 		let obj = {
									// 			'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
									// 			'result': false,
									// 			'data': res
									// 		};
									// 		mDeviceEvent.notifyDeviceMsgEvent(obj);
									// 	}
									// });
								},
								fail: function (res) {
									let obj = {
										'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
										'result': false,
										'data': res
									};
									mDeviceEvent.notifyDeviceMsgEvent(obj);
								}
							});
						},
						fail: function (res) {
							let obj = {
								'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_START,
								'result': false,
								'data': res
							};
							mDeviceEvent.notifyDeviceMsgEvent(obj);
						}
					});
				}
			});
		} else {
			uni.stopBluetoothDevicesDiscovery({
				success: function (res) {
					clearInterval(tempTimer);
					let obj = {
						'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
						'result': true,
						'data': res
					};
					mDeviceEvent.notifyDeviceMsgEvent(obj);
				},
				fail: function (res) {
					let obj = {
						'type': mDeviceEvent.XBLUFI_TYPE.TYPE_GET_DEVICE_LISTS_STOP,
						'result': false,
						'data': res
					};
					mDeviceEvent.notifyDeviceMsgEvent(obj);
				}
			});
		}
	});
	mDeviceEvent.listenConnectBle(true, function (options) {
		console.log("我要连接?", options.isStart,options);
		if (options.isStart){
			uni.createBLEConnection({ 
			deviceId: options.deviceId, 
			success: (res) =>{
				// console.log(res,'100');
				self.data.deviceId = options.deviceId;
				mDeviceEvent.notifyDeviceMsgEvent({
					'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECTED,
					'result': true,
					'data': {
						deviceId: options.deviceId,
						name: options.name
					},
				});
			},
			fail: (res) =>{
				// console.log(res,'1112');
				self.data.deviceId = null;
				mDeviceEvent.notifyDeviceMsgEvent({
					'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECTED,
					'result': false,
					'data': res
				});
			}
		});
		} 
		else uni.closeBLEConnection({
			deviceId: options.deviceId,
			success: function (res) {
				console.log('断开成功');
				self.data.deviceId = null;
				mDeviceEvent.notifyDeviceMsgEvent({
					'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CLOSE_CONNECTED,
					'result': true,
					'data': {
						deviceId: options.deviceId,
						name: options.name
					}
				});
			},
			fail: function (res) {
				self.data.deviceId = null;
				mDeviceEvent.notifyDeviceMsgEvent({
					'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CLOSE_CONNECTED,
					'result': false,
					'data': res
				});
			}
		});
	});
	mDeviceEvent.listenInitBleEsp32(true, function (options) {
		sequenceControl = 0;
		sequenceNumber = -1;
		self = null;
		self = {
			data: {
				deviceId: null,
				isConnected: false,
				failure: false,
				value: 0,
				desc: "请耐心等待...",
				isChecksum: true,
				isEncrypt: true,
				flagEnd: false,
				defaultData: 1,
				ssidType: 2,
				passwordType: 3,
				meshIdType: 3,
				deviceId: "",
				ssid: "",
				uuid: "",
				serviceId: "",
				password: "",
				meshId: "",
				processList: [],
				result: [],
				service_uuid: "000000FF-0000-1000-8000-00805F9B34FB",
				characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
				characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
				customData: null,
				md5Key: 0
			}
		};
		let deviceId = options.deviceId;
		self.data.deviceId = options.deviceId;
		mac_id = options.deviceId;
		
setTimeout(() => {
	console.log(deviceId,'deviceIddeviceId');
		uni.getBLEDeviceServices({
			// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
			deviceId: deviceId,
			success: function(res) {
				console.log("服务发现456", res)
				var services = res.services;
				if (services.length > 0) {
					for (var i = 0; i < services.length; i++) {
						if (services[i].uuid === self.data.service_uuid) {
							var serviceId = services[i].uuid;
							uni.getBLEDeviceCharacteristics({
								// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
								deviceId: deviceId,
								serviceId: serviceId,
								success: function(res) {
									var list = res.characteristics;

									if (list.length > 0) {
										console.log("list@@@@@@@", list)
										for (var i = 0; i < list.length; i++) {
											var uuid = list[i].uuid;
											console.log("uuid", uuid)	
											if (uuid == self.data.characteristic_write_uuid) {
												self.data.serviceId = serviceId;
												self.data.uuid = uuid;
												console.log("uuid", uuid)	
												uni.notifyBLECharacteristicValueChange({
													state: true,
													// 启用 notify 功能
													deviceId: deviceId,
													serviceId: serviceId,
													characteristicId: list[0].uuid,
													success: function(res) {
														console.log("成功", res)	
														writeCutomsData(self.data.deviceId, self.data.service_uuid, self.data.characteristic_write_uuid, "get_fw");

															setTimeout(() => {
															const mtu = 212;
																uni.setBLEMTU({
																	deviceId: self.data.deviceId,
																	mtu,
																	success: (
																		res
																	) => {
																		console
																			.log(
																				"set1212BLEMTU success>>",
																				res
																			)
																	},
																	fail: (
																		res
																	) => {
																	},
																});
															  }, 1000);
															
														uni.onBLECharacteristicValueChange(function(res) {
															var my_str = Utf8ArrayToStr(res.value)
															if(my_str.indexOf("wifi_ok") != -1)	
															{
																console.log("获取到wifiok设备数据OK", my_str);
																mDeviceEvent.notifyDeviceMsgEvent({
																	'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
																	'result': true,
																	'data': {
																		'progress': 100,
																		'ssid': ""
																	}
																});
															} else  if(my_str.indexOf("wifi_err") != -1)	{
																console.log("获取到设备数据失败", my_str);
																mDeviceEvent.notifyDeviceMsgEvent({
																	'type': mDeviceEvent.XBLUFI_TYPE.TYPE_CONNECT_ROUTER_RESULT,
																	'result': false,
																	'data': {
																		'progress': 0,
																		'ssid': ""
																	}
																});
															}
															else
															{
															let obj = {
																'type': mDeviceEvent.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA,
																'result': true,
																'data': my_str
															};
															mDeviceEvent.notifyDeviceMsgEvent(obj);
										
														}
														});
													},
													fail: function(res) {

														console.log("监听", res)		
														uni.onBLECharacteristicValueChange(function(res) {
															var my_str = Utf8ArrayToStr(res.value)
															{
															let obj = {
																'type': mDeviceEvent.XBLUFI_TYPE.TYPE_RECIEVE_CUSTON_DATA,
																'result': true,
																'data': my_str
															};
															mDeviceEvent.notifyDeviceMsgEvent(obj);
										
														}
														});

														// let obj = {
														// 	'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
														// 	'result': false,
														// 	'data': res
														// };
														// mDeviceEvent.notifyDeviceMsgEvent(obj);
													}
												});
											}
										}
									}
								},
								fail: function(res) {
									// let obj = {
									// 	'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
									// 	'result': false,
									// 	'data': res
									// };
									// mDeviceEvent.notifyDeviceMsgEvent(obj);
									// console.log("fail getBLEDeviceCharacteristics:" + JSON.stringify(res));
								}
							});
							break;
						}
					}
				}
				else
				{
					
				}
			},
			fail: function(res) {
				let obj = {
					'type': mDeviceEvent.XBLUFI_TYPE.TYPE_INIT_ESP32_RESULT,
					'result': false,
					'data': res
				};
				mDeviceEvent.notifyDeviceMsgEvent(obj);
				console.log("fail getBLEDeviceServices:" + JSON.stringify(res));
			}
		});
	
},2000);
	});
	mDeviceEvent.listenSendRouterSsidAndPassword(true, function(options) {
		self.data.password = options.password;
		self.data.ssid = options.ssid;
		writeDeviceRouterInfoStart(self.data.deviceId, self.data.service_uuid, self.data.characteristic_write_uuid, self.data);
	});
	mDeviceEvent.listenSendCustomData(true, function(options) {
		self.data.customData = options.customData;
		// writeCutomsData(self.data.deviceId, self.data.service_uuid, self.data.characteristic_write_uuid, null);
		writeCutomsData(mac_id, self.data.service_uuid, self.data.characteristic_write_uuid, self.data.customData);
	});
}
/****************************** 对外  ***************************************/


module.exports = {
	init: init
};