UNPKG

rasp-blefi

Version:

Experimental project that allow headless configuration of WIFI network on Rasperry PI using BLE.

3 lines (2 loc) 8.12 kB
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t,r=require("events"),n=require("@abandonware/bleno"),i=e(n),o=e(require("util")),s=require("winston"),c=require("child_process");function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}var f=(null!==(t=process.env.BLEFI_LOG)&&void 0!==t?t:"INFO").toLowerCase(),d=!["trace","debug","info","warn","error"].includes(f),l=s.createLogger({transports:[new s.transports.Console({level:d?"debug":f,silent:d,format:s.format.combine(s.format.simple(),s.format.timestamp())})]});function h(e){var t=this;this.network=e,this._updateValueCb=null,i.Characteristic.call(this,{uuid:"fff1",properties:["read","notify"],descriptors:[new i.Descriptor({uuid:"2901",value:""})],onReadRequest:function(e,r){l.info("bluetooth on read request network status characateristic"),t.network.getStatus().then((function(e){return r(t.RESULT_SUCCESS,Buffer.from(e))})).catch((function(e){l.error("unable to get network status",{err:e}),r(t.RESULT_UNLIKELY_ERROR)}))},onSubscribe:function(e,r){l.info("bluetooth on subscribe network status characateristic"),t._updateValueCb=r,t.network.on("statusChange",(function(e){t._updateValueCb(Buffer.from(e))}))}})}function v(e){var t=this;this.network=e,i.Characteristic.call(this,{uuid:"fff2",properties:["write"],descriptors:[new i.Descriptor({uuid:"2901",value:""})],onWriteRequest:function(e,r,n,i){if(l.info("bluetooth read network credential characateristic"),r)i(t.RESULT_ATTR_NOT_LONG);else if(e.length>32||e.length<=0)i(t.RESULT_INVALID_ATTRIBUTE_LENGTH);else{var o=e.toString("utf-8").split(" "),s=o[0],c=o[1];if(!s)return l.error("network ssid is empty",{ssid:s}),void i(t.RESULT_UNLIKELY_ERROR);t.network.configureNetwork(s,c).then((function(){l.info("network successfully configured"),i(t.RESULT_SUCCESS)})).catch((function(e){l.error("unable to configure network",{err:e}),i(t.RESULT_UNLIKELY_ERROR)}))}}})}function m(e){var t=this;this.network=e,i.Characteristic.call(this,{uuid:"fff3",properties:["read"],descriptors:[new i.Descriptor({uuid:"2901",value:""})],onReadRequest:function(e,r){l.info("bluetooth read network SSID characateristic"),t.network.getConnectedSSID().then((function(e){return r(t.RESULT_SUCCESS,Buffer.from(e))})).catch((function(e){l.error("unable to get connected SSID",{err:e}),r(t.RESULT_UNLIKELY_ERROR)}))}})}function w(e){i.PrimaryService.call(this,{uuid:"fff1",characteristics:[new h(e),new v(e),new m(e)]})}o.inherits(h,n.Characteristic),o.inherits(v,n.Characteristic),o.inherits(m,n.Characteristic),o.inherits(w,n.PrimaryService),"undefined"!=typeof Symbol&&(Symbol.iterator||(Symbol.iterator=Symbol("Symbol.iterator"))),"undefined"!=typeof Symbol&&(Symbol.asyncIterator||(Symbol.asyncIterator=Symbol("Symbol.asyncIterator")));var p,g=function(e,t,r,n){try{return l.info("set wpa_cli network variable",{networkId:t,name:r}),Promise.resolve(b(e,"set_network",t,r,n)).then((function(){}))}catch(e){return Promise.reject(e)}};function S(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];var n=t.join(" ");return l.info("execute shell command",{cmd:n}),new Promise((function(e,t){c.exec(n,(function(r,n,i){return r?(l.error("shell command execution failed",{error:r}),void t(r)):i?(l.error("shell command execution error",{stderr:i}),void t(r)):void e(n.trim())}))}))}function b(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];return l.info("execute wpa_cli command",{ifname:e,args:r}),S.apply(void 0,["wpa_cli","-i",e].concat(r))}!function(e){e.connected="connected",e.disconnected="disconnected"}(p||(p={}));var k,_=function(e){function t(t){var r;return(r=e.call(this)||this).ssid="",r.ifName=t,setInterval((function(){l.debug("watch for status change"),r.hasStatusChanged(r.status)&&r.emit("statusChange",r.status,r.ssid)}),1e3),r}a(t,e);var r=t.prototype;return r.getConnectedSSID=function(){try{var e=this;return Promise.resolve(function(e){try{return l.info("get connected wifi network SSID",{ifname:e}),Promise.resolve(S.apply(void 0,["iwgetid","-r",e]))}catch(e){return Promise.reject(e)}}(e.ifName)).then((function(t){return e.ssid=t,e.ssid}))}catch(e){return Promise.reject(e)}},r.getStatus=function(){try{var e=this;return l.info("get WIFI network connection status"),Promise.resolve(e.getConnectedSSID()).then((function(t){return e.status=t?p.connected:p.disconnected,e.status}))}catch(e){return Promise.reject(e)}},r.hasStatusChanged=function(e){try{return l.info("check if network connection status has changed"),Promise.resolve(this.getStatus()).then((function(t){return t!==e}))}catch(e){return Promise.reject(e)}},r.configureNetwork=function(e,t){try{var r,n=this;l.info("configure WIFI network",{ssid:e});var i=function(i,o){try{var s=Promise.resolve(function(e,t){try{return l.info("find wpa_cli network by SSID",{ifname:e,ssid:t}),Promise.resolve(function(e){try{return l.info("execute wpa_cli list networks",{ifname:e}),Promise.resolve(b(e,"list_networks")).then((function(e){return e.split("\n").map((function(e){var t=e.split("\t");return{networkId:parseInt(t[0],10),ssid:t[1],bssid:t[2],flags:t[3]}}))}))}catch(e){return Promise.reject(e)}}(e)).then((function(e){return e.find((function(e){return e.ssid===t}))}))}catch(e){return Promise.reject(e)}}(n.ifName,e)).then((function(i){function o(){return Promise.resolve(g(n.ifName,r,"ssid","'\""+e+"\"'")).then((function(){return Promise.resolve(g(n.ifName,r,"psk","'\""+t+"\"'")).then((function(){return Promise.resolve(function(e,t){try{return l.info("enable wpa_cli network",{ifname:e,networkId:t}),Promise.resolve(b(e,"enable_network",t))}catch(e){return Promise.reject(e)}}(n.ifName,r)).then((function(){}))}))}))}var s=function(){if(!i.networkId)return Promise.resolve(function(e){try{return l.info("create new wpa_cli network",{ifname:e}),Promise.resolve(b(e,"add_network")).then((function(e){return parseInt(e,10)}))}catch(e){return Promise.reject(e)}}(n.ifName)).then((function(e){r=e}));r=i.networkId}();return s&&s.then?s.then(o):o()}))}catch(e){return o()}return s&&s.then?s.then(void 0,o):s}(0,(function(){var e=function(){if(r)return Promise.resolve(function(e,t){try{return l.info("remove wpa_cli network",{ifname:e}),Promise.resolve(b(e,"remove_network",t))}catch(e){return Promise.reject(e)}}(n.ifName,r)).then((function(){}))}();return e&&e.then?e.then((function(){})):void 0}));return Promise.resolve(i&&i.then?i.then((function(){})):void 0)}catch(e){return Promise.reject(e)}},t}(r.EventEmitter);!function(e){e.POWERED_ON="poweredOn",e.POWERED_OFF="poweredOff"}(k||(k={})),exports.NetworkConfigurator=function(e){function t(t){var r,n;(n=e.call(this)||this).deviceName=t.deviceName,n.network=new _(t.ifName),l.info("configure network configurator",{deviceName:t.deviceName,ifName:t.ifName});var o=null!==(r=t.customServices)&&void 0!==r?r:[],s=new w(n.network);return n.services=[s].concat(o),i.on("stateChange",n.stateChange.bind(u(n))),i.on("advertisingStart",n.advertisingStart.bind(u(n))),n.network.on("statusChange",(function(e,t){return n.emit("statusChange",e,t)})),n}a(t,e);var r=t.prototype;return r.stateChange=function(e){switch(l.info("bluetooth services state change",{event:e}),e){case k.POWERED_ON:var t=this.services.map((function(e){return e.uuid}));i.startAdvertising(this.deviceName,t,(function(){l.info("bluetooth services advertising started")}));break;case k.POWERED_OFF:i.stopAdvertising((function(){return l.warn("bluetooth services advertising stopped")}));break;default:l.debug("bluetooth services triggered unhandled event",{event:e})}},r.advertisingStart=function(e){l.debug("advertising start callback called"),e?l.error("bluetooth advertising starting failed",e):i.setServices(this.services,(function(e){e?l.error("bluetooth services registration failed",e):l.info("bluetooth services registered")}))},t}(r.EventEmitter); //# sourceMappingURL=rasp-blefi.cjs.production.min.js.map