-------------------------------------------------------
# handle dependencies > (OpenSuse-42.2, Fedora-25, Ubuntu 16.04.2LTS)
gcc > 4.8
- systemd-devel (libsystemd-dev>=222)
+ systemd-devel (libsystemd-dev>=222)
libuuid-devel
file-devel(OpenSuSe) or libmagic-dev(Ubuntu)
libjson-c-devel
ElectricFence (BUG should not be mandatory)
libopenssl-devel libgcrypt-devel libgnutls-devel (optional but requested by libmicrohttpd for https)
- OpenSuse >=42.2
+ OpenSuse >=42.2
zypper in gcc5 gdb gcc5-c++ git cmake make ElectricFence systemd-devel libopenssl-devel libuuid-devel alsa-devel libgcrypt-devel libgnutls-devel libjson-c-devel file-devel mxml-devel
Ubuntu >= 16.4 libuuid-devel
echo "#---------- AGL options Start ---------" >>~/.bashrc
echo "# Object: AGL cmake option for binder/bindings" >>~/.bashrc
echo "# Date: `date`" >>~/.bashrc
- echo 'export CC=gcc-5; export CXX=g++-5' >>~/.bashrc # if using gcc5
+ echo 'export CC=gcc-5; export CXX=g++-5' >>~/.bashrc # if using gcc5
echo 'export INSTALL_PREFIX=$HOME/opt' >>~/.bashrc
echo 'export LD_LIBRARY_PATH=$INSTALL_PREFIX/lib64:$INSTALL_PREFIX/lib' >>~/.bashrc
echo 'export LIBRARY_PATH=$INSTALL_PREFIX/lib64:$INSTALL_PREFIX/lib' >>~/.bashrc
cd app-framework-binder; mkdir -p build; cd build
cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX ..
make
- make install
+ make install
```
firefox http://localhost:1234
```
-# Archive
+# Archive
```
VERSION=0.1
GIT_TAG=master
-PKG_NAME=unicens-agent
+PKG_NAME=UNICENS-agent
git archive --format=tar.gz --prefix=${PKG_NAME}-${VERSION}/ ${GIT_TAG} -o ${PKG_NAME}_${VERSION}.orig.tar.gz
```
```
Examples:
-
+
# WORK when running in direct
afb-daemon --workdir=.. --ldpaths=build --port=1234 --roothttp=./htdocs
gdb -args afb-daemon --workdir=.. --ldpaths=build --port=1234 --roothttp=./htdocs
run
...
- NOTICE: API unicens added
+ NOTICE: API UNICENS added
NOTICE: Waiting port=1234 rootdir=.
NOTICE: Browser URL= http://localhost:1234
(hit Ctrl-C to break the execution)
# Project Info
# ------------------
-set(PROJECT_NAME unicens-agent)
+set(PROJECT_NAME UNICENS-agent)
set(PROJECT_VERSION "0.1")
set(PROJECT_PRETTY_NAME "Unicens Agent")
-set(PROJECT_DESCRIPTION "Expose MicroChip UnicensV2 through AGL AppFw")
+set(PROJECT_DESCRIPTION "Expose Microchip UNICENS v2 through AGL AppFw")
set(PROJECT_URL "https://github.com/iotbzh/unicens-agent")
set(PROJECT_ICON "icon.png")
set(PROJECT_AUTHOR "Fulup, Ar Foll")
+++ /dev/null
-###########################################################################
-# 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.
-###########################################################################
-
-
-Name: unicens-agent
-Version: 0.1
-Release: 1
-License: GPV2
-Summary: Expose MicroChip UnicensV2 through AGL AppFw
-Url: https://github.com/iotbzh/unicens-agent
-
-Provides: unicens-agent
-Prefix: /opt/unicens-agent
-BuildRequires: pkg-config , pkgconfig(libsystemd>=222), pkgconfig(libmicrohttpd>=0.9.54), pkgconfig(afb-daemon), pkgconfig(json-c), pkgconfig(mxml)
-
-BuildRoot:/home/fulup/Workspace/AGL-AppFW/unicens2rc-afb/build
-
-%description
-Expose MicroChip UnicensV2 through AGL AppFw
-
-%prep
-
-%build
-(mkdir -p build; cd build; cmake ..; make)
-
-%install
-(cd build; make populate DESTDIR=%{buildroot})
-
file(GLOB SOURCE_FILES "*.ucsx")
- add_custom_target(${TARGET_NAME}
+ add_custom_target(${TARGET_NAME}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
- )
+ )
add_custom_command(
DEPENDS ${SOURCE_FILES}
switch (code) {
case RETOK:
reply(this.pendings, id, ans, 0);
- break;
+ break;
case RETERR:
reply(this.pendings, id, ans, 1);
- break;
+ break;
case EVENT:
default:
fire(this.awaitens, id, ans);
- break;
+ break;
}
}
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
-
+
// default soundcard is "PCH"
var devid=getParameterByName("devid");
if (!devid) devid="hw:0";
-
+
var sndname=getParameterByName("sndname");
if (!sndname) sndname="PCH";
-
+
var quiet=getParameterByName("quiet");
if (!quiet) quiet="99";
-
+
function init() {
ws = new afb.ws(onopen, onabort);
}
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;
document.getElementById("question").innerHTML = "subscribe: "+api+"/"+verb + " (" + JSON.stringify(message) +")";
ws.call(api+"/"+verb, {data:message}).then(replyok, replyerr);
}
-
-
+
+
function callbinder(api, verb, query) {
console.log ("subscribe api="+api+" verb="+verb+" query=" +query);
document.getElementById("question").innerHTML = "apicall: " + api+"/"+verb +" ("+ JSON.stringify(query)+")";
ws.call(api+"/"+verb, query).then(replyok, replyerr);
- }
\ No newline at end of file
+ }
file(GLOB SOURCE_FILES "*.html" "*.js" "*.jpg")
- add_custom_target(${TARGET_NAME}
+ add_custom_target(${TARGET_NAME}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
- )
+ )
add_custom_command(
DEPENDS ${SOURCE_FILES}
<html>
<head>
<title>Hello world test</title>
-
+
<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" onclick="init()">Binder WS Fail</button></li>
<br>
<ol>
- <li><button onclick="callbinder('unicens','initialise', {filename:'data/ucs2_config/config.ucsx'})">Parse Config.ucsx</button></li>
- <li><button onclick="callbinder('unicens','setvol', {channel:'master', volume: 255})">Set Master Volume to 255</button></li>
- <li><button onclick="callbinder('unicens','setvol', {channel:'master', volume: 200})">Set Master Volume to 200</button></li>
- <li><button onclick="callbinder('unicens','setvol', [[0,200], [1,255]])">Set left=200 right=250</button></li>
- <li><button onclick="callbinder('unicens','setvol', [[0,255], [1,200]])">Set right=250 left=200</button></li>
- <li><button onclick="callbinder('unicens','setvol', [[0,255], [1,255]])">Set right=255 left=255</button></li>
+ <li><button onclick="callbinder('UNICENS','initialise', {filename:'data/config.ucsx'})">Parse Config.ucsx</button></li>
+ <li><button onclick="callbinder('UNICENS','setvol', {channel:'master', volume: 255})">Set Master Volume to 255</button></li>
+ <li><button onclick="callbinder('UNICENS','setvol', {channel:'master', volume: 200})">Set Master Volume to 200</button></li>
+ <li><button onclick="callbinder('UNICENS','setvol', [[0,200], [1,255]])">Set left=200 right=250</button></li>
+ <li><button onclick="callbinder('UNICENS','setvol', [[0,255], [1,200]])">Set right=250 left=200</button></li>
+ <li><button onclick="callbinder('UNICENS','setvol', [[0,255], [1,255]])">Set right=255 left=255</button></li>
</ol>
- <br>
+ <br>
<div id="main" style="visibility:hidden">
<ol>
<li>Question <div id="question"></div>
<li>Response <div id="output"></div>
<li>Events: <div id="outevt"></div>
</ol>
- </div>
+ </div>
<head>
<title>AGL-Unicens tests</title>
<body>
- <h1>unicens-bindings test</h1>
+ <h1>UNICENS-bindings test</h1>
<ol>
- <li><a href="unicens.html">Unicens Config</a>
+ <li><a href="UNICENS.html">UNICENS Config</a>
+++ /dev/null
-###########################################################################
-# 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.
-###########################################################################
-
-
-Name: unicens-agent
-Version: 0.1
-Release: 1
-License: Apache-V2
-Summary: Expose MicroChip UnicensV2 through AGL AppFw
-Url: https://github.com/iotbzh/unicens-agent
-Source0: %{name}_%{version}.orig.tar.gz
-
-Prefix: /opt/unicens-agent
-BuildRequires: cmake
-BuildRequires: gcc gcc-c++
-BuildRequires: pkgconfig(libsystemd) >= 222,
-BuildRequires: pkgconfig(libmicrohttpd) >= 0.9.54
-BuildRequires: pkgconfig(afb-daemon), pkgconfig(json-c), pkgconfig(mxml)
-
-BuildRoot:%{_tmppath}/%{name}-%{version}-build
-
-%description
-Expose MicroChip UnicensV2 through AGL AppFw
-
-%prep
-%setup -q
-
-%build
-%cmake -DBINDINGS_INSTALL_PREFIX:PATH=%{_libdir}
-%__make %{?_smp_mflags}
-
-%install
-[ -d build ] && cd build
-%make_install
-
-%files
-%defattr(-,root,root)
-%dir %{_libdir}/unicens-agent
-%{_libdir}/unicens-agent/afb-ucs2.so
{
"openapi": "3.0.0",
- "$schema": "file:///home/fulup/Workspace/AGL-AppFW/unicens2rc-afb/etc/openapi-schema.json",
+ "$schema": "file:///home/fulup/Workspace/AGL-AppFW/unicens2rc-afb/etc/openapi-schema.json",
"info": {
"description": "",
"title": "ucs2",
"version": "1.0",
"x-binding-c-generator": {
- "api": "unicens",
+ "api": "UNICENS",
"version": 2,
"prefix": "ucs2_",
"postfix": "",
"onevent": null,
"init": null,
"scope": "static",
- "private": true
+ "private": true
}
},
"servers": [
},
"x-permissions": {
"config": {
- "permission": "urn:AGL:permission:unicens:public:initialise"
+ "permission": "urn:AGL:permission:UNICENS:public:initialise"
},
"monitor": {
- "permission": "urn:AGL:permission:unicens:public:monitor"
+ "permission": "urn:AGL:permission:UNICENS:public:monitor"
}
},
"responses": {
}
],
"responses": {
- "200": {"$ref": "#/components/responses/200"}
+ "200": {"$ref": "#/components/responses/200"}
}
}
},
"$ref": "#/components/x-permissions/monitor"
},
"responses": {
- "200": {"$ref": "#/components/responses/200"}
+ "200": {"$ref": "#/components/responses/200"}
}
}
}
{ .name= "initialise", .session= AFB_SESSION_NONE, .callback= ucs2Init, .info= "Parse XML & initialise Unicens " },
{ .name= "setvol" , .session= AFB_SESSION_NONE, .callback= ucs2SetVol, .info= "Set Volume" },
// { .name= "monitor" , .session= AFB_SESSION_NONE, .callback= ucs2Monitor, .info= "Subscribe to network error" },
-
-
+
+
{ .name= NULL } /* marker for end of the array */
};
/* description conforms to VERSION 1 */
.type= AFB_BINDING_VERSION_1,
.v1= {
- .prefix= "unicens",
- .info= "Unicens MOST Control API",
+ .prefix= "UNICENS",
+ .info= "UNICENS MOST Control API",
.verbs = binding_verbs
- }
+ }
};
// this is call when after all bindings are loaded
*/
const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf) {
afbIface= itf;
-
+
return &binding_description; /* returns the description of the binding */
}
* 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.
- *
+ *
* references:
* https://gist.github.com/ghedo/963382
* http://alsa-utils.sourcearchive.com/documentation/1.0.15/aplay_8c-source.html
struct timespec currentTime;
uint16_t timer;
pTag = pTag;
-
+
if (clock_gettime(CLOCK_MONOTONIC_RAW, ¤tTime)) {
assert(false);
return 0;
}
-
+
timer = (uint16_t) ((currentTime.tv_sec * 1000 ) + ( currentTime.tv_nsec / 1000000 ));
- return(timer);
+ return(timer);
}
STATIC int onTimerCB (sd_event_source* source,uint64_t timer, void* pTag) {
ucsContextT *ucsContext = (ucsContextT*) pTag;
- sd_event_source_unref(source);
+ sd_event_source_unref(source);
UCSI_Timeout(&ucsContext->ucsiData);
return 0;
// UCS2 Interface Timer Callback
PUBLIC void UCSI_CB_OnSetServiceTimer(void *pTag, uint16_t timeout) {
uint64_t usec;
- // set a timer with 250ms accuracy
- sd_event_now(afb_daemon_get_event_loop(afbIface->daemon), CLOCK_BOOTTIME, &usec);
+ // set a timer with 250ms accuracy
+ sd_event_now(afb_daemon_get_event_loop(afbIface->daemon), CLOCK_BOOTTIME, &usec);
sd_event_add_time(afb_daemon_get_event_loop(afbIface->daemon), NULL, CLOCK_MONOTONIC, usec + (timeout*1000), 250, onTimerCB, pTag);
-
+
}
/**
// UCSI_Service cannot be call directly within Unicens context, need to reset stack through mainloop
STATIC int OnServiceRequiredCB (sd_event_source *source, uint64_t usec, void *pTag) {
ucsContextT *ucsContext = (ucsContextT*) pTag;
-
+
sd_event_source_unref(source);
UCSI_Service(&ucsContext->ucsiData);
return (0);
// UCS Callback fire when ever pTag instance needs to be serviced
PUBLIC void UCSI_CB_OnServiceRequired(void *pTag) {
-
+
// push an asynchronous request for loopback to call UCSI_Service
sd_event_add_time(afb_daemon_get_event_loop(afbIface->daemon), NULL, CLOCK_MONOTONIC, 0, 0, OnServiceRequiredCB, pTag);
}
PUBLIC void UCSI_CB_OnMostError(void *pTag, uint16_t sourceAddr,
uint8_t fblock, uint8_t inst, uint16_t function, uint8_t op,
const uint8_t *pPayload, uint32_t payloadLen) {
-
+
// Error to send to syslog
DEBUG (afbIface, "OnMostError source=0x%x", sourceAddr);
}
// Callback when ever this instance wants to send a message to INIC.
// BUGS?? Sample was returning true/false on error when integration layer expect a void [question from Fulup to Thorsten]
PUBLIC void UCSI_CB_SendMostMessage(void *pTag, const uint8_t *pData, uint32_t len) {
-
+
ucsContextT *ucsContext = (ucsContextT*) pTag;
CdevData_t *cdevTx = &ucsContext->tx;
uint32_t total = 0;
-
-
+
+
if (NULL == pData || 0 == len) return;
-
+
if (O_RDONLY == cdevTx->fileFlags) return;
if (-1 == cdevTx->fileHandle)
cdevTx->fileHandle = open(cdevTx->fileName, cdevTx->fileFlags);
if (-1 == cdevTx->fileHandle)
return;
-
+
while(total < len) {
ssize_t written = write(cdevTx->fileHandle, &pData[total], (len - total));
if (0 >= written)
}
total += (uint32_t) written;
}
-
- return;
+
+ return;
}
/**
*/
void UCSI_CB_OnStop(void *pTag) {
NOTICE (afbIface, "Unicens stopped");
-
+
}
/**
* \param pNode - Pointer to node structure holding details of changed node
*/
extern void UCSI_CB_OnMgrReport(void *pTag, Ucs_MgrReport_t code, uint16_t nodeAddress, Ucs_Rm_Node_t *pNode) {
-
+
DEBUG (afbIface, "OnMgrReport: Ucs_MgrReport_t=%d nodeAdresse=0x%x", code, nodeAddress);
}
bool Cdev_Init(CdevData_t *d, const char *fileName, bool read, bool write)
{
if (NULL == d || NULL == fileName) goto OnErrorExit;
-
+
memset(d, 0, sizeof(CdevData_t));
strncpy(d->fileName, fileName, MAX_FILENAME_LEN);
d->fileHandle = -1;
-
+
if (read && write)
d->fileFlags = O_RDWR | O_NONBLOCK;
else if (read)
d->fileFlags = O_RDONLY | O_NONBLOCK;
else if (write)
d->fileFlags = O_WRONLY | O_NONBLOCK;
-
+
// open file to enable event loop
- d->fileHandle = open(d->fileName, d->fileFlags);
+ d->fileHandle = open(d->fileName, d->fileFlags);
if (d->fileHandle <= 0) goto OnErrorExit;
-
+
return true;
-
+
OnErrorExit:
return false;
}
int ok;
len = read (ucsContext->rx.fileHandle, &pBuffer, sizeof(pBuffer));
-
+
ok= UCSI_ProcessRxData(&ucsContext->ucsiData, pBuffer, (uint16_t)len);
if (!ok) {
DEBUG (afbIface, "Buffer overrun (not handle)");
ssize_t readSize;
int fdHandle ;
struct stat fdStat;
- UcsXmlVal_t* ucsConfig;
+ UcsXmlVal_t* ucsConfig;
const char *filename = afb_req_value(request, "filename");
if (!filename) {
afb_req_fail_f (request, "filename-missing", "No filename given");
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
+
fdHandle = open(filename, O_RDONLY);
if (fdHandle <= 0) {
afb_req_fail_f (request, "fileread-error", "File not accessible: '%s' err=%s", filename, strerror(fdHandle));
goto OnErrorExit;
}
-
+
// read file into buffer as a \0 terminated string
fstat(fdHandle, &fdStat);
xmlBuffer = (char*)alloca(fdStat.st_size + 1);
readSize = read(fdHandle, xmlBuffer, fdStat.st_size);
close(fdHandle);
xmlBuffer[readSize] = '\0'; //In any case, terminate it.
-
+
if (readSize != fdStat.st_size) {
afb_req_fail_f (request, "fileread-fail", "File to read fullfile '%s' size(%d!=%d)", filename, readSize, fdStat.st_size);
goto OnErrorExit;
}
-
+
ucsConfig = UcsXml_Parse(xmlBuffer);
if (!ucsConfig) {
afb_req_fail_f (request, "filexml-error", "File XML invalid: '%s'", filename);
goto OnErrorExit;
}
-
+
return (ucsConfig);
-
+
OnErrorExit:
return NULL;
}
case json_type_array:
if (!sscanf (json_object_get_string (json_object_array_get_idx(commandJ, 0)), "%d", &numid)) {
afb_req_fail_f (request, "channel-invalid","command=%s channel is not an integer", json_object_get_string (channelJ));
- goto OnErrorExit;
- }
+ goto OnErrorExit;
+ }
if (!sscanf (json_object_get_string (json_object_array_get_idx(commandJ, 1)), "%d", &vol)) {
afb_req_fail_f (request, "vol-invalid","command=%s vol is not an integer", json_object_get_string (channelJ));
- goto OnErrorExit;
- }
+ goto OnErrorExit;
+ }
break;
-
- case json_type_object:
+
+ case json_type_object:
if (json_object_object_get_ex (commandJ, "numid", &channelJ)) {
if (!sscanf (json_object_get_string (channelJ), "%d", &numid)) {
afb_req_fail_f (request, "channel-invalid","command=%s numid is not an integer", json_object_get_string (channelJ));
- goto OnErrorExit;
- }
- } else {
+ goto OnErrorExit;
+ }
+ } else {
if (json_object_object_get_ex (commandJ, "channel", &nameJ)) {
int idx;
const char *name = json_object_get_string(nameJ);
}
if (ucsContext->channels[idx].name == NULL) {
afb_req_fail_f (request, "channel-invalid","command=%s channel name does not exist", name);
- goto OnErrorExit;
- }
+ goto OnErrorExit;
+ }
} else {
afb_req_fail_f (request, "channel-invalid","command=%s no valid channel name or channel", json_object_get_string(commandJ));
- goto OnErrorExit;
+ goto OnErrorExit;
};
}
-
+
if (!json_object_object_get_ex (commandJ, "volume", &volJ)) {
afb_req_fail_f (request, "vol-missing","command=%s vol not present", json_object_get_string (commandJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
+
if (!sscanf (json_object_get_string (volJ), "%d", &vol)) {
afb_req_fail_f (request, "vol-invalid","command=%s vol:%s is not an integer", json_object_get_string (commandJ), json_object_get_string (volJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
break;
-
- default:
+
+ default:
afb_req_fail_f (request, "setvol-invalid","command=%s not valid JSON Volume Command", json_object_get_string(commandJ));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
-
+
+
// Fulup what's append when channel or vol are invalid ???
err = UCSI_Vol_Set (&ucsContext->ucsiData, numid, (uint8_t) vol);
if (err) {
// Fulup this might only be a warning (not sure about it)
- afb_req_fail_f (request, "vol-refused","command=%s vol was refused by unicens", json_object_get_string (volJ));
- goto OnErrorExit;
+ afb_req_fail_f (request, "vol-refused","command=%s vol was refused by UNICENS", json_object_get_string (volJ));
+ goto OnErrorExit;
}
-
+
return 0;
-
- OnErrorExit:
+
+ OnErrorExit:
return 1;
}
-
+
PUBLIC void ucs2SetVol (struct afb_req request) {
struct json_object *queryJ;
int err;
-
- // check unicens is initialised
+
+ // check UNICENS is initialised
if (!ucsContextS) {
- afb_req_fail_f (request, "unicens-init","Should Load Config before using setvol");
- goto OnErrorExit;
+ afb_req_fail_f (request, "UNICENS-init","Should Load Config before using setvol");
+ goto OnErrorExit;
}
-
+
queryJ = afb_req_json(request);
if (!queryJ) {
afb_req_fail_f (request, "query-notjson","query=%s not a valid json entry", afb_req_value(request,""));
- goto OnErrorExit;
+ goto OnErrorExit;
};
-
+
enum json_type jtype= json_object_get_type(queryJ);
switch (jtype) {
case json_type_array:
for (int idx=0; idx < json_object_array_length (queryJ); idx ++) {
- err= volSndCmd (request, json_object_array_get_idx (queryJ, idx), ucsContextS);
+ err= volSndCmd (request, json_object_array_get_idx (queryJ, idx), ucsContextS);
if (err) goto OnErrorExit;
}
break;
-
+
case json_type_object:
err = volSndCmd (request, queryJ, ucsContextS);
if (err) goto OnErrorExit;
break;
-
- default:
+
+ default:
afb_req_fail_f (request, "query-notarray","query=%s not valid JSON Volume Command Array", afb_req_value(request,""));
- goto OnErrorExit;
+ goto OnErrorExit;
}
-
- afb_req_success(request,NULL,NULL);
-
+
+ afb_req_success(request,NULL,NULL);
+
OnErrorExit:
return;
}
sd_event_source *evtSource;
int err;
-
+
// Read and parse XML file
ucsConfig = ParseFile (request);
if (NULL == ucsConfig) goto OnErrorExit;
-
+
// Fulup->Thorsten BUG InitializeCdevs should fail when control does not exit
if (!InitializeCdevs(&ucsContext)) {
afb_req_fail_f (request, "devnit-error", "Fail to initialise device [rx=%s tx=%s]", CONTROL_CDEV_RX, CONTROL_CDEV_TX);
// Initialise Unicens Config Data Structure
UCSI_Init(&ucsContext.ucsiData, &ucsContext);
-
+
// Initialise Unicens with parsed config
if (!UCSI_NewConfig(&ucsContext.ucsiData, ucsConfig)) {
- afb_req_fail_f (request, "unicens-init", "Fail to initialize Unicens");
+ afb_req_fail_f (request, "UNICENS-init", "Fail to initialize Unicens");
goto OnErrorExit;
}
afb_req_fail_f (request, "register-mainloop", "Cannot hook events to mainloop");
goto OnErrorExit;
}
-
+
// init Unicens Volume Library
ucsContext.channels = UCSI_Vol_Init (&ucsContext.ucsiData, volumeCB);
if (!ucsContext.channels) {
}
// save this in a statical variable until ucs2vol move to C
ucsContextS = &ucsContext;
-
- afb_req_success(request,NULL,"unicens-active");
-
+
+ afb_req_success(request,NULL,"UNICENS-active");
+
OnErrorExit:
return;
}
bool initialized;
RB_t rb;
uint8_t rbBuf[(CMD_QUEUE_LEN * sizeof(UnicensCmdEntry_t))];
- Ucs_Inst_t *unicens;
+ Ucs_Inst_t *UNICENS;
Ucs_InitData_t uniInitData;
bool triggerService;
Ucs_Lld_Api_t *uniLld;
UnicensCmdEntry_t *currentCmd;
} UCSI_Data_t;
-#endif /* UNICENSINTEGRATION_H_ */
\ No newline at end of file
+#endif /* UNICENSINTEGRATION_H_ */
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Public API */
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
+
// Fulup interface added to support ucs2vol
typedef const struct {
char* name;
}
#endif
-#endif /* UCSI_H_ */
\ No newline at end of file
+#endif /* UCSI_H_ */
memset(my, 0, sizeof(UCSI_Data_t));
my->magic = MAGIC;
my->tag = pTag;
- my->unicens = Ucs_CreateInstance();
- if (NULL == my->unicens)
+ my->UNICENS = Ucs_CreateInstance();
+ if (NULL == my->UNICENS)
{
UCSI_CB_OnUserMessage(my->tag, "Can not instance a new version of UNICENS, "\
"increase UCS_NUM_INSTANCES define", 0);
UnicensCmdEntry_t *e;
bool popEntry = true; //Set to false in specific case, where function will callback asynchrony.
assert(MAGIC == my->magic);
- if (NULL != my->unicens && my->triggerService) {
+ if (NULL != my->UNICENS && my->triggerService) {
my->triggerService = false;
- Ucs_Service(my->unicens);
+ Ucs_Service(my->UNICENS);
}
if (NULL != my->currentCmd) return;
my->currentCmd = e = (UnicensCmdEntry_t *)RB_GetReadPtr(&my->rb);
if (NULL == e) return;
switch (e->cmd) {
case UnicensCmd_Init:
- if (UCS_RET_SUCCESS == Ucs_Init(my->unicens, e->val.Init.init_ptr, OnUcsInitResult))
+ if (UCS_RET_SUCCESS == Ucs_Init(my->UNICENS, e->val.Init.init_ptr, OnUcsInitResult))
popEntry = false;
else
UCSI_CB_OnUserMessage(my->tag, "Ucs_Init failed", 0);
break;
case UnicensCmd_Stop:
- if (UCS_RET_SUCCESS == Ucs_Stop(my->unicens, OnUcsStopResult))
+ if (UCS_RET_SUCCESS == Ucs_Stop(my->UNICENS, OnUcsStopResult))
popEntry = false;
else
UCSI_CB_OnUserMessage(my->tag, "Ucs_Stop failed", 0);
break;
case UnicensCmd_RmSetRoute:
- if (UCS_RET_SUCCESS != Ucs_Rm_SetRouteActive(my->unicens, e->val.RmSetRoute.routePtr, e->val.RmSetRoute.isActive))
+ if (UCS_RET_SUCCESS != Ucs_Rm_SetRouteActive(my->UNICENS, e->val.RmSetRoute.routePtr, e->val.RmSetRoute.isActive))
UCSI_CB_OnUserMessage(my->tag, "Ucs_Rm_SetRouteActive failed", 0);
break;
case UnicensCmd_NsRun:
- if (UCS_RET_SUCCESS != Ucs_Ns_Run(my->unicens, e->val.NsRun.node_ptr, OnUcsNsRun))
+ if (UCS_RET_SUCCESS != Ucs_Ns_Run(my->UNICENS, e->val.NsRun.node_ptr, OnUcsNsRun))
UCSI_CB_OnUserMessage(my->tag, "Ucs_Ns_Run failed", 0);
break;
default:
void UCSI_Timeout(UCSI_Data_t *my)
{
assert(MAGIC == my->magic);
- if (NULL == my->unicens) return;
- Ucs_ReportTimeout(my->unicens);
+ if (NULL == my->UNICENS) return;
+ Ucs_ReportTimeout(my->UNICENS);
}
/************************************************************************/
{.name= "CENTER" , .numid= (int)LIB_MOST_VOLUME_CH_CENTER},
{.name= "SUB" , .numid= (int)LIB_MOST_VOLUME_CH_SUB},
{.name= "MASTER" , .numid= (int)LIB_MOST_VOLUME_MASTER},
-
+
{.name= NULL}
};
UCSI_channelsT *UCSI_Vol_Init (UCSI_Data_t *pPriv, UCSI_VolumeServiceCB_t serviceCB) {
int err;
- err = lib_most_volume_init(pPriv->unicens, (lib_most_volume_service_cb_t) serviceCB);
+ err = lib_most_volume_init(pPriv->UNICENS, (lib_most_volume_service_cb_t) serviceCB);
if (err) return (NULL);
else return (ucsiChannels);
}
uint8_t UCSI_Vol_Set(UCSI_Data_t *pPriv, int numid, uint8_t volume) {
-
+
return (lib_most_volume_set((enum lib_most_volume_channel_t)numid, volume));
}
#include "libmostvolume.h"
class CDeviceContainer {
-
+
public:
CDeviceContainer();
virtual ~CDeviceContainer();
-
+
void AssignService(lib_most_volume_service_cb_t service_fptr, Ucs_Inst_t *ucs_ptr) {_service_fptr = service_fptr; _ucs_inst_ptr = ucs_ptr;}
-
+
void RegisterValues(CDeviceValue** list_pptr, uint16_t list_sz);
void SetValue(uint16_t key, uint8_t value);
void ClearValues();
DEVICE_VAL_MASTER = 0,
DEVICE_VAL_LEFT = 1,
DEVICE_VAL_RIGHT = 2
-
+
};
class CDeviceValue {
public:
CDeviceValue(uint16_t address, DeviceValueType type, uint16_t key);
virtual ~CDeviceValue();
-
+
uint16_t GetKey(){return _key;}
DeviceValueType GetType(){return _type;} // returns the assigned type
void SetValue(uint8_t value){_target_value = value;} // sets desired value
-
+
bool RequiresUpdate(); // returns true if target is not actual value
// returns true if success, false if failed
- // -> stop transmission
+ // -> stop transmission
bool FireUpdateMessage(void);// fires message & updates actual value
-
+
private:
void HandleI2cResult(Ucs_I2c_Result_t result);
void ApplyMostValue(uint8_t value, DeviceValueType type, uint8_t tx_payload[]);
-
+
bool _is_initial; // ensure first update
DeviceValueType _type; // determines the remote i2c command
- uint16_t _key; // lookup key
+ uint16_t _key; // lookup key
uint16_t _address; // target node/group address
uint8_t _target_value; // desired value
uint8_t _actual_value; // value set and confirmed via network
#ifdef __cplusplus
extern "C" {
#endif
-
+
/** Describes the volume control */
enum lib_most_volume_channel_t{
LIB_MOST_VOLUME_CH_FRONT_LEFT = 0,
* \param timeout Time in ms after which the application shall call lib_most_volume_service().
* Valid values:
* 0x0000: as soon as possible,
- * 0x0001..0xFFFE: timeout in ms,
+ * 0x0001..0xFFFE: timeout in ms,
* 0xFFFF: never
*/
typedef void (*lib_most_volume_service_cb_t)(uint16_t timeout);
/** Initializes the library
- * \param unicens_inst Reference to the UNICENS instance, created by the application.
- * \param req_service_fptr Callback function which is fired if the application shall call
+ * \param UNICENS_inst Reference to the UNICENS instance, created by the application.
+ * \param req_service_fptr Callback function which is fired if the application shall call
* lib_most_volume_service.
- * \return '0' on success, otherwise value >'0'.
+ * \return '0' on success, otherwise value >'0'.
*/
-extern uint8_t lib_most_volume_init(Ucs_Inst_t *unicens_inst, lib_most_volume_service_cb_t req_service_fptr);
+extern uint8_t lib_most_volume_init(Ucs_Inst_t *UNICENS_inst, lib_most_volume_service_cb_t req_service_fptr);
/** Terminates the library
* \return '0' on success, otherwise value >'0'.
*/
extern uint8_t lib_most_volume_set(enum lib_most_volume_channel_t channel, uint8_t volume);
-/** Shall be called either cyclically (e.g. 50ms -> polling) or after "timeout"
+/** Shall be called either cyclically (e.g. 50ms -> polling) or after "timeout"
* when "service_fptr" is fired (-> event triggered).
* \return '0' on success, otherwise value >'0'.
- */
+ */
extern uint8_t lib_most_volume_service(void);
#ifdef __cplusplus
#define MAX_MASTERS 3u
class CSetup {
-
+
public:
- void Configure(Ucs_Inst_t *unicens_inst, lib_most_volume_service_cb_t service_fptr);
+ void Configure(Ucs_Inst_t *UNICENS_inst, lib_most_volume_service_cb_t service_fptr);
Ucs_Inst_t *RetrieveUnicensInst(void);
void SetVolume(enum lib_most_volume_channel_t channel, uint8_t volume);
- void Update();
-
-private:
+ void Update();
+
+private:
CDeviceValue _volume_amp_270_m;
CDeviceValue _volume_amp_270_l;
CDeviceValue _volume_amp_270_r;
-
+
CDeviceValue _volume_amp_271_m;
CDeviceValue _volume_amp_271_l;
CDeviceValue _volume_amp_271_r;
-
+
CDeviceValue _volume_amp_272_m;
CDeviceValue _volume_amp_272_l;
CDeviceValue _volume_amp_272_r;
CDeviceContainer _value_container;
Ucs_Inst_t *ucs_inst;
-
+
public:
static CSetup* GetInstance(); // singleton
static void Release(); // singleton
-
+
protected:
CSetup(); // singleton
virtual ~CSetup(); // singleton
-
+
private:
static CSetup* _instance; // singleton
};
)
# Define properties to expose when others use this target
- TARGET_INCLUDE_DIRECTORIES(ucs2-vol
- PUBLIC
+ TARGET_INCLUDE_DIRECTORIES(ucs2-vol
+ PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../inc
${CMAKE_CURRENT_SOURCE_DIR}/../cfg
${CMAKE_CURRENT_SOURCE_DIR}/ucs-xml
#define CONTROL_CH_1 0x08U
#define CONTROL_CH_2 0x09U
-CDeviceValue::CDeviceValue(uint16_t address, DeviceValueType type, uint16_t key)
+CDeviceValue::CDeviceValue(uint16_t address, DeviceValueType type, uint16_t key)
{
this->_is_initial = true;
this->_address = address;
this->_target_value = 0x01u;
this->_actual_value = 0x01u;
-
+
this->_type = type;
this->_key = key;
-
+
_tx_payload[0] = CONTROL_MASTER;// 7: master, 8: channel 1, 9: Channel 2
_tx_payload[1] = MUTE_VALUE_HB; //HB:Volume
_tx_payload[2] = MUTE_VALUE_LB; //LB:Volume
_tx_payload_sz = 3u;
}
-CDeviceValue::~CDeviceValue()
+CDeviceValue::~CDeviceValue()
{
}
void CDeviceValue::ApplyMostValue(uint8_t value, DeviceValueType type, uint8_t tx_payload[])
{
uint16_t tmp = MUTE_VALUE;
-
- switch (type)
+
+ switch (type)
{
case DEVICE_VAL_LEFT:
tmp = 0x80U + 0x37FU - (0x37FU * ((int32_t)value) / (0xFFU));
tx_payload[0] = CONTROL_MASTER;
break;
}
-
+
tx_payload[1] = (uint8_t)((tmp >> 8U) & (uint16_t)0xFFU); //HB:Volume
tx_payload[2] = (uint8_t)(tmp & (uint16_t)0xFFU); //LB:Volume
}
// returns true if target is not actual value
-bool CDeviceValue::RequiresUpdate()
+bool CDeviceValue::RequiresUpdate()
{
- if (this->_target_value != this->_actual_value)
+ if (this->_target_value != this->_actual_value)
{
return true;
}
-
+
return false;
}
static bool _running = false;
-extern "C" uint8_t lib_most_volume_init(Ucs_Inst_t *unicens_inst, lib_most_volume_service_cb_t req_service_fptr)
+extern "C" uint8_t lib_most_volume_init(Ucs_Inst_t *UNICENS_inst, lib_most_volume_service_cb_t req_service_fptr)
{
uint8_t success = 1U;
/*std::cerr << "lib_most_volume_init(): called" << std::endl;*/
if (!_running)
{
- CSetup::GetInstance()->Configure(unicens_inst, req_service_fptr);
+ CSetup::GetInstance()->Configure(UNICENS_inst, req_service_fptr);
success = 0U;
_running = true;
}
}
return success;
-}
\ No newline at end of file
+}
// singleton
CSetup* CSetup::GetInstance() {
if (_instance == NULL) {
- _instance = new CSetup();
+ _instance = new CSetup();
}
-
+
return _instance;
}
_volume_amp_272_l(0x272U, DEVICE_VAL_LEFT, LIB_MOST_VOLUME_CH_CENTER),
_volume_amp_272_r(0x272U, DEVICE_VAL_RIGHT, LIB_MOST_VOLUME_CH_SUB),
_value_container()
-{
+{
static CDeviceValue* value_list[3] = { &_volume_amp_270_m,
&_volume_amp_270_l,
&_volume_amp_270_r/*,
}
-void CSetup::Configure(Ucs_Inst_t *unicens_inst, lib_most_volume_service_cb_t service_fptr)
+void CSetup::Configure(Ucs_Inst_t *UNICENS_inst, lib_most_volume_service_cb_t service_fptr)
{
- ucs_inst = unicens_inst;
- _value_container.AssignService(service_fptr, unicens_inst);
+ ucs_inst = UNICENS_inst;
+ _value_container.AssignService(service_fptr, UNICENS_inst);
}
Ucs_Inst_t* CSetup::RetrieveUnicensInst(void)
void CSetup::Update()
{
_value_container.Update();
-}
\ No newline at end of file
+}