From 7dda5549b51ce1bbf674c620a5715986d7da4ffd Mon Sep 17 00:00:00 2001 From: Fulup Ar Foll Date: Fri, 25 Aug 2017 01:10:00 +0200 Subject: Fix Initial Volume for Jabra --- conf.d/project/lua.d/CMakeLists.txt | 34 +++++++ conf.d/project/lua.d/onload-aaaa-00-utils.lua | 86 +++++++++++++++++ conf.d/project/lua.d/onload-aaaa-01-init.lua | 48 +++++++++ conf.d/project/lua.d/onload-aaaa-03-controls.lua | 118 +++++++++++++++++++++++ conf.d/project/lua.d/onload-aaaa-10-event.lua | 74 ++++++++++++++ 5 files changed, 360 insertions(+) create mode 100644 conf.d/project/lua.d/CMakeLists.txt create mode 100644 conf.d/project/lua.d/onload-aaaa-00-utils.lua create mode 100644 conf.d/project/lua.d/onload-aaaa-01-init.lua create mode 100644 conf.d/project/lua.d/onload-aaaa-03-controls.lua create mode 100644 conf.d/project/lua.d/onload-aaaa-10-event.lua (limited to 'conf.d/project/lua.d') diff --git a/conf.d/project/lua.d/CMakeLists.txt b/conf.d/project/lua.d/CMakeLists.txt new file mode 100644 index 0000000..71b3371 --- /dev/null +++ b/conf.d/project/lua.d/CMakeLists.txt @@ -0,0 +1,34 @@ +########################################################################### +# Copyright 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# 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. +########################################################################### + + +################################################## +# Control Policy Config file +################################################## +PROJECT_TARGET_ADD(ctl-lua.d) + file(GLOB LUA_FILES "*.lua") + + # Romain work around to activate lua compilation + set(LUA_LIST "${LUA_FILES}" CACHE STRING "") + + add_input_files("${LUA_FILES}") + + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS "DATA" + OUTPUT_NAME ${TARGET_NAME} + ) \ No newline at end of file diff --git a/conf.d/project/lua.d/onload-aaaa-00-utils.lua b/conf.d/project/lua.d/onload-aaaa-00-utils.lua new file mode 100644 index 0000000..29d2c70 --- /dev/null +++ b/conf.d/project/lua.d/onload-aaaa-00-utils.lua @@ -0,0 +1,86 @@ +--[[ + Copyright (C) 2016 "IoT.bzh" + Author Fulup Ar Foll + + 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. + + Note: this file should be called before any other to assert declare function + is loaded before anything else. + + References: + http://lua-users.org/wiki/DetectingUndefinedVariables + +--]] + + +--=================================================== +--= Niklas Frykholm +-- basically if user tries to create global variable +-- the system will not let them!! +-- call GLOBAL_lock(_G) +-- +--=================================================== +function GLOBAL_lock(t) + local mt = getmetatable(t) or {} + mt.__newindex = lock_new_index + setmetatable(t, mt) +end + +--=================================================== +-- call GLOBAL_unlock(_G) +-- to change things back to normal. +--=================================================== +function GLOBAL_unlock(t) + local mt = getmetatable(t) or {} + mt.__newindex = unlock_new_index + setmetatable(t, mt) +end + +function lock_new_index(t, k, v) + if (string.sub(k,1,1) ~= "_") then + GLOBAL_unlock(_G) + error("GLOBALS are locked -- " .. k .. + " must be declared local or prefix with '_' for globals.", 2) + else + rawset(t, k, v) + end +end + +function unlock_new_index(t, k, v) + rawset(t, k, v) +end + +-- return serialised version of printable table +function Dump_Table(o) + if type(o) == 'table' then + local s = '{ ' + for k,v in pairs(o) do + if type(k) ~= 'number' then k = '"'..k..'"' end + s = s .. '['..k..'] = ' .. Dump_Table(v) .. ',' + end + return s .. '} ' + else + return tostring(o) + end +end + + +-- simulate C prinf function +printf = function(s,...) + io.write(s:format(...)) + io.write("\n") + return +end + +-- lock global variable +GLOBAL_lock(_G) diff --git a/conf.d/project/lua.d/onload-aaaa-01-init.lua b/conf.d/project/lua.d/onload-aaaa-01-init.lua new file mode 100644 index 0000000..8de0c24 --- /dev/null +++ b/conf.d/project/lua.d/onload-aaaa-01-init.lua @@ -0,0 +1,48 @@ +--[[ + Copyright (C) 2016 "IoT.bzh" + Author Fulup Ar Foll + + 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. +--]] + +-- Global variable SHOULD start with _ +_Global_Context={} + +--[[ + This function is call during controller init phase as describe in onload-daemon-sample.json + It receives two argument 1st one is the source (here on load) second one is the arguments + as expose in config file. + + In this sample we create an event that take the name of args["zzzz"], the resulting handle + is save into _Global_Context for further use. + + Note: init functions are not call from a client and thus do not receive query + +--]] +function _Audio_Controller_Init(source, control) + + printf ("[--> Audio_Controller_Init -->] source=%d control=%s", source, Dump_Table(control)) + + -- create an event from configuration name + _Global_Context["event"]=AFB:evtmake(control["evtname"]) + + -- query HAL to retrieve sound card. + local err,result= AFB:servsync ("alsacore", "hallist", {}) + + if (err) then + AFB_ERROR("Fail to retrieve Audio HAL") + else + _Global_Context["registry"]=result["response"] + printf("[<-- Audio_Controller_Init <--] Active HAL=%s", Dump_Table(result["response"])) + end +end diff --git a/conf.d/project/lua.d/onload-aaaa-03-controls.lua b/conf.d/project/lua.d/onload-aaaa-03-controls.lua new file mode 100644 index 0000000..6c7c8a5 --- /dev/null +++ b/conf.d/project/lua.d/onload-aaaa-03-controls.lua @@ -0,0 +1,118 @@ +--[[ + Copyright (C) 2016 "IoT.bzh" + Author Fulup Ar Foll + + 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. + + Following function are called when a control activate a label with + labeller api -> APi=label VERB=dispatch + arguments are + - source (0) when requesting the label (-1) when releasing + - label comme from config given with 'control' in onload-middlename-xxxxx.json + - control is the argument part of the query as providing by control requesting the label. + +--]] + +_CurrentHalVolume={} + + +local function Apply_Hal_Control(source, label, adjustment) + local HAL = _Global_Context["registry"] + + -- check we really got some data + if (adjustment == nil) then + AFB:error ("--* (Hoops) Control should provide volume adjustment") + return 1 + end + + -- loop on each HAL save current volume and push adjustment + for key,hal in pairs(_Global_Context["registry"]) do + printf ("--- HAL=%s", Dump_Table(hal)) + + -- action set loop on active HAL and get current volume + -- if label respond then do volume adjustment + if (source == 0) then + + -- get current volume for each HAL + local err,result= AFB:servsync(hal["api"],"ctlget", {["label"]=label}) + + -- if no error save current volume and set adjustment + if (err ~= nil) then + local response= result["response"] + printf ("--- Response %s=%s", hal["api"], Dump_Table(response)) + + if (response == nil) then + printf ("--- Fail to Activate '%s'='%s' result=%s", hal["api"], label, Dump_Table(result)) + return 1 -- unhappy + end + + -- save response in global space + _CurrentHalVolume [hal["api"]] = response + + -- finally set the new value + local query= { + ["tag"]= response["tag"], + ["val"]= adjustment + } + + -- best effort to set adjustment value + AFB:servsync(hal["api"],"ctlset",query) + end + + else -- when label is release reverse action at preempt time + + if (_CurrentHalVolume [hal["api"]] ~= nil) then + + printf("--- Restoring initial volume HAL=%s Control=%s", hal["api"], _CurrentHalVolume [hal["api"]]) + + AFB:servsync(hal["api"],"ctlset", _CurrentHalVolume [hal["api"]]) + end + end + + end + return 0 -- happy end +end + + +-- Simple Happy(granted) Control +function _Temporarily_Control(source, control, client) + + printf ("[--> _Temporarily_Control -->] source=%d control=%s client=%s", source, Dump_Table(control), Dump_Table(client)) + + -- Init should have been properly done + if (_Global_Context["registry"] == nil) then + AFB:error ("--* (Hoops) No Hal in _Global_Context=%s", Dump_Table(_Global_Context)) + return 1 + end + + -- make sure label as valid + if (control["ctl"] == nil or control["val"] == nil) then + AFB:error ("--* Action Ignore no/invalid control=%s", Dump_Table(control)) + return 1 -- unhappy + end + + if (source == 0) then + AFB:info("-- Adjust %s=%d", control["ctl"], control["val"]) + local error=Apply_Hal_Control(source, control["ctl"], control["val"]) + if (error == nil) then + return 1 -- unhappy + end + AFB:notice ("[<-- _Temporarily_Control Granted<--]") + else + Apply_Hal_Control(source, control["ctl"],0) + AFB:notice ("[<-- _Temporarily_Control Restore--]") + end + + return 0 -- happy return +end + diff --git a/conf.d/project/lua.d/onload-aaaa-10-event.lua b/conf.d/project/lua.d/onload-aaaa-10-event.lua new file mode 100644 index 0000000..474ebe0 --- /dev/null +++ b/conf.d/project/lua.d/onload-aaaa-10-event.lua @@ -0,0 +1,74 @@ +--[[ + Copyright (C) 2016 "IoT.bzh" + Author Fulup Ar Foll + + 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. + + + Provide Sample Timer Handing to push event from LUA +--]] + +-- Create event on Lua script load +_MyContext={} + +-- WARNING: call back are global and should start with '_' +function _Timer_Test_CB (timer, context) + + local evtinfo= AFB:timerget(timer) + printf ("[-- _Timer_Test_C --] evtInfo=%s", Dump_Table(evtinfo)) + + --send an event an event with count as value + AFB:evtpush (_MyContext["event"], {["label"]= evtinfo["label"], ["count"]=evtinfo["count"], ["info"]=context["info"]}) + + -- note when timerCB return!=0 timer is kill + return 0 + +end + +-- sendback event depending on count and delay +function _Simple_Timer_Test (request, client) + + local context = { + ["info"]="My 1st private Event", + } + + -- if event does not exit create it now. + if (_MyContext["event"] == nil) then + _MyContext["event"]= AFB:evtmake(client["label"]) + end + + -- if delay not defined default is 5s + if (client["delay"]==nil) then client["delay"]=5000 end + + -- if count is not defined default is 10 + if (client["count"]==nil) then client["count"]=10 end + + -- we could use directly client but it is a sample + local myTimer = { + ["label"]=client["label"], + ["delay"]=client["delay"], + ["count"]=client["count"], + } + AFB:notice ("Test_Timer myTimer=%s", myTimer) + + -- subscribe to event + AFB:subscribe (request, _MyContext["event"]) + + -- settimer take a table with delay+count as input (count==0 means infinite) + AFB:timerset (myTimer, "_Timer_Test_CB", context) + + -- nothing special to return send back + AFB:success (request, myTimer) + + return 0 +end -- cgit 1.2.3-korg