SamsungInternet / SamsungBluetoothWiFiManager

This is a node.js application that will allow WiFi configuration of a server. Designed to be used on Gateway devices or devices that need to be configured that may not have a UI to allow user configuration.
MIT License
15 stars 10 forks source link

Just to clarify for anybody INSTALL + tried to run the PWA #15

Open spacewalkingninja opened 4 years ago

spacewalkingninja commented 4 years ago

Hey guys! Im just going to get this clear-er for people trying this out in this day and age. Or even myself if I forget later, lol. So. Im installing this on RPI 3b+ with raspbian.

When you run sudo setcap cap_net_raw+eip $(eval readlink -fwhich node) if you get an error because of the symlink just run which node and do sudo setcap cap_net_raw+eip #OUTPUT FROM WHICH NODE HERE#

Then, you might get errors building the bluetooth-hci-manager. For this you might need to downgrade node

So, install n, globally if you haven't.

sudo npm install -g n

and then downgrade to 9.11.2 using the n package.

sudo n 9.11.2

This done, you should be able to run the manager on your server. The pwa.. is a whole different story, just spent a couple of hours trying to run it but sapper and svelte aren't my area and there's virtually no docs.

Im now trying to get connected to a wifi network using only Light Blue and then if it works, I'll implement it in my web app.

peterfealey commented 2 years ago

npm install bleno@npm:@abandonware/bleno

spacewalkingninja commented 2 years ago

Hmmm, peterfealey, I understand the command but please clarify so future users can understand what exactly happens by typing such a set of characters and depressing the "enter" key after that? Thanks.

peterfealey commented 2 years ago

Good point @spacewalkingninja and sorry for being lazy!

The folks over at: abandonware have been maintaining bluetooth-hci-manager and rolling in pull requests/changes to keep the module alive.

Using their module npm install bleno@npm:@abandonware/bleno in place of plain ol' npm install bleno allows the package to install, and then run on my Ubuntu dev machine. No such luck with my aarch64 project though - and I'm so new to embedded Linux that I wouldn't know where to begin to support with that. I'm also super late to the node.js party

Out of interest did you get anywhere with the PWA? I appreciate it's been a couple of years. Trying to find something like this project elsewhere has been challenging!

spacewalkingninja commented 2 years ago

Hadn't noticed they've been updating it. Just gave a quick glance at the abandoware project. Catchy name. And quite unfortunate as this wifi manager thing is nuts. As for the pwa... I ended up using the backend of this solution for my project. I modified it but I'm kind of lazy to get all the source rn. In short, after some modifications to the backend node code I made it work on all raspbberry pi 3 and raspbbery pi 4 as a service, it turns on the bluetooth, scans wifi networks, and identifies itself as a bluetooth receiver thing (bluetooth possibly could broadcast the networks' names, but I had some problems and stalled there because except this it was working). Then, IN my case, the user has to be in range, and on their Bluetooth enabled PC / smartphone they will access a simple web page. It is:

   <div id="netwerks">
   <label>Network</label>
   <br>
   <input type="text" id="network"/>
   </div>
    
   <div class="checkbox" id="wpas">
   <input type="checkbox" id="WPA2" value=""/>
   <label>WPA2 Password</label><div class="clear"></div>
   </div>
    
   <div id="passwordfield" style="display:none">
   <label>Password</label>
   <input type="text" id="wpa2Password"/>
   </div>
    
  <button type="button" id="connectQuery">Connect!</button>
   
  <input type="text" id='status'/>

And the JS code is:

var savedResolve;
var popupClosed = new Promise(function (resolve, reject) {
    console.log("got here");
    savedResolve = resolve;
});
$(window).on("load", function () {
    function ulog(logval) {
        $("#status").val(logval);
    }
    function wait(ms) {
        return new Promise((r) => setTimeout(r, ms));
    }
    async function onButtonClick() {
        keymgmt = "0";
        pass = "NONE";
        usernet = $("#network").val();
        console.log("ako");
        if ($("#WPA2").prop("checked")) {
            pass = $("#wpa2Password").val();
            keymgmt = "5";
        }
        const encoder = new TextEncoder("utf-8");
        passcode = encoder.encode(pass);
        console.log(passcode);
        key = encoder.encode(keymgmt);
        net = encoder.encode(usernet);
        try {
            ulog("Requesting RIFT Server...");
            const device = await navigator.bluetooth.requestDevice({ filters: [{ name: ["RIFT Controller"] }], optionalServices: ["00010000-89bd-43c8-9231-40f6e305f96d"] });
            ulog("Connecting to RIFT Server...");
            const server = await device.gatt.connect();
            ulog("Getting BTService...");
            const service = await server.getPrimaryService("00010000-89bd-43c8-9231-40f6e305f96d");
            ulog("Setting Network Characteristic...");
            const characteristicSetNetwork = await service.getCharacteristic("00010001-89bd-43c8-9231-40f6e305f96d");
            let networkName = net;
            await characteristicSetNetwork.writeValue(networkName);
            ulog("Setting Network Keymgmt...");
            const characteristicSetKeymgmt = await service.getCharacteristic("00010006-89bd-43c8-9231-40f6e305f96d");
            let networkKeymgmt = key;
            await characteristicSetKeymgmt.writeValue(networkKeymgmt);
            ulog("Setting Network Pass...");
            const characteristicSetPass = await service.getCharacteristic("00010002-89bd-43c8-9231-40f6e305f96d");
            let networkPass = passcode;
            await characteristicSetPass.writeValue(networkPass);
            ulog("> " + "Connected!");
            const characteristicGetStatus = await service.getCharacteristic("00010005-89bd-43c8-9231-40f6e305f96d");
            let value = await characteristicGetStatus.readValue();
            console.log(value);
            let networksStatus = new TextDecoder().decode(value);
            ulog("> " + networksStatus);
            ip = networksStatus = networksStatus.substring(networksStatus.indexOf(",") + 1);
            if (ip != "127.0.0.1") {
                window.location.assign("http://" + ip);
                // HERE we get the device broadcasted IP once on the network and redirect the user to the device control panel
            }
            //Now I made a little hack cause the rbpi / bluetooth combo wouldn't always work first try
            //I brute force a 5 second wait and then repeat the same
            await wait(5000);
            value = await characteristicGetStatus.readValue();
            networksStatus = new TextDecoder().decode(value);
            ulog("> " + networksStatus);
            ip = networksStatus = networksStatus.substring(networksStatus.indexOf(",") + 1);
            if (ip != "127.0.0.1") {
                window.location.assign("http://" + ip); 
                // HERE we get the device broadcasted IP once on the network and redirect the user to the device control panel
            }
            characteristicGetStatus.addEventListener("characteristicvaluechanged", handleNotifications);
        } catch (error) {
            ulog("Argh! " + error);
        }
    }
    function handleNotifications(event) {
        let value = event.target.value;
        networksStatus = new TextDecoder().decode(value);
        ulog("> " + networksStatus);
    }
    $("#WPA2").change(function () {
        if (this.checked) {
            $("#passwordfield").show(200);
        } else {
            $("#passwordfield").hide();
        }
    });
    $("#connectQuery").click(function () {
        onButtonClick();
    });
});