noble / bleno

A Node.js module for implementing BLE (Bluetooth Low Energy) peripherals
MIT License
2.12k stars 447 forks source link

Cannot transfer a JSON object between nodeJS (bleno module) and a corodova app (ng-cordova-bluetoothle plugin) #427

Open nikolaof opened 5 years ago

nikolaof commented 5 years ago

I'm building a cordova app using angularJS and the ng-cordova-bluetoothle plugin for the central side while using nodeJS with bleno for the peripheral side on a raspberry Pi.

On the peripheral side, I've built a characteristic with only 'read' property available and looks like this:

// GET TEMP CHARACTERISTIC
   new bleno.Characteristic({
       value:null,
       uuid: settings.get_temp_characteristic_id,
       properties: ['read'],
       onReadRequest: function(offset, callback){
           getTemp()
       .then( (res) => {
           var buffer = Buffer.from( JSON.stringify(res) );
           callback(this.RESULT_SUCCESS, buffer);
       })
       }
   })

function getTemp(){
    return axios.get('http://127.0.0.1:8000/get_temp')
    .then( (res) => {
        console.error(res.data);
        return res.data;
    })
    .catch( (error) => {
        console.error(error);
        return error;
    })
}

Now, on the central part I'm having a function that creates a read request to the peripheral like this:

function getTemp(){
        return bleReadgetTemp()
        .then (function(response){
                var bytes = bluetoothle.encodedStringToBytes(response.value);
                var string = bluetoothle.bytesToString(bytes);
                var response = JSON.parse(string);

                 //response = JSON.parse(atob(response.value));
                 Log.add("[+] getTemp: " + JSON.stringify(response) );
                 var tempTimePoint = { time: Date.now() / 1000, y: response.temp };
                 // Push the temp value into rootScope vars.
                 $rootScope.experiment.actualTemp = [];
                 $rootScope.experiment.actualTemp.push( tempTimePoint );
                 $rootScope.experiment.historyTemp[0].values.push( tempTimePoint );

                 Log.add("[+] TempBuffer: " + $rootScope.experiment.actualTemp[0] );
                 return response;
        })
        .catch( function(error){
            Log.add('[!] getTemp Error' + JSON.stringify(error));
        })
    } 

So here is the problem. In the case where the nodeJS side send an object like {"temp": 2455555555}, everything works perfectly and as expected. But, if the digits of the returning temp are more than 10 or in general, the object gets bigger, something like {"temp":232, "status": "OK"} then the whole universe collapses and I'm getting (in the central side) the error

[!] getTemp Error {}

NOTICE:

One other thing that I've noticed, is the following. In the central side, I'm calling the getTemp() function inside an interval call like $interval( function(){ getTemp(); }, 5000). So, as long as the JSON object is in its small version this interval loops triggers the function once every 5 seconds. If the JSON object gets bigger, then the interval triggers the function continuously.

So, what is going on? Is there any overflow problem? Am I converting my JSON data in a wrong way?

Any idea or hint is really welcomed.

leonardoviada commented 3 years ago

I'm having a quite similar issue. I've undertood browsing around that the MTU with BLE is 31 bytes, and the json object should be splitted into packages. Did you find a solution? @nikolaof