aboutsummaryrefslogtreecommitdiffstats
path: root/htdocs
diff options
context:
space:
mode:
Diffstat (limited to 'htdocs')
-rw-r--r--htdocs/AFB.js3
-rw-r--r--htdocs/CMakeLists.txt33
-rw-r--r--htdocs/amazon.js323
-rw-r--r--htdocs/binding.js88
-rw-r--r--htdocs/index.html61
5 files changed, 36 insertions, 472 deletions
diff --git a/htdocs/AFB.js b/htdocs/AFB.js
index b07efc5..2cf3aec 100644
--- a/htdocs/AFB.js
+++ b/htdocs/AFB.js
@@ -210,7 +210,8 @@ var AFB_websocket;
/*********************************************/
return {
context: AFB_context,
- ws: AFB_websocket
+ ws: AFB_websocket,
+ url: urlws
};
};
diff --git a/htdocs/CMakeLists.txt b/htdocs/CMakeLists.txt
deleted file mode 100644
index 7aa0ce1..0000000
--- a/htdocs/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-###########################################################################
-# Copyright 2015, 2016, 2017 IoT.bzh
-#
-# author: Fulup Ar Foll <fulup@iot.bzh>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###########################################################################
-
-
-
-##################################################
-# HTML Testing Files
-##################################################
-PROJECT_TARGET_ADD(htdocs)
-
- file(GLOB SOURCE_FILES "*.html" "*.js" "*.jpg" "*.css" "assets")
-
- add_input_files("${SOURCE_FILES}")
-
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- LABELS "HTDOCS"
- OUTPUT_NAME ${TARGET_NAME}
- )
diff --git a/htdocs/amazon.js b/htdocs/amazon.js
deleted file mode 100644
index 05704f1..0000000
--- a/htdocs/amazon.js
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-AMAZON = function() {
-
-var afb;
-var alexaWs;
-
-var base = {
- base: "api",
- token: "HELLO",
-};
-
-// GUID generator for generating device serial number.
-function guid() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
-}
-
-/*********************************************/
-/**** ****/
-/**** AMAZON_cbl ****/
-/**** ****/
-/*********************************************/
-var AMAZON_Cbl;
-{
- const amazonHostUrl = "https://api.amazon.com";
- const amazonCodePairUrl = amazonHostUrl + "/auth/O2/create/codepair";
- const amazonTokenUrl = amazonHostUrl + "/auth/O2/token";
- const deviceSerialNumber = guid();
- var clientID = localStorage.getItem("client_id");
- var productID = localStorage.getItem("product_id");
- var alexaVAAddress = localStorage.getItem("alexa_va_address");
- var alexaVAConnected = false;
- var alexaVAAddressInput;
- var clientIDInput;
- var productIDInput;
-
- AMAZON_Cbl = function() {
- // Alexa VA Address
- const alexaVAAddressInput = document.getElementById('alexa-va-address');
- alexaVAAddress = alexaVAAddressInput.value;
- connectToAlexaVA(alexaVAAddress);
-
- alexaVAAddressInput.addEventListener("change",(evt) => {
- var newAlexaVAAddress = alexaVAAddressInput.value;
- if (alexaVAAddress != newAlexaVAAddress) {
- connectToAlexaVA(newAlexaVAAddress);
- localStorage.setItem("alexa_va_address", newAlexaVAAddress);
- }
- });
-
- // Client ID
- const clientIDInput = document.getElementById('client-id');
- clientIDInput.addEventListener("change",(evt) => {
- var newClientID = clientIDInput.value;
- if (clientID != newClientID) {
- clientID = newClientID;
- localStorage.setItem("client_id", newClientID);
- }
- });
-
- // Product ID
- const productIDInput = document.getElementById('product-id');
- productIDInput.addEventListener("change",(evt) => {
- var newProductID = productIDInput.value;
- if (productID != newProductID) {
- productID = newProductID;
- localStorage.setItem("product_id", newProductID);
- }
- });
- }
-
- function connectToAlexaVA(address) {
- base.host = address;
- afb = new AFB(base, "secret");
-
- function onopen() {
- console.log("Connected to Alexa VA");
- alexaVAConnected = true;
- }
-
- function onabort() {
- console.log("Alexa VA connection aborted.");
- alexaVAConnected = false;
- }
-
- alexaWs = new afb.ws(onopen, onabort);
- }
-
- function sendRequest(httpReq, paramsJson, url, responseCb) {
- httpReq.onreadystatechange = responseCb;
- var paramsQueryString = Object.keys(paramsJson).map(key => key + '=' + paramsJson[key]).join('&');
- httpReq.open("POST", url, true);
- httpReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- httpReq.send(paramsQueryString);
- }
-
- //**********************************************
- // Generic function to call VA binder
- //***********************************************
- function callVABinder(voiceAgent, verb, query) {
- console.log(voiceAgent.api, verb, query);
-
- // ws.call return a Promise
- return alexaWs.call(voiceAgent.api + '/' + verb, query)
- .then(function (res) {
- log.reply(res);
- count++;
- return res;
- })
- .catch(function (err) {
- log.reply(err);
- count++;
- throw err;
- });
- };
-
- function updateAccessToken(voiceAgent, tokenResponseJson) {
- if (alexaVAAddress === undefined || alexaVAAddress === null) {
- console.log("No Alexa VA. So not updating the access token.");
- return;
- }
-
- // store the access and refresh tokens.
- if (typeof(Storage) !== "undefined") {
- localStorage.setItem("access_token", tokenResponseJson["access_token"]);
- localStorage.setItem("refresh_token", tokenResponseJson["refresh_token"]);
- }
-
- // Set the auth token
- if (alexaVAConnected) {
- // Set new token
- const query = {"token": tokenResponseJson["access_token"]};
- callVABinder(voiceAgent, 'setAuthToken', query);
- }
-
- // Refresh the token as soon as it expires.
- setTimeout(refreshToken, tokenResponseJson["expires_in"] * 1000);
- }
-
- function refreshToken(voiceAgent) {
- if (voiceAgent == "undefined") {
- console.log("Error: VoiceAgent undefined");
- return;
- }
-
- var refreshToken = localStorage.getItem("refresh_token");
- if (refreshToken == null) {
- console.log("Error: No refresh token");
- return;
- }
-
- var paramsJson = {
- "grant_type":"refresh_token",
- "refresh_token":refreshToken,
- "client_id":clientID,
- };
-
- const tokenRefreshReq = new XMLHttpRequest();
- sendRequest(tokenRefreshReq, paramsJson, amazonTokenUrl, function() {
- if (tokenRefreshReq.readyState == 4) {
- if (tokenRefreshReq.status == 200) {
- console.log("Got access token " + tokenRefreshReq.responseText);
- var tokenResponseJson = JSON.parse(tokenRefreshReq.responseText);
- updateAccessToken(voiceAgent, tokenResponseJson);
- } else {
- console.log("Failed to refresh access token: " + tokenRefreshReq.responseText);
- }
- }
- });
- }
-
- function displayUserCodeAndURI(authResponseJson) {
- const modal = document.getElementById('login-with-amazon');
- const cblStatusDiv = document.createElement("div");
- const cblStatusMsg = document.createElement("p");
- const blank = "_blank";
-
- var cblPage = authResponseJson["verification_uri"] + "?cbl-code=" + authResponseJson["user_code"]
- var msg = "To use Alexa,you must sign in to Amazon.<br> Go to " +
- "<a href=" + cblPage + " target="+ blank+ " >" +
- cblPage + "</a>";
- cblStatusMsg.innerHTML = msg;
- cblStatusDiv.appendChild(cblStatusMsg);
- modal.appendChild(cblStatusDiv);
-
- const closeBtn = document.createElement("button");
- closeBtn.addEventListener('click', (evt) => {
- modal.close();
- });
- closeBtn.style = "margin: 10px";
- closeBtn.innerHTML = "Close";
- modal.appendChild(closeBtn);
- }
-
- function hideLoginUI() {
- const loginDiv = document.getElementById('login-area');
- loginDiv.style.display = "none";
- }
-
- function login(voiceAgent) {
- if (voiceAgent == undefined) {
- console.log("Error: VoiceAgent undefined");
- return;
- }
-
- const modal = document.getElementById('login-with-amazon');
- const submitBtn = document.getElementById('submit-btn');
- const cancelBtn = document.getElementById('cancel-btn');
- submitBtn.addEventListener('click', (evt) => {
- console.log("Alexa Destination address set to: " + alexaVAAddress);
- startLoginProcess(voiceAgent);
- });
-
- cancelBtn.addEventListener('click', (evt) => {
- modal.close();
- });
-
- const alexaVAAddressInput = document.getElementById('alexa-va-address');
- alexaVAAddressInput.value = alexaVAAddress;
-
- const clientIDInput = document.getElementById('client-id');
- clientIDInput.value = clientID;
-
- const productIDInput = document.getElementById('product-id');
- productIDInput.value = productID;
-
- modal.showModal();
- }
-
- function startLoginProcess(voiceAgent) {
- if (clientID == null || productID == null || alexaVAAddress == null) {
- console.log("Required information missing to start login process.");
- return;
- }
-
- var reqJson = {
- "response_type": "device_code",
- "client_id": clientID,
- "scope":"alexa:all",
- "scope_data": JSON.stringify({
- "alexa:all": {
- "productID":productID,
- "productInstanceAttributes" : {
- "deviceSerialNumber": deviceSerialNumber
- }
- }
- })
- };
-
- const authReq = new XMLHttpRequest();
- var tokenUrl = amazonTokenUrl;
- sendRequest(authReq, reqJson, amazonCodePairUrl, function() {
- if (authReq.readyState == 4) {
- if (authReq.status == 200) {
- var authResponse = JSON.parse(authReq.responseText);
- console.log("Got auth codepair " + authReq.responseText);
- hideLoginUI();
- displayUserCodeAndURI(authResponse);
- var maxTokenReqCnt = authResponse["expires_in"] / authResponse["interval"];
- var tokenReqFuncId = setTimeout(function tokenReqFunc() {
- var reqJson = {
- "grant_type":"device_code",
- "device_code":authResponse["device_code"],
- "user_code":authResponse["user_code"]
- };
- const tokenReq = new XMLHttpRequest();
- sendRequest(tokenReq, reqJson, tokenUrl, function() {
- if (tokenReq.readyState == 4) {
- if (tokenReq.status == 200) {
- console.log("Got access token " + tokenReq.responseText);
- var tokenResponseJson = JSON.parse(tokenReq.responseText);
- updateAccessToken(voiceAgent, tokenResponseJson);
- }
- else {
- maxTokenReqCnt--;
- console.log("Retrying... " + tokenReq.responseText);
- setTimeout(tokenReqFunc, authResponse["interval"] * 1000);
- }
- }
- });
- }, authResponse["interval"] * 1000);
- // Cancel if max token request attempts are reached.
- if (maxTokenReqCnt == 0) {
- console.log("Reached max token request attemps limit.");
- }
- } else {
- console.log(authReq.status);
- }
- }
- });
- }
-
- AMAZON_Cbl.prototype = {
- login: login,
- refreshToken: refreshToken,
- };
-}
-/*********************************************/
-/**** ****/
-/**** ****/
-/**** ****/
-/*********************************************/
-return {
- cbl: AMAZON_Cbl
-};
-}; \ No newline at end of file
diff --git a/htdocs/binding.js b/htdocs/binding.js
index 7e7439b..c5ceb06 100644
--- a/htdocs/binding.js
+++ b/htdocs/binding.js
@@ -1,18 +1,14 @@
-var afb = new AFB("api", "mysecret");
+var afbVshlCore;
var ws;
var evtIdx = 0;
var count = 0;
-
-var amazon = new AMAZON();
-var amazonCbl;
-
//**********************************************
// Logger
//**********************************************
var log = {
- command: function (api, verb, query) {
+ command: function (url, api, verb, query) {
console.log("subscribe api=" + api + " verb=" + verb + " query=", query);
- var question = afb.url + "/" + api + "/" + verb + "?query=" + JSON.stringify(query);
+ var question = url + "/" + api + "/" + verb + "?query=" + JSON.stringify(query);
log._write("question", count + ": " + log.syntaxHighlight(question));
},
@@ -67,8 +63,8 @@ var log = {
//**********************************************
// Generic function to call binder
//***********************************************
-function callbinder(api, verb, query) {
- log.command(api, verb, query);
+function callbinder(url, api, verb, query) {
+ log.command(url, api, verb, query);
// ws.call return a Promise
return ws.call(api + '/' + verb, query)
@@ -84,10 +80,15 @@ function callbinder(api, verb, query) {
});
};
+
//**********************************************
-// Init - establish Websocket connection
+// connect - establish Websocket connection
//**********************************************
-function init(elemID, api, verb, query) {
+function connect(elemID, api, verb, query) {
+ connectVshlCore(elemID, api, verb, query);
+}
+
+function connectVshlCore(elemID, api, verb, query) {
function onopen() {
document.getElementById("main").style.visibility = "visible";
@@ -104,7 +105,15 @@ function init(elemID, api, verb, query) {
document.getElementById("connected").style.background = "red";
}
- ws = new afb.ws(onopen, onabort);
+ var urlparams = {
+ base: "api",
+ token: "HELLO",
+ };
+ const vshlCoreAddressInput = document.getElementById('vshl-core-address');
+ urlparams.host = vshlCoreAddressInput.value;
+
+ afbVshlCore = new AFB(urlparams, "HELLO");
+ ws = new afbVshlCore.ws(onopen, onabort);
}
function clearPre(preId) {
@@ -120,11 +129,11 @@ function fetchAndRenderVoiceAgents() {
agentsDiv.removeChild(agentsDiv.firstChild);
}
- const api = 'vshl';
+ const api = 'vshl-core';
const verb = 'enumerateVoiceAgents';
const query = {};
- log.command(api, verb, query);
+ log.command(afbVshlCore.url, api, verb, query);
return ws.call(api + '/' + verb, query)
.then(function (res) {
@@ -155,7 +164,7 @@ function addVoiceAgent(containerDiv, voiceAgent, isDefault) {
const setDefaultBtn = document.createElement("button");
setDefaultBtn.addEventListener('click', (evt) => {
const query = {"id": voiceAgent.id};
- callbinder('vshl', 'setDefaultVoiceAgent', query);
+ callbinder(afbVshlCore.url, 'vshl-core', 'setDefaultVoiceAgent', query);
fetchAndRenderVoiceAgents();
});
setDefaultBtn.innerHTML = 'SetDefault';
@@ -169,24 +178,6 @@ function addVoiceAgent(containerDiv, voiceAgent, isDefault) {
subscribeBtn.innerHTML = 'Subscribe';
agentDiv.appendChild(subscribeBtn);
- // Login implementation for Alexa Voice Agent
- if (voiceAgent.name == "Alexa") {
- amazonCbl = new amazon.cbl();
- if (typeof(Storage) !== "undefined" &&
- localStorage.getItem("access_token") !== null &&
- localStorage.getItem("refresh_token") !== null) {
- amazonCbl.refreshToken(voiceAgent);
- } else {
- const loginWithAmazonBtn = document.createElement("button");
- loginWithAmazonBtn.addEventListener('click', (evt) => {
- loginWithAmazonBtn.style.visibility = "hidden";
- amazonCbl.login(voiceAgent);
- });
- loginWithAmazonBtn.innerHTML = 'Login With Amazon!!';
- agentDiv.appendChild(loginWithAmazonBtn);
- }
- }
-
containerDiv.appendChild(agentDiv);
}
@@ -210,7 +201,7 @@ function showAgentEventChooserDialog(voiceAgentId) {
if (connectionState)
query.events.push('voice_connectionstate_event');
- callbinder('vshl', 'subscribe', query);
+ callbinder(afbVshlCore.url, 'vshl-core', 'subscribe', query);
modal.close();
});
@@ -218,31 +209,6 @@ function showAgentEventChooserDialog(voiceAgentId) {
modal.showModal();
}
-function showTemplateUIEventChooserDialog() {
- const modal = document.getElementById('templateui-event-chooser');
- const subscribeBtn = document.getElementById('templateui-subscribe-btn');
-
- subscribeBtn.addEventListener('click', (evt) => {
- const renderTemplate = document.getElementById('render_template').checked;
- const clearTemplate = document.getElementById('clear_template').checked;
- const renderPlayerInfo = document.getElementById('render_player_info').checked;
- const clearPlayerInfo = document.getElementById('clear_player_info').checked;
-
- const query = {"actions":[]};
-
- if (renderTemplate)
- query.actions.push('render_template');
- if (clearTemplate)
- query.actions.push('clear_template');
- if (renderPlayerInfo)
- query.actions.push('render_player_info');
- if (clearPlayerInfo)
- query.actions.push('clear_player_info');
-
- callbinder('vshl', 'guiMetadata/subscribe', query);
- modal.close();
- });
-
- // makes modal appear (adds `open` attribute)
- modal.showModal();
+function startListening() {
+ callbinder(afbVshlCore.url, 'vshl-core', 'startListening', {});
} \ No newline at end of file
diff --git a/htdocs/index.html b/htdocs/index.html
index bf5f840..4e10f66 100644
--- a/htdocs/index.html
+++ b/htdocs/index.html
@@ -1,22 +1,22 @@
<html>
<head>
- <title>VSHL API Test</title>
+ <title>VSHL CORE API Test</title>
<link rel="stylesheet" href="binding.css">
<script type="text/javascript" src="AFB.js"></script>
<script type="text/javascript" src="amazon.js"></script>
<script type="text/javascript" src="binding.js"></script>
</head>
-<body class="page-content" onload="init()">
+<body class="page-content" onload="connect()">
<h1>Voice Service High Level API Tester</h1>
<button id="connected" onclick="init()">Binder WS Fail</button>
<button id="monitoring" onclick="window.open('/monitoring/monitor.html','_monitor_ctl')">Debug/Monitoring</a>
</button>
- <button onclick="clearPre('question'); clearPre('output'); clearPre('outevt');">Clear</button>
-
+ <button onclick="clearPre('question'); clearPre('output'); clearPre('outevt');">Clear</button> <br><br>
+ VSHL CORE URL: <input type="text" id="vshl-core-address" value="localhost:1111" onchange="connectVshlCore()"> <br><br>
<br>
<br>
@@ -43,60 +43,13 @@
</footer>
</dialog>
- <dialog id="templateui-event-chooser">
- <h3 class="dialogheader">Subscribe to the following GUI Metadata Messages</h3>
- <div>
- <ol>
- <li>
- <input type="checkbox" id="render_template" checked>
- <label>render_template</label>
- </li>
- <li>
- <input type="checkbox" id="clear_template" checked>
- <label>clear_template</label>
- </li>
- <li>
- <input type="checkbox" id="render_player_info" checked>
- <label>render_player_info</label>
- </li>
- <li>
- <input type="checkbox" id="clear_player_info" checked>
- <label>clear_player_info</label>
- </li>
- </ol>
- </div>
- <footer>
- <button id="templateui-subscribe-btn" type="button" style="margin: 10px">Subscribe</button>
- </footer>
- </dialog>
-
- <dialog id="login-with-amazon">
- <h3 class="dialogheader">Login with Amazon !!</h3>
- <div id="login-area">
- <div>
- Alexa VA URL: <input type="text" id="alexa-va-address" value="localhost:1111"> <br><br>
- Client ID : <input type="text" id="client-id"> <br><br>
- Product ID : <input type="text" id="product-id"> <br><br>
- To generate client and product ID, please register a new AVS product for
- <i><b>Other devices and platforms</b></i> using instructions in
- <a href="https://developer.amazon.com/docs/alexa-voice-service/register-a-product.html" target="_blank">this </a>
- link.<br><br>
- </div>
- <footer id ="login-with-amazon-footer">
- <button id="submit-btn" type="button" style="margin: 10px">Login</button>
- <button id="cancel-btn" type="button" style="margin: 10px">Cancel</button>
- </footer>
- </div>
- </dialog>
-
<div id="top" class="row">
<div id='actions' class="col1">
<div>
- <h2>VSHL APIs</h2>
- <p>APIs that are voiceagent agnostic</p>
- <button onclick="callbinder('vshl','startListening',{});">startListening</button>
+ <h2>VSHL CORE APIs</h2>
+ <p>Speech framework's VSHL Core APIs</p>
+ <button onclick="startListening()">startListening</button>
<button onclick="fetchAndRenderVoiceAgents();">enumerateAgents</button>
- <button onclick="showTemplateUIEventChooserDialog();">Subscribe to GUI Metadata</button>
</div>
<div id="agentsDiv">