| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- const logEnable = false;
- let isAndroid = false;
- let ecBluetoothAdapterStateChangeCallback = () => { };
- let ecBLEConnectionStateChangeCallback = () => { };
- let ecDeviceId = '';
- let ecGattServerUUID = '';
- const ecGattServerUUIDOption1 = '0000FFF0-0000-1000-8000-00805F9B34FB';
- const ecGattServerUUIDOption2 = 'FFF0';
- let ecGattCharacteristicWriteUUID = '';
- const ecGattCharacteristicWriteUUIDOption1 = '0000FFF2-0000-1000-8000-00805F9B34FB';
- const ecGattCharacteristicWriteUUIDOption2 = 'FFF2';
- const log = data => {
- if (logEnable) {
- console.log('[eciot]:' + JSON.stringify(data));
- }
- };
- const onBluetoothAdapterStateChange = cb => {
- ecBluetoothAdapterStateChangeCallback = cb;
- };
- // const getSetting = () => {
- // return new Promise(function (resolve, reject) {
- // jd.getSetting({
- // success(res) {
- // log(res);
- // if (res.authSetting && res.authSetting['scope.bluetooth']) {
- // resolve({
- // ok: true,
- // errCode: 0,
- // errMsg: ''
- // });
- // } else {
- // resolve({
- // ok: false,
- // errCode: 30001,
- // errMsg: 'getSetting fail'
- // });
- // }
- // },
- // fail(res) {
- // log(res);
- // resolve({
- // ok: false,
- // errCode: res.errCode ? res.errCode : 30000,
- // errMsg: res.errMsg ? res.errMsg : 'getSetting fail'
- // });
- // }
- // });
- // });
- // };
- // const authorize = () => {
- // return new Promise(function (resolve, reject) {
- // jd.authorize({
- // scope: 'scope.bluetooth',
- // success(res) {
- // log(res);
- // resolve({
- // ok: true,
- // errCode: 0,
- // errMsg: ''
- // });
- // },
- // fail(res) {
- // log(res);
- // // {"errMsg":"authorize:fail:auth deny"}
- // resolve({
- // ok: false,
- // errCode: 30000,
- // errMsg: res.errMsg
- // });
- // }
- // });
- // });
- // };
- const _openBluetoothAdapter = () => {
- return new Promise(function (resolve, reject) {
- jd.openBluetoothAdapter({
- success(res) {
- log(res);
- // {errno: 0, errMsg: "openBluetoothAdapter:ok"}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- resolve({
- ok: false,
- errCode: res.errCode ? res.errCode : 30000,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- const openBluetoothAdapter = async () => {
- // await _openBluetoothAdapter()
- const systemInfo = jd.getSystemInfoSync();
- log(systemInfo);
- if (systemInfo.platform.toLowerCase() === 'android') {
- isAndroid = true;
- }
- // if (!systemInfo.bluetoothEnabled) {
- // ecBluetoothAdapterStateChangeCallback({
- // ok: false,
- // errCode: 30001,
- // errMsg: '请打开系统蓝牙开关'
- // });
- // return;
- // }
- // if (isAndroid && !systemInfo.locationEnabled) {
- // ecBluetoothAdapterStateChangeCallback({
- // ok: false,
- // errCode: 30002,
- // errMsg: '请打开系统定位开关'
- // });
- // return;
- // }
- // if (isAndroid && !systemInfo.locationAuthorized) {
- // ecBluetoothAdapterStateChangeCallback({
- // ok: false,
- // errCode: 30003,
- // errMsg: '请打开微信定位权限,允许微信使用您的位置信息'
- // });
- // return;
- // }
- // const setting = await getSetting(); //小程序蓝牙权限
- // if (!setting.ok) {
- // const authRes = await authorize();
- // if (!authRes.ok) {
- // ecBluetoothAdapterStateChangeCallback({
- // ok: false,
- // errCode: 30004,
- // errMsg: '请打开小程序蓝牙开关,点击右上角三个点,然后点击设置'
- // });
- // return;
- // }
- // }
- jd.offBluetoothAdapterStateChange();
- jd.onBluetoothAdapterStateChange(res => {
- log(res); // {available: true, discovering: true}
- if (!res.available) {
- ecBluetoothAdapterStateChangeCallback({
- ok: false,
- errCode: 30005,
- errMsg: '蓝牙适配器不可用'
- });
- }
- });
- const openRes = await _openBluetoothAdapter();
- ecBluetoothAdapterStateChangeCallback(openRes);
- };
- const onBluetoothDeviceFound = cb => {
- jd.offBluetoothDeviceFound();
- jd.onBluetoothDeviceFound(res => {
- // log(res);
- const device = res.devices[0];
- const name = device.name ? device.name : device.localName;
- if (!name) {
- return;
- }
- let id = device.deviceId;
- let rssi = device.RSSI;
- cb({
- id,
- name,
- rssi
- });
- });
- };
- const startBluetoothDevicesDiscovery = () => {
- jd.startBluetoothDevicesDiscovery({
- //services: [ecServerId],
- allowDuplicatesKey: true,
- powerLevel: 'high',
- complete(res) {
- log(res);
- }
- });
- };
- const stopBluetoothDevicesDiscovery = () => {
- jd.stopBluetoothDevicesDiscovery({
- complete(res) {
- // {errno: 0, errMsg: "stopBluetoothDevicesDiscovery:ok", isDiscovering: false}
- log(res);
- }
- });
- };
- const onBLEConnectionStateChange = cb => {
- ecBLEConnectionStateChangeCallback = cb;
- };
- const _createBLEConnection = () => {
- return new Promise(function (resolve, reject) {
- jd.createBLEConnection({
- deviceId: ecDeviceId,
- success(res) {
- log(res);
- // {"errno":0,"errCode":0,"errMsg":"createBLEConnection:ok"}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- // {"errno":1001,"errMsg":"createBLEConnection:fail parameter error: parameter.deviceId should be String instead of Undefined;"}
- resolve({
- ok: false,
- errCode: res.errCode ? res.errCode : res.errno,
- errMsg: res.errMsg
- });
- }
- });
- if (!isAndroid) {
- setTimeout(() => {
- jd.createBLEConnection({
- deviceId: ecDeviceId,
- success(res) {
- log(res);
- // {"errno":0,"errCode":0,"errMsg":"createBLEConnection:ok"}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- // {"errno":1001,"errMsg":"createBLEConnection:fail parameter error: parameter.deviceId should be String instead of Undefined;"}
- resolve({
- ok: false,
- errCode: res.errCode ? res.errCode : res.errno,
- errMsg: res.errMsg
- });
- }
- });
- }, 1000)
- }
- });
- };
- const getBLEDeviceServices = () => {
- return new Promise(function (resolve, reject) {
- jd.getBLEDeviceServices({
- deviceId: ecDeviceId,
- success(res) {
- log(res);
- //{"services":[{"uuid":"0000FFF0-0000-1000-8000-00805F9B34FB","isPrimary":true}],"errCode":0,"errno":0,"errMsg":"getBLEDeviceServices:ok"}
- // {"errno":0,"deviceId":"7C7E20F2-CB75-6DA8-F8DF-FFF702B0D63F","services":[{"isPrimary":true,"uuid":"0000FFF0-0000-1000-8000-00805F9B34FB"}],"errMsg":"getBLEDeviceServices:ok","errCode":0}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: '',
- services: res.services
- });
- },
- fail(res) {
- log(res);
- resolve({
- ok: false,
- errCode: res.errCode,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- const getBLEDeviceCharacteristics = serviceId => {
- return new Promise(function (resolve, reject) {
- jd.getBLEDeviceCharacteristics({
- deviceId: ecDeviceId,
- serviceId,
- success(res) {
- log(res);
- // {"characteristics":[{"uuid":"0000FFF2-0000-1000-8000-00805F9B34FB","handle":3,"properties":{"read":false,"write":true,"notify":false,"indicate":false,"writeNoResponse":true,"writeDefault":true}},{"uuid":"0000FFF1-0000-1000-8000-00805F9B34FB","handle":5,"properties":{"read":true,"write":true,"notify":true,"indicate":false,"writeNoResponse":true,"writeDefault":true}}],"errCode":0,"errno":0,"errMsg":"getBLEDeviceCharacteristics:ok"}
- // {"characteristics":[{"properties":{"writeDefault":true,"notify":false,"write":true,"indicate":false,"read":false,"writeNoResponse":true},"uuid":"0000FFF2-0000-1000-8000-00805F9B34FB"},{"properties":{"writeDefault":true,"notify":true,"write":true,"indicate":false,"read":true,"writeNoResponse":true},"uuid":"0000FFF1-0000-1000-8000-00805F9B34FB"}],"deviceId":"7C7E20F2-CB75-6DA8-F8DF-FFF702B0D63F","serviceId":"0000FFF0-0000-1000-8000-00805F9B34FB","errno":0,"errMsg":"getBLEDeviceCharacteristics:ok","errCode":0}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: '',
- characteristics: res.characteristics
- });
- },
- fail(res) {
- log(res);
- resolve({
- ok: false,
- errCode: res.errCode,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- const notifyBLECharacteristicValueChange = (serviceId, characteristicId) => {
- return new Promise(function (resolve, reject) {
- jd.notifyBLECharacteristicValueChange({
- state: true,
- deviceId: ecDeviceId,
- serviceId,
- characteristicId,
- success(res) {
- log(res);
- // {"errCode":0,"errno":0,"errMsg":"notifyBLECharacteristicValueChange:ok"}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- resolve({
- ok: false,
- errCode: res.errCode,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- const setBLEMTU = mtu => {
- return new Promise(function (resolve, reject) {
- jd.setBLEMTU({
- deviceId: ecDeviceId,
- mtu,
- success(res) {
- log(res);
- // {"errMsg":"setBLEMTU:ok","errno":0,"errCode":0,"mtu":50}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- // {"errCode":-1,"errno":1500104,"errMsg":"setBLEMTU:fail:internal error"}
- resolve({
- ok: false,
- errCode: res.errCode,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- //和设备建立连接
- const createBLEConnection = async id => {
- ecDeviceId = id;
- jd.offBLEConnectionStateChange();
- jd.onBLEConnectionStateChange(async res => {
- log(res);
- // {"deviceId":"EC:22:05:13:78:49","connected":true}
- if (res.connected) {
- const servicesResult = await getBLEDeviceServices();
- if (!servicesResult.ok) {
- ecBLEConnectionStateChangeCallback(servicesResult);
- closeBLEConnection();
- return;
- }
- for (const service of servicesResult.services) {
- if (service.uuid.toUpperCase() === ecGattServerUUIDOption1 || service.uuid.toUpperCase() === ecGattServerUUIDOption2) {
- ecGattServerUUID = service.uuid;
- }
- const characteristicsResult = await getBLEDeviceCharacteristics(service.uuid);
- if (!characteristicsResult.ok) {
- ecBLEConnectionStateChangeCallback(characteristicsResult);
- closeBLEConnection();
- return;
- }
- for (const characteristic of characteristicsResult.characteristics) {
- if (characteristic.properties && characteristic.properties.notify) {
- const notifyResult = await notifyBLECharacteristicValueChange(service.uuid, characteristic.uuid);
- if (!notifyResult.ok) {
- ecBLEConnectionStateChangeCallback({
- ok: false,
- errCode: 30000,
- errMsg: 'notify error'
- });
- closeBLEConnection();
- return;
- }
- }
- if (characteristic.uuid.toUpperCase() === ecGattCharacteristicWriteUUIDOption1 || characteristic.uuid.toUpperCase() === ecGattCharacteristicWriteUUIDOption2) {
- ecGattCharacteristicWriteUUID = characteristic.uuid;
- }
- }
- }
- if (isAndroid) {
- await setBLEMTU(247);
- }
- ecBLEConnectionStateChangeCallback({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- } else {
- ecBLEConnectionStateChangeCallback({
- ok: false,
- errCode: 0,
- errMsg: 'disconnect'
- });
- }
- });
- const res = await _createBLEConnection();
- if (!res.ok) {
- ecBLEConnectionStateChangeCallback(res);
- }
- };
- //关闭当前连接
- const closeBLEConnection = () => {
- jd.closeBLEConnection({
- deviceId: ecDeviceId,
- complete(res) {
- log(res);
- }
- });
- };
- const onBLECharacteristicValueChange = cb => {
- jd.offBLECharacteristicValueChange();
- jd.onBLECharacteristicValueChange(res => {
- log(res);
- let x = new Uint8Array(res.value);
- log(x);
- let str = utf8BytesToStr(x);
- let strHex = '';
- for (let i = 0; i < x.length; i++) {
- strHex = strHex + x[i].toString(16).padStart(2, '0').toUpperCase();
- }
- log(str);
- log(strHex);
- cb(str, strHex);
- });
- };
- const _writeBLECharacteristicValue = buffer => {
- return new Promise(function (resolve, reject) {
- jd.writeBLECharacteristicValue({
- deviceId: ecDeviceId,
- serviceId: ecGattServerUUID,
- characteristicId: ecGattCharacteristicWriteUUID,
- value: buffer,
- writeType: 'writeNoResponse',
- success(res) {
- log(res);
- // {"errno":0,"errCode":0,"errMsg":"writeBLECharacteristicValue:ok"}
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- });
- },
- fail(res) {
- log(res);
- resolve({
- ok: false,
- errCode: res.errCode,
- errMsg: res.errMsg
- });
- }
- });
- });
- };
- const writeBLECharacteristicValue = async (str, isHex) => {
- if (str.length === 0) return {
- ok: false,
- errCode: 30000,
- errMsg: 'data is null'
- };
- let buffer;
- if (isHex) {
- buffer = new ArrayBuffer(str.length / 2);
- let x = new Uint8Array(buffer);
- for (let i = 0; i < x.length; i++) {
- x[i] = parseInt(str.substr(2 * i, 2), 16);
- }
- } else {
- buffer = new Uint8Array(strToUtf8Bytes(str)).buffer;
- }
- return await _writeBLECharacteristicValue(buffer);
- };
- const utf8BytesToStr = utf8Bytes => {
- let unicodeStr = '';
- for (let pos = 0; pos < utf8Bytes.length;) {
- let flag = utf8Bytes[pos];
- let unicode = 0;
- if (flag >>> 7 === 0) {
- unicodeStr += String.fromCharCode(utf8Bytes[pos]);
- pos += 1;
- }
- // else if ((flag & 0xFC) === 0xFC) {
- // unicode = (utf8Bytes[pos] & 0x3) << 30
- // unicode |= (utf8Bytes[pos + 1] & 0x3F) << 24
- // unicode |= (utf8Bytes[pos + 2] & 0x3F) << 18
- // unicode |= (utf8Bytes[pos + 3] & 0x3F) << 12
- // unicode |= (utf8Bytes[pos + 4] & 0x3F) << 6
- // unicode |= (utf8Bytes[pos + 5] & 0x3F)
- // unicodeStr += String.fromCharCode(unicode)
- // pos += 6
- // }
- // else if ((flag & 0xF8) === 0xF8) {
- // unicode = (utf8Bytes[pos] & 0x7) << 24
- // unicode |= (utf8Bytes[pos + 1] & 0x3F) << 18
- // unicode |= (utf8Bytes[pos + 2] & 0x3F) << 12
- // unicode |= (utf8Bytes[pos + 3] & 0x3F) << 6
- // unicode |= (utf8Bytes[pos + 4] & 0x3F)
- // unicodeStr += String.fromCharCode(unicode)
- // pos += 5
- // }
- else if ((flag & 0xf0) === 0xf0) {
- unicode = (utf8Bytes[pos] & 0xf) << 18;
- unicode |= (utf8Bytes[pos + 1] & 0x3f) << 12;
- unicode |= (utf8Bytes[pos + 2] & 0x3f) << 6;
- unicode |= utf8Bytes[pos + 3] & 0x3f;
- unicodeStr += String.fromCharCode(unicode);
- pos += 4;
- } else if ((flag & 0xe0) === 0xe0) {
- unicode = (utf8Bytes[pos] & 0x1f) << 12;
- unicode |= (utf8Bytes[pos + 1] & 0x3f) << 6;
- unicode |= utf8Bytes[pos + 2] & 0x3f;
- unicodeStr += String.fromCharCode(unicode);
- pos += 3;
- } else if ((flag & 0xc0) === 0xc0) {
- //110
- unicode = (utf8Bytes[pos] & 0x3f) << 6;
- unicode |= utf8Bytes[pos + 1] & 0x3f;
- unicodeStr += String.fromCharCode(unicode);
- pos += 2;
- } else {
- unicodeStr += String.fromCharCode(utf8Bytes[pos]);
- pos += 1;
- }
- }
- return unicodeStr;
- };
- const strToUtf8Bytes = str => {
- let bytes = [];
- for (let i = 0; i < str.length; ++i) {
- let code = str.charCodeAt(i);
- if (code >= 0x10000 && code <= 0x10ffff) {
- bytes.push(code >> 18 | 0xf0); // 第一个字节
- bytes.push(code >> 12 & 0x3f | 0x80);
- bytes.push(code >> 6 & 0x3f | 0x80);
- bytes.push(code & 0x3f | 0x80);
- } else if (code >= 0x800 && code <= 0xffff) {
- bytes.push(code >> 12 | 0xe0);
- bytes.push(code >> 6 & 0x3f | 0x80);
- bytes.push(code & 0x3f | 0x80);
- } else if (code >= 0x80 && code <= 0x7ff) {
- bytes.push(code >> 6 | 0xc0);
- bytes.push(code & 0x3f | 0x80);
- } else {
- bytes.push(code);
- }
- }
- return bytes;
- };
- module.exports = {
- onBluetoothAdapterStateChange,
- openBluetoothAdapter,
- onBluetoothDeviceFound,
- startBluetoothDevicesDiscovery,
- stopBluetoothDevicesDiscovery,
- onBLEConnectionStateChange,
- createBLEConnection,
- closeBLEConnection,
- onBLECharacteristicValueChange,
- writeBLECharacteristicValue
- };
|