diff options
Diffstat (limited to 'htdocs')
-rw-r--r-- | htdocs/AFB-websock.js | 172 | ||||
-rw-r--r-- | htdocs/AudioBinding.js | 67 | ||||
-rw-r--r-- | htdocs/README.md | 2 | ||||
-rw-r--r-- | htdocs/alsa-core.html | 44 | ||||
-rw-r--r-- | htdocs/audio-logic.html | 47 | ||||
-rw-r--r-- | htdocs/websock.js | 117 |
6 files changed, 271 insertions, 178 deletions
diff --git a/htdocs/AFB-websock.js b/htdocs/AFB-websock.js new file mode 100644 index 0000000..f904a58 --- /dev/null +++ b/htdocs/AFB-websock.js @@ -0,0 +1,172 @@ +AFB = function(base, initialtoken){ + +var urlws = "ws://"+window.location.host+"/"+base; +var urlhttp = "http://"+window.location.host+"/"+base; + +/*********************************************/ +/**** ****/ +/**** AFB_context ****/ +/**** ****/ +/*********************************************/ +var AFB_context; +{ + var UUID = undefined; + var TOKEN = initialtoken; + + var context = function(token, uuid) { + this.token = token; + this.uuid = uuid; + } + + context.prototype = { + get token() {return TOKEN;}, + set token(tok) {if(tok) TOKEN=tok;}, + get uuid() {return UUID;}, + set uuid(id) {if(id) UUID=id;} + }; + + AFB_context = new context(); +} +/*********************************************/ +/**** ****/ +/**** AFB_websocket ****/ +/**** ****/ +/*********************************************/ +var AFB_websocket; +{ + var CALL = 2; + var RETOK = 3; + var RETERR = 4; + var EVENT = 5; + + var PROTO1 = "x-afb-ws-json1"; + + AFB_websocket = function(onopen, onabort) { + var u = urlws; + if (AFB_context.token) { + u = u + '?x-afb-token=' + AFB_context.token; + if (AFB_context.uuid) + u = u + '&x-afb-uuid=' + AFB_context.uuid; + } + this.ws = new WebSocket(u, [ PROTO1 ]); + this.pendings = {}; + this.awaitens = {}; + this.counter = 0; + this.ws.onopen = onopen.bind(this); + this.ws.onerror = onerror.bind(this); + this.ws.onclose = onclose.bind(this); + this.ws.onmessage = onmessage.bind(this); + this.onopen = onopen; + this.onabort = onabort; + } + + function onerror(event) { + var f = this.onabort; + if (f) { + delete this.onopen; + delete this.onabort; + f && f(this); + } + this.onerror && this.onerror(this); + } + + function onopen(event) { + var f = this.onopen; + delete this.onopen; + delete this.onabort; + f && f(this); + } + + function onclose(event) { + for (var id in this.pendings) { + var ferr = this.pendings[id].onerror; + ferr && ferr(null, this); + } + this.pendings = {}; + this.onclose && this.onclose(); + } + + function fire(awaitens, name, data) { + var a = awaitens[name]; + if (a) + a.forEach(function(handler){handler(data);}); + var i = name.indexOf("/"); + if (i >= 0) { + a = awaitens[name.substring(0,i)]; + if (a) + a.forEach(function(handler){handler(data);}); + } + a = awaitens["*"]; + if (a) + a.forEach(function(handler){handler(data);}); + } + + function reply(pendings, id, ans, offset) { + if (id in pendings) { + var p = pendings[id]; + delete pendings[id]; + var f = p[offset]; + f(ans); + } + } + + function onmessage(event) { + var obj = JSON.parse(event.data); + var code = obj[0]; + var id = obj[1]; + var ans = obj[2]; + AFB_context.token = obj[3]; + switch (code) { + case RETOK: + reply(this.pendings, id, ans, 0); + break; + case RETERR: + reply(this.pendings, id, ans, 1); + break; + case EVENT: + default: + fire(this.awaitens, id, ans); + break; + } + } + + function close() { + this.ws.close(); + } + + function call(method, request) { + return new Promise((function(resolve, reject){ + var id, arr; + do { + id = String(this.counter = 4095 & (this.counter + 1)); + } while (id in this.pendings); + this.pendings[id] = [ resolve, reject ]; + arr = [CALL, id, method, request ]; + if (AFB_context.token) arr.push(AFB_context.token); + this.ws.send(JSON.stringify(arr)); + }).bind(this)); + } + + function onevent(name, handler) { + var id = name; + var list = this.awaitens[id] || (this.awaitens[id] = []); + list.push(handler); + } + + AFB_websocket.prototype = { + close: close, + call: call, + onevent: onevent + }; +} +/*********************************************/ +/**** ****/ +/**** ****/ +/**** ****/ +/*********************************************/ +return { + context: AFB_context, + ws: AFB_websocket +}; +}; + diff --git a/htdocs/AudioBinding.js b/htdocs/AudioBinding.js new file mode 100644 index 0000000..a1267b1 --- /dev/null +++ b/htdocs/AudioBinding.js @@ -0,0 +1,67 @@ + var afb = new AFB("api", "mysecret"); + var ws; + var evtidx=0; + + function getParameterByName(name, url) { + if (!url) { + url = window.location.href; + } + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, " ")); + } + + // default soundcard is hw:0 + var devid=getParameterByName("devid"); + if (!devid) devid="hw:0"; + + var sndname=getParameterByName("sndname"); + if (!sndname) sndname="PCH"; + + function init() { + ws = new afb.ws(onopen, onabort); + } + + function onopen() { + document.getElementById("main").style.visibility = "visible"; + document.getElementById("connected").innerHTML = "Binder WS Active"; + document.getElementById("connected").style.background = "lightgreen"; + ws.onevent("*", gotevent); + } + + function onabort() { + document.getElementById("main").style.visibility = "hidden"; + document.getElementById("connected").innerHTML = "Connected Closed"; + document.getElementById("connected").style.background = "red"; + + } + + function replyok(obj) { + console.log("replyok:" + JSON.stringify(obj)); + document.getElementById("output").innerHTML = "OK: "+JSON.stringify(obj); + } + + function replyerr(obj) { + console.log("replyerr:" + JSON.stringify(obj)); + document.getElementById("output").innerHTML = "ERROR: "+JSON.stringify(obj); + } + + function gotevent(obj) { + console.log("gotevent:" + JSON.stringify(obj)); + document.getElementById("outevt").innerHTML = (evtidx++) +": "+JSON.stringify(obj); + } + + function send(message) { + var api = document.getElementById("api").value; + var verb = document.getElementById("verb").value; + ws.call(api+"/"+verb, {data:message}).then(replyok, replyerr); + } + + + function callbinder(api, verb, query) { + console.log ("subscribe api="+api+" verb="+verb+" query=" +query); + ws.call(api+"/"+verb, query).then(replyok, replyerr); + }
\ No newline at end of file diff --git a/htdocs/README.md b/htdocs/README.md index 6468356..79b57d8 100644 --- a/htdocs/README.md +++ b/htdocs/README.md @@ -1,5 +1,5 @@ ------------------------------------------------------------------------ - Simple HTML test + Basic HTML & WS test ------------------------------------------------------------------------ # Load bindings directly from development tree for debug diff --git a/htdocs/alsa-core.html b/htdocs/alsa-core.html index 0969b6f..9d0fd83 100644 --- a/htdocs/alsa-core.html +++ b/htdocs/alsa-core.html @@ -2,41 +2,23 @@ <head> <title>Hello world test</title> - <script type="text/javascript" src="websock.js"></script> - <script type="text/javascript"> - var ws; + <script type="text/javascript" src="AFB-websock.js"></script> + <script type="text/javascript" src="AudioBinding.js"></script> - function onopen() { - document.getElementById("main").style.visibility = "visible"; - document.getElementById("connected").innerHTML = "WebSocket Open"; - } - function onabort() { - document.getElementById("main").style.visibility = "hidden"; - document.getElementById("connected").innerHTML = "Connected Closed"; - } - function init() { - ws = new AfbWsItf("api", onopen, onabort, new AfbCtxItf("mysecret")); - } - function replyok(obj) { - document.getElementById("output").innerHTML = "OK: "+JSON.stringify(obj); - } - function replyerr(obj) { - document.getElementById("output").innerHTML = "ERROR: "+JSON.stringify(obj); - } - function subscribe(devid) { - ws.call("alsacore", "subctl", {devid:devid}, replyok, replyerr); - } - </script> - <body onload="init();"> <h1>Hello world test</h1> + <button id="connected">Binder WS Fail</button></li> + <br> <ol> - <li><a href="api/alsacore/getinfo">getinfo: List Sound Cards</a> - <li><a href="api/alsacore/getinfo?devid=hw:0">Card info about hw:0</a> - <li><a href="api/alsacore/getctl?devid=hw:0">List controls for hw:0 (quiet)</a> - <li><a href="api/alsacore/getctl?devid=hw:0&quiet=0">List controls for hw:0 (verbose)</a> - <li><a href="api/alsacore/getctl?devid=hw:0&numid=1&quiet=0">return control numid=1 for hw:0</a> - <li><button id="connected" onclick="subscribe('hw:0')">Click to Connected</button></li> + <li><a href="api/alsacore/getinfo">getinfo: List Sound Cards</a> + <li><a href="api/alsacore/getinfo?devid=hw:0">Card info about hw:0</a> + <li><a href="api/alsacore/getctl?devid=hw:0">List controls for hw:0 (quiet)</a> + <li><a href="api/alsacore/getctl?devid=hw:0&quiet=0">List controls for hw:0 (verbose)</a> + <li><a href="api/alsacore/getctl?devid=hw:0&numid=1&quiet=0">return control numid=1 for hw:0</a> + <br> + <li><button onclick="callbinder('alsacore','subscribe', {devid:devid})">Subscribe AlsaCtl Events</button></li> + <br> <div id="main" style="visibility:hidden"> Server says... <div id="output"></div> + Events: <div id="outevt"></div> </div> diff --git a/htdocs/audio-logic.html b/htdocs/audio-logic.html index ff806ad..79ab114 100644 --- a/htdocs/audio-logic.html +++ b/htdocs/audio-logic.html @@ -2,39 +2,28 @@ <head> <title>Hello world test</title> - <script type="text/javascript" src="websock.js"></script> - <script type="text/javascript"> - var ws; - - function onopen() { - document.getElementById("main").style.visibility = "visible"; - document.getElementById("connected").innerHTML = "WebSocket Open"; - } - function onabort() { - document.getElementById("main").style.visibility = "hidden"; - document.getElementById("connected").innerHTML = "Connected Closed"; - } - function init() { - ws = new AfbWsItf("api", onopen, onabort, new AfbCtxItf("mysecret")); - } - function replyok(obj) { - document.getElementById("output").innerHTML = "OK: "+JSON.stringify(obj); - } - function replyerr(obj) { - document.getElementById("output").innerHTML = "ERROR: "+JSON.stringify(obj); - } - function subscribe(devid) { - ws.call("alsacore", "subctl", {devid:devid}, replyok, replyerr); - } - </script> + <script type="text/javascript" src="AFB-websock.js"></script> + <script type="text/javascript" src="AudioBinding.js"></script> <body onload="init();"> <h1>Hello world test</h1> + <button id="connected">Binder WS Fail</button></li> + <br> <ol> - <li><a href="api/audio/setvol?devid=hw:0&pcm=master&vol=50%">Set Master PCM volume to 50%</a> - <li><a href="api/audio/getvol?devid=hw:0&pcm=master">Get Master PCM volume</a> - <li><a href="api/alsacore/monitor?devid=hw:0">Activate devid=hw:0 monitoring</a> - <li><button id="connected" onclick="subscribe('hw:0')">Click to Subscribe</button></li> + <li><button onclick="callbinder('audio','open',{sndname: sndname})">Open SndCard</button></li> + <br> + <li><button onclick="callbinder('audio','setvol', {pcm:'master', vol='+10'})">Increase +10 Master</button></li> + <li><button onclick="callbinder('audio','setvol', {pcm:'master', vol='-10'})">Decrease -10 Master</button></li> + <li><button onclick="callbinder('audio','setvol', {pcm:'master', vol='%50'})">SetVol %50 Master</button></li> + <li><button onclick="callbinder('audio','getvol', {pcm:'master'})">GetVolume Master</button></li> + <br> + <li><button onclick="callbinder('audio','monitor')">Monitor LowLevel Events</button></li> + <li><button onclick="callbinder('audio','subscribe')">Subscribe AudioBinding Events</button></li> + <br> + <li><button onclick="callbinder('audio','close')">Close SndCard</button></li> + + <br> <div id="main" style="visibility:hidden"> Server says... <div id="output"></div> + Events: <div id="outevt"></div> </div> diff --git a/htdocs/websock.js b/htdocs/websock.js deleted file mode 100644 index c429553..0000000 --- a/htdocs/websock.js +++ /dev/null @@ -1,117 +0,0 @@ - -AfbCtxItf = (function(){ - - var UUID = undefined; - var TOKEN = undefined; - - function AfbCtxItf(token, uuid) { - this.token = token; - this.uuid = uuid; - } - - AfbCtxItf.prototype = { - get token() {return TOKEN;}, - set token(tok) {if(tok) TOKEN=tok;}, - get uuid() {return UUID;}, - set uuid(id) {if(id) UUID=id;} - }; - - return AfbCtxItf; -})(); - - -AfbWsItf = (function(){ - - var CALL = 2; - var RETOK = 3; - var RETERR = 4; - - function AfbWsItf(base, onopen, onabort, ctx) { - ctx = ctx || new AfbCtxItf(); - var wl = window.location; - var u = "ws://"+wl.host+"/"+base; - if (ctx.token) { - u = u + '?x-afb-token=' + ctx.token; - if (ctx.uuid) - u = u + '&x-afb-uuid=' + ctx.uuid; - } - this.ws = new (WebSocket || MozWebSocket)(u, [ "x-afb-ws-json1" ]); - this.pendings = {}; - this.counter = 0; - this.ctx = ctx; - this.ws.onopen = onopen.bind(this); - this.ws.onerror = onerror.bind(this); - this.ws.onclose = onclose.bind(this); - this.ws.onmessage = onmessage.bind(this); - this.onopen = onopen; - this.onabort = onabort; - } - - function onerror(event) { - var f = this.onabort; - if (f) { - delete this.onopen; - delete this.onabort; - f && f(this); - } - this.onerror && this.onerror(this); - } - - function onopen(event) { - var f = this.onopen; - delete this.onopen; - delete this.onabort; - f && f(this); - } - - function onclose(event) { - for (var id in this.pendings) { - var ferr = this.pendings[id].onerror; - ferr && ferr(null, this); - } - this.pendings = {}; - this.onclose && this.onclose(); - } - - function onmessage(event) { - var obj = JSON.parse(event.data); - var code = obj[0]; - var id = obj[1]; - var ans = obj[2]; - this.ctx.token = obj[3]; - var pend; - if (id && id in this.pendings) { - pend = this.pendings[id]; - delete this.pendings[id]; - } - switch (code) { - case RETOK: - pend && pend.onsuccess && pend.onsuccess(ans, this); - break; - case RETERR: - default: - pend && pend.onerror && pend.onerror(ans, this); - break; - } - } - - function close() { - this.ws.close(); - } - - function call(api, verb, request, onsuccess, onerror) { - var id = String(++this.counter); - this.pendings[id] = { onsuccess: onsuccess, onerror: onerror }; - var arr = [CALL, id, api+"/"+verb, request ]; - if (this.ctx.token) arr.push(this.ctx.token); - this.ws.send(JSON.stringify(arr)); - } - - AfbWsItf.prototype = { - close: close, - call: call - }; - - return AfbWsItf; -})(); - |