aboutsummaryrefslogtreecommitdiffstats
path: root/src/can-signals.cpp
blob: 5f23c40a19a01522aca38cc47367fbe064f9162a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * Copyright (C) 2015, 2016 "IoT.bzh"
 * Author "Romain Forlot" <romain.forlot@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.
 */

#include "can-signals.hpp"

#include <fnmatch.h>

#include "can-decoder.hpp"
#include "low-can-binding.hpp"

std::vector<std::vector<CanMessageDefinition>> CAN_MESSAGES = {
	{{620, CanMessageFormat::STANDARD, {10, 0, nullptr}, false, (uint8_t)NULL}},
};

/**
 * @brief Dumb SIGNALS array. It is composed by CanMessageSet
 * SIGNALS[MESSAGE_SET_ID][CanSignal]
 */
std::vector<std::vector<CanSignal>> SIGNALS = {
	{{&(CAN_MESSAGES[0][0]), "can.driver_door.open", 2, 4, 1.000000, 0.000000, 0.000000, 0.000000, {10, 0, nullptr}, false, true, nullptr, 0, false, decoder_t::booleanDecoder, nullptr, false, (float)NULL}},
};

/**
* @brief Mutex allowing safe manipulation on subscribed_signals map.
* @desc To ensure that the map object isn't modified when we read it, you
*  have to set this mutex before use subscribed_signals map object.
*/
std::mutex subscribed_signals_mutex;

std::mutex& get_subscribed_signals_mutex()
{
	return subscribed_signals_mutex;
}

const std::vector<CanSignal> getSignals()
{
	return SIGNALS[MESSAGE_SET_ID];
}

size_t getSignalCount()
{
	return SIGNALS[MESSAGE_SET_ID].size();
}

std::vector<CanSignal> find_can_signals(const openxc_DynamicField &key)
{
	std::vector<CanSignal> signals;

	switch(key.type)
	{
		case openxc_DynamicField_Type::openxc_DynamicField_Type_STRING:
			for(const CanSignal& s : getSignals())
			{
				if(fnmatch(key.string_value, s.genericName, FNM_CASEFOLD) == 0)
					signals.push_back(s);
			}
			break;
		case openxc_DynamicField_Type::openxc_DynamicField_Type_NUM:
			for(const CanSignal& s : getSignals())
			{
				CanMessageDefinition *msg_def = s.message;
				if(msg_def->id == key.numeric_value)
					signals.push_back(s);
			}
			break;
		default:
			ERROR(binder_interface, "find_can_signals: wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only.");
			CanSignal cs;
			::memset(&cs, 0, sizeof(CanSignal));
			signals.push_back(cs);
			return signals;
			break;
	}
	return signals;
}

inline uint32_t get_CanSignal_id(const CanSignal& sig)
{
	return sig.message->id;
}

const std::map<std::string, struct afb_event> get_subscribed_signals()
{
	return subscribed_signals;
}
lass="nx">PROTO1 ]; this.context = ctxt; var url = "ws:" + ctxt.refid + ctxt.uws; var q = ctxt.uuid ? ("?x-afb-uuid=" + ctxt.uuid) : ""; if (ctxt.token) q = (q ? (q + "&") : "?") + ("x-afb-token=" + ctxt.token); this.pendings = {}; this.awaitens = {}; this.counter = 0; this.ws = new WebSocket(url + q, protos); 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; } AfbWebSocket.prototype = { call: function(method, query) { return new Promise((function(resolve, reject){ var id = String(this.counter = 4095 & (this.counter + 1)); while (id in this.pendings) id = String(this.counter = 4095 & (this.counter + 1)); this.pendings[id] = [ resolve, reject ]; var arr = [CALL, id, method, request ]; var tok = this.context.token; if (tok) arr.push(tok); this.ws.send(angular.toJson(arr, 0)); }).bind(this)); }, addEvent: function (name, handler) { (this.awaitens[name] || (this.awaitens[name] = [])).push(handler); }, removeEvent: function (name, handler) { var a = this.awaitens[name]; if (a) { var i = a.indexOf(handler); if (i >= 0) a.splice(i, 1); } } }; function onmessage(ev) { var obj = angular.fromJson(ev.data); var id = obj[1]; var ans = obj[2]; if (obj[3]) this.context.token = obj[3]; switch (obj[0]) { case RETOK: reply(this.pendings, id, ans, 0); break; case RETERR: reply(this.pendings, id, ans, 1); break; case EVENT: fire(this.awaitens, id, ans); break; } } 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]; if (f) f(ans); } } AFB_websocket = function(onopen, 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 close() { this.ws.close(); } function call(method, request) { } /* // Factory is a singleton and share its context within all instances. AfbClientModule.factory('AppCall', function ($http, AppConfig, $log) { var myCalls = { get : function(plugin, action, query, callback) { if (!query.token) query.token = AppConfig.session.token; // add token to provided query $http.get('/api/' + plugin + '/' + action , {params: query}).then (callback, callback); } }; return myCalls; }); */ })();