aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/kuksa.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/kuksa.js')
-rw-r--r--src/js/kuksa.js229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/js/kuksa.js b/src/js/kuksa.js
new file mode 100644
index 0000000..8542dcb
--- /dev/null
+++ b/src/js/kuksa.js
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 Igalia, S.L.
+ *
+ * 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.
+ */
+
+import { v4 as uuidv4 } from 'uuid';
+
+const DEFAULT_TARGET = "https://localhost:8888";
+
+// TODO: use an application token when needed
+// currently using https://github.com/eclipse/kuksa.val/blob/master/kuksa_certificates/jwt/super-admin.json.token
+const TEST_TOKEN =
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA';
+
+var kuksa_context = {
+ authToken: TEST_TOKEN,
+ client: undefined,
+ target: DEFAULT_TARGET,
+ subscribe_entries: [],
+ subscribe_stream: null,
+ locks: new Map()
+}
+
+var pathToHandler = null;
+
+function updateVehicleInfo(path, dp) {
+ if (!pathToHandler.has(path)) {
+ console.log('Handler not found for', path);
+ return;
+ }
+
+ var handler = pathToHandler.get(path);
+ handler.update(path, dp)
+}
+
+function send(action, values) {
+}
+
+function add_subscribe_entry(path) {
+ console.log('Adding subscribe entry for ' + path + '...')
+ var entry = new VAL.SubscribeEntry();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_PATH);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ kuksa_context.subscribe_entries.push(entry);
+}
+
+function subscribe() {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.SubscribeRequest();
+ for (var i in kuksa_context.subscribe_entries) {
+ var entry = kuksa_context.subscribe_entries[i];
+ entry.setView(TYPES.View.VIEW_CURRENT_VALUE);
+ request.addEntries(entry);
+ }
+
+ kuksa_context.subscribe_stream = kuksa_context.client.subscribe(request, metadata);
+
+ kuksa_context.subscribe_stream.on('data', function(response) {
+ var updates = response.getUpdatesList();
+ for (var i in updates) {
+ var update = updates[i];
+ var entry = update.getEntry();
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+
+ kuksa_context.subscribe_stream.on('error', function(error) {
+ console.log("Error code: " + error.code + " message: " + error.message);
+ // if an error happens here, the databroker will drop the subscriber, so
+ // we need to subscribe again
+ subscribe();
+ });
+}
+
+// TODO: investigate why an empty response is always being returned on the
+// response
+export function get(path) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
+ }
+
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var request = new VAL.GetRequest();
+ var entry = new VAL.EntryRequest();
+ entry.setPath(path);
+ entry.setView(TYPES.View.VIEW_ALL);
+ entry.addFields(TYPES.Field.FIELD_METADATA);
+ entry.addFields(TYPES.Field.FIELD_VALUE);
+ request.addEntries(entry);
+
+ kuksa_context.client.get(request, metadata, function(error, response) {
+ if (error) {
+ console.log("Get error, code: " + error.code);
+ return;
+ }
+ if (!response) {
+ return;
+ }
+ var entries = response.getEntriesList();
+ for (var i in entries) {
+ var entry = entries[i];
+ var path = entry.getPath();
+ var dp = entry.getValue();
+
+ if (!(entry && path && dp)) {
+ continue;
+ }
+ lock(path);
+ updateVehicleInfo(path, dp);
+ unlock(path);
+ }
+ });
+}
+
+export function set(path, dp) {
+ if (kuksa_context.client == undefined) {
+ console.log("Client not initialized.");
+ return;
+ }
+ if (isLocked(path)) {
+ return;
+ }
+ lock(path);
+
+ var metadata = {'authorization': 'Bearer ' + kuksa_context.authToken };
+
+ var entry = new TYPES.DataEntry();
+ entry.setPath(path);
+ entry.setValue(dp);
+
+ var update = new VAL.EntryUpdate();
+ update.addFields(TYPES.Field.FIELD_PATH);
+ update.addFields(TYPES.Field.FIELD_VALUE);
+ update.setEntry(entry);
+
+ var request = new VAL.SetRequest();
+ request.addUpdates(update);
+
+ kuksa_context.client.set(request, metadata, function(error, response) {
+ // don't unlock updates here, only when we get a value from
+ // the subscription updates
+ });
+}
+
+export function init(handlers) {
+ console.log("Initializing kuka-val module...");
+ pathToHandler = new Map(handlers);
+ pathToHandler.forEach(function(handler, path) {
+ add_subscribe_entry(path);
+ });
+
+ if (kuksa_context.client == undefined) {
+ console.log("Creating kuksa-val client...");
+ kuksa_context.client = new VAL_WEB.VALClient(kuksa_context.target);
+
+ subscribe();
+ }
+}
+
+export function setInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setInt32(value);
+ set(path, dp);
+}
+
+export function setUInt32(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setUint32(value);
+ set(path, dp);
+}
+
+export function setBool(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setBool(value);
+ set(path, dp);
+}
+
+export function setString(path, value) {
+ var dp = new TYPES.Datapoint();
+ dp.setString(value);
+ set(path, dp);
+}
+
+export function lock(path) {
+ kuksa_context.locks[path] = true;
+}
+
+export function unlock(path) {
+ kuksa_context.locks[path] = false;
+}
+
+export function isLocked(path) {
+ if (!kuksa_context.locks.has(path)) {
+ kuksa_context.locks[path] = false;
+ }
+ return kuksa_context.locks[path];
+}