cordova-plugin-bluetoothle
cordova-plugin-bluetoothle copied to clipboard
multiple concurrent connect/discover/read causes one connect to not return, IOS 14
I have an ionic native app, using promises to parallelize reading from multiple devices.
there are two promise loops one to get all the needed characteristics from a device
and one o wait for the gets for all the devices to complete
readdeviceInfo(peripherals, characteristics){
const plist=[] // for waiting for all device operatons to complete
const promiseList={}; // for all operations on A device to complete
// loop thru all the devices found during scan cycle
peripherals.forEach(peripheral=>{
// init its promise list
promiseList[peripheral.address]=[]
plist.push(new Promise((zresolve,zreject)=>{
this.LogIt("connecting to device="+JSON.stringify(peripheral))
// connect to this device
BluetoothLE.connect({address: peripheral.address}).subscribe((device)=>{
this.LogIt("connected device="+JSON.stringify(peripheral))
// have to manually discover service/characteristics?!..
// before we can read
BluetoothLE.discover({address:peripheral.address}).then(()=>{
// loop thru the characteristics we need to gt info for
characteristics.forEach((characteristic)=>{
//this.LogIt("processing for characteristic="+characteristic)
// wrap with a promise so they are all async
promiseList[peripheral.address].push(new Promise((resolve,reject)=>{
//try {
//this.LogIt("in promise for characteristic="+characteristic)
// if this is read RSSI OR we don't have the table info yet
if(characteristic !== DATATABLE | this.deviceTable[peripheral.advertisement.serviceUuids[0].slice(0,8)] === undefined){
// execute the read
BluetoothLE.read(
{
"address": peripheral.address,
"service": peripheral.advertisement.serviceUuids[0],
"characteristic": characteristic
}
).then((result)=>{
const p = peripheral
if(characteristic === RSSI ){
// handle one characteristic
}
else{
// handle the other characteristics
}
resolve();
}).catch((error)=>{
//this.LogIt(" read error="+JSON.stringify(error)+" for characteristic="+characteristic)
reject(error)
})
}
else{
// array of characteristics needed might contain some we don't need right now
// skip it
resolve();
}
//}catch(error){
//this.LogIt(/*peripheral.advertisement.serviceUuids[0]+*/" processing error="+JSON.stringify(error) )
// peripheral
//} // end try/catch
}) // end new promise
) // end push
}) // end loop characteristics.forEach
this.LogIt("first promise.all waiting");
// wait for all the operations for A device to complete
Promise.all(promiseList[peripheral.address]).then(()=>{
this.LogIt("all promises for "+peripheral.address+" resolved ok")
//this.LogIt("disconnecting")
// reset the device timestamp
peripheral.timestamp=Date.now();
BluetoothLE.disconnect({address: peripheral.address}).then(()=>{
this.LogIt("disconnect for "+peripheral.address+" completed, closing")
BluetoothLE.close({address: peripheral.address}).then(()=>{
this.LogIt("close completed ok. resolve="+typeof zresolve)
zresolve() // signal for the outer promise.. this device data collection done
})/*.catch(error=>{
this.LogIt("close failed error="+JSON.stringify(error))
zreject()
}) */
})/*.catch(error=>{
this.LogIt("disconnect failed error="+JSON.stringify(error))
zreject()
}) */
})/*.catch(error=>{
this.LogIt("Promise all 1 failed error="+JSON.stringify(error))
zreject()
}) */
})/*.catch(error=>{
this.LogIt(" discover error="+JSON.stringify(error))
zreject()
})*/
})/*.catch(error=>{
this.LogIt(" connect error="+JSON.stringify(error)+" reject="+typeof zreject)
zreject()
})*/
}))
})
this.LogIt("second promise.all waiting, there are "+plist.length+" devices to process");
// this for ALL devices reported in scan
Promise.all(plist).then(()=>{
this.LogIt("table="+this.flatten(this.deviceTable))
this.LogIt("all device info collected")
this.LogIt("beacon handler="+this.inputBeaconStream)
// send devices on to device handler
if(this.shouldProcess){
setTimeout(()=>{this.inputBeaconStream.next(peripherals)}, 10)
}
}).catch(error=>{
this.LogIt("second promise failed=" +error);
})
}
i've been using this code for months.. and two changes happened this week
- I added two more devices to be detected (6 now, up from 4)
- there was the IOS security upgrade, on both iPhones (7 & 7plus) to 14.8
i had to comment out all the .then() catches, as I was getting an error
undefined is not a function near f9000-090-0-9-99090-999()()()( .catch(function(
which made no sense
commented out the catches and no fatal error anywhere... weird..
anyhow..
whenever I get more than 4 devices back, one of the extras (5 or 6), the connect() never returns
here is the trace (captured over socket.io to my desktop)
client sent=1632068833020 start scanning
client sent=1632068833022 scan for BluetoothLE
client sent=1632068833034 Scanning for devices (will continue to scan until you stop it)...
client sent=1632068833072 FOUND DEVICE: 00000200 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00000200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"51DAEFDD-E532-7BF1-5C9B-773641735327"}
client sent=1632068833101 FOUND DEVICE: 00010201 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010201-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-90,"name":"FacilityDevice","address":"7E03A35E-9F21-62AE-E345-DAC5DD6C7215"}
client sent=1632068833184 FOUND DEVICE: 00010202 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-78,"name":"FacilityDevice","address":"F08CDF62-C692-D913-3FC6-3249B58A254A"}
client sent=1632068833228 FOUND DEVICE: 00010203 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010203-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-58,"name":"FacilityDevice","address":"FF85CCC9-5925-DFB4-C2DE-A614F966D654"}
client sent=1632068833240 FOUND DEVICE: 00020202 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00020202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-74,"name":"FacilityDevice","address":"9DC84DDB-DCB5-8B9D-FAD3-D76C56DB31BD"}
client sent=1632068833346 FOUND DEVICE: 00010200 info={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"isConnectable":1,"serviceData":{},"serviceUuids":["00010200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"0C157ABD-6AD6-BF61-0357-6A1AA843B86F"}
client sent=1632068833779 stopscan successful, streaming beacons
client sent=1632068833779 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"isConnectable":1,"serviceData":{},"serviceUuids":["00010200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"0C157ABD-6AD6-BF61-0357-6A1AA843B86F","direction":322,"timestamp":1632068833347}
client sent=1632068833785 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010203-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-58,"name":"FacilityDevice","address":"FF85CCC9-5925-DFB4-C2DE-A614F966D654","direction":322,"timestamp":1632068833229}
--------------------------------------------------------------
client sent=1632068833792 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010201-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-90,"name":"FacilityDevice","address":"7E03A35E-9F21-62AE-E345-DAC5DD6C7215","direction":322,"timestamp":1632068833102}
------------------------------------------------------------- no response, in a prior scan this device worked ok
client sent=1632068833796 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00000200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"51DAEFDD-E532-7BF1-5C9B-773641735327","direction":322,"timestamp":1632068833073}
client sent=1632068833798 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-78,"name":"FacilityDevice","address":"F08CDF62-C692-D913-3FC6-3249B58A254A","direction":322,"timestamp":1632068833184}
client sent=1632068833799 connecting to device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00020202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-74,"name":"FacilityDevice","address":"9DC84DDB-DCB5-8B9D-FAD3-D76C56DB31BD","direction":322,"timestamp":1632068833241}
client sent=1632068833800 second promise.all waiting, there are 6 devices to process
client sent=1632068834134 connected device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-78,"name":"FacilityDevice","address":"F08CDF62-C692-D913-3FC6-3249B58A254A","direction":322,"timestamp":1632068833184}
client sent=1632068834751 first promise.all waiting
client sent=1632068834826 all promises for F08CDF62-C692-D913-3FC6-3249B58A254A resolved ok
client sent=1632068834864 disconnect for F08CDF62-C692-D913-3FC6-3249B58A254A completed, closing
client sent=1632068834872 close completed ok. resolve=function
client sent=1632068834135 connected device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00010203-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-58,"name":"FacilityDevice","address":"FF85CCC9-5925-DFB4-C2DE-A614F966D654","direction":322,"timestamp":1632068833229}
client sent=1632068834764 first promise.all waiting
client sent=1632068834812 all promises for FF85CCC9-5925-DFB4-C2DE-A614F966D654 resolved ok
client sent=1632068834827 disconnect for FF85CCC9-5925-DFB4-C2DE-A614F966D654 completed, closing
client sent=1632068834839 close completed ok. resolve=function
client sent=1632068834667 connected device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00020202-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-74,"name":"FacilityDevice","address":"9DC84DDB-DCB5-8B9D-FAD3-D76C56DB31BD","direction":322,"timestamp":1632068833241}
client sent=1632068835345 first promise.all waiting
client sent=1632068835404 all promises for 9DC84DDB-DCB5-8B9D-FAD3-D76C56DB31BD resolved ok
client sent=1632068835417 disconnect for 9DC84DDB-DCB5-8B9D-FAD3-D76C56DB31BD completed, closing
client sent=1632068835422 close completed ok. resolve=function
client sent=1632068836171 connected device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"isConnectable":1,"serviceData":{},"serviceUuids":["00010200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"0C157ABD-6AD6-BF61-0357-6A1AA843B86F","direction":322,"timestamp":1632068833347}
client sent=1632068837413 first promise.all waiting
client sent=1632068837624 all promises for 0C157ABD-6AD6-BF61-0357-6A1AA843B86F resolved ok
client sent=1632068837637 disconnect for 0C157ABD-6AD6-BF61-0357-6A1AA843B86F completed, closing
client sent=1632068837642 close completed ok. resolve=function
client sent=1632068835296 connected device={"status":"scanResult","advertisement":{"solicitedServiceUuids":[],"overflowServiceUuids":[],"localName":"FacilityDevice","isConnectable":1,"serviceData":{},"serviceUuids":["00000200-27B9-42F0-82AA-2E951747BBF9"]},"rssi":-88,"name":"FacilityDevice","address":"51DAEFDD-E532-7BF1-5C9B-773641735327","direction":322,"timestamp":1632068833073}
client sent=1632068836236 first promise.all waiting
client sent=1632068836326 all promises for 51DAEFDD-E532-7BF1-5C9B-773641735327 resolved ok
client sent=1632068836342 disconnect for 51DAEFDD-E532-7BF1-5C9B-773641735327 completed, closing
client sent=1632068836347 close completed ok. resolve=function
so, I changed all my promise
.then(
()=>{} // resolve handler
)
.catch(
()=>{} // error handler
)
to
.then(
()=>{}, // resolve handler
()=>{} // reject handler
)
and now everything works. ?!.. but NO promise rejects are reported, but also no weird
undefined is not a function near f9000-090-0-9-99090-999()()()( .catch(function(
still seeing occasional connect not returning. is there a timeout option?
i put the .catch back on to see if the promise is failing and get the weird error
client sent=1632333894495 second promise failed=TypeError: undefined is not a function (near '...ify(e)),a()})).catch((function(e){n.LogI...')
the n.LogI is my code, inside the catch..
i am back to trying to deal with connect not returning..
never mind, i re-read the doc, and it clearly says this will happen AND you the developer using this lib are responsible for setting up error recovery...
one thing I haven't seen is a disconnect while in use... does that flow on the connect subscribe? nm, see below