From b90978a93e23a91d8c3f4fa8ec023c60340bdea5 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Wed, 14 Dec 2016 18:10:54 +0900 Subject: merge the Settings in CES2017 and bindings from ALPS Change-Id: I00a7a6c5dae1cd579f91d543b0f5fba4616a633b Signed-off-by: Tasuku Suzuki --- app/SettingPage.qml | 60 ++ app/Settings.qml | 60 ++ app/SettingsLauncher.qml | 77 +++ app/api/Binding.qml | 62 ++ app/api/MessageId.js | 22 + app/app.pri | 12 + app/app.pro | 15 + app/bluetooth/Bluetooth.qml | 341 ++++++++++ app/bluetooth/bluetooth.qrc | 8 + app/bluetooth/images/HMI_Pair_Button.svg | 98 +++ app/bluetooth/images/HMI_Paired_Button.svg | 98 +++ .../images/HMI_Settings_BluetoothIcon.svg | 55 ++ app/config.tests/libhomescreen/.qmake.stash | 14 + app/config.tests/libhomescreen/libhomescreen.cpp | 8 + app/config.tests/libhomescreen/libhomescreen.pro | 5 + app/datetime/DateEdit.qml | 122 ++++ app/datetime/DateTime.qml | 50 ++ app/datetime/EditSeparator.qml | 40 ++ app/datetime/TimeEdit.qml | 86 +++ app/datetime/datetime.qrc | 14 + .../HMI_Settings_TimeDate_Arrow_DividingLine.svg | 57 ++ .../images/HMI_Settings_TimeDate_Arrow_Down.svg | 56 ++ .../images/HMI_Settings_TimeDate_Arrow_Up.svg | 56 ++ .../images/HMI_Settings_TimeDate_Button_Cancel.svg | 98 +++ .../images/HMI_Settings_TimeDate_Button_Set.svg | 98 +++ app/datetime/images/HMI_Settings_TimeIcon.svg | 59 ++ app/example/Example.qml | 96 +++ app/example/example.qrc | 6 + app/example/images/HMI_Settings_Example.svg | 72 ++ app/images/HMI_Settings_DividingLine.svg | 58 ++ app/images/HMI_Settings_X.svg | 72 ++ app/images/images.qrc | 6 + app/main.cpp | 76 +++ app/settings.qrc | 7 + app/wifi/Wifi.qml | 435 ++++++++++++ app/wifi/images/HMI_Settings_WifiIcon.svg | 61 ++ app/wifi/images/HMI_Settings_Wifi_1Bar.svg | 71 ++ app/wifi/images/HMI_Settings_Wifi_2Bars.svg | 71 ++ app/wifi/images/HMI_Settings_Wifi_3Bars.svg | 71 ++ app/wifi/images/HMI_Settings_Wifi_Full.svg | 70 ++ app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg | 78 +++ app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg | 78 +++ app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg | 78 +++ app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg | 77 +++ .../images/HMI_Settings_Wifi_Locked_NoBars.svg | 79 +++ app/wifi/images/HMI_Settings_Wifi_NoBars.svg | 70 ++ app/wifi/wifi.qrc | 16 + binding-bluetooth/binding-bluetooth.pro | 11 + binding-bluetooth/binding.pri | 6 + binding-bluetooth/bluetooth-api.c | 503 ++++++++++++++ binding-bluetooth/bluetooth-api.h | 50 ++ binding-bluetooth/bluetooth-manager.c | 747 +++++++++++++++++++++ binding-bluetooth/bluetooth-manager.h | 143 ++++ binding-bluetooth/export.map | 1 + binding-wifi/agent.c | 262 ++++++++ binding-wifi/binding-wifi.pro | 11 + binding-wifi/binding.pri | 6 + binding-wifi/export.map | 1 + binding-wifi/wifi-api.c | 489 ++++++++++++++ binding-wifi/wifi-api.h | 38 ++ binding-wifi/wifi-connman.c | 354 ++++++++++ binding-wifi/wifi-connman.h | 126 ++++ package/config.xml | 11 + package/icon.svg | 283 ++++++++ package/package.pro | 21 + settings.pro | 3 + 66 files changed, 6385 insertions(+) create mode 100644 app/SettingPage.qml create mode 100644 app/Settings.qml create mode 100644 app/SettingsLauncher.qml create mode 100644 app/api/Binding.qml create mode 100644 app/api/MessageId.js create mode 100644 app/app.pri create mode 100644 app/app.pro create mode 100644 app/bluetooth/Bluetooth.qml create mode 100644 app/bluetooth/bluetooth.qrc create mode 100644 app/bluetooth/images/HMI_Pair_Button.svg create mode 100644 app/bluetooth/images/HMI_Paired_Button.svg create mode 100644 app/bluetooth/images/HMI_Settings_BluetoothIcon.svg create mode 100644 app/config.tests/libhomescreen/.qmake.stash create mode 100644 app/config.tests/libhomescreen/libhomescreen.cpp create mode 100644 app/config.tests/libhomescreen/libhomescreen.pro create mode 100644 app/datetime/DateEdit.qml create mode 100644 app/datetime/DateTime.qml create mode 100644 app/datetime/EditSeparator.qml create mode 100644 app/datetime/TimeEdit.qml create mode 100644 app/datetime/datetime.qrc create mode 100644 app/datetime/images/HMI_Settings_TimeDate_Arrow_DividingLine.svg create mode 100644 app/datetime/images/HMI_Settings_TimeDate_Arrow_Down.svg create mode 100644 app/datetime/images/HMI_Settings_TimeDate_Arrow_Up.svg create mode 100644 app/datetime/images/HMI_Settings_TimeDate_Button_Cancel.svg create mode 100644 app/datetime/images/HMI_Settings_TimeDate_Button_Set.svg create mode 100644 app/datetime/images/HMI_Settings_TimeIcon.svg create mode 100644 app/example/Example.qml create mode 100644 app/example/example.qrc create mode 100644 app/example/images/HMI_Settings_Example.svg create mode 100644 app/images/HMI_Settings_DividingLine.svg create mode 100644 app/images/HMI_Settings_X.svg create mode 100644 app/images/images.qrc create mode 100644 app/main.cpp create mode 100644 app/settings.qrc create mode 100644 app/wifi/Wifi.qml create mode 100644 app/wifi/images/HMI_Settings_WifiIcon.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_1Bar.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_2Bars.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_3Bars.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Full.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_Locked_NoBars.svg create mode 100644 app/wifi/images/HMI_Settings_Wifi_NoBars.svg create mode 100644 app/wifi/wifi.qrc create mode 100644 binding-bluetooth/binding-bluetooth.pro create mode 100644 binding-bluetooth/binding.pri create mode 100644 binding-bluetooth/bluetooth-api.c create mode 100644 binding-bluetooth/bluetooth-api.h create mode 100644 binding-bluetooth/bluetooth-manager.c create mode 100644 binding-bluetooth/bluetooth-manager.h create mode 100644 binding-bluetooth/export.map create mode 100644 binding-wifi/agent.c create mode 100644 binding-wifi/binding-wifi.pro create mode 100644 binding-wifi/binding.pri create mode 100644 binding-wifi/export.map create mode 100644 binding-wifi/wifi-api.c create mode 100644 binding-wifi/wifi-api.h create mode 100644 binding-wifi/wifi-connman.c create mode 100644 binding-wifi/wifi-connman.h create mode 100644 package/config.xml create mode 100644 package/icon.svg create mode 100644 package/package.pro create mode 100644 settings.pro diff --git a/app/SettingPage.qml b/app/SettingPage.qml new file mode 100644 index 0000000..10aea21 --- /dev/null +++ b/app/SettingPage.qml @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AGL.Demo.Controls 1.0 + +Page { + id: root + readonly property bool isSetting: true + property string icon + property bool checkable: false + property bool checked: false + function done() { + parent.pop() + } + + Connections { + target: root + onCheckedChanged: { + checkedSwitch.checked = checked + } + } + + Row { + anchors.right: parent.right + anchors.rightMargin: 100 + anchors.bottom: parent.top + anchors.bottomMargin: 10 + spacing: 20 + + Switch { + id: checkedSwitch + visible: root.checkable + onCheckedChanged: root.checked = checked + } + + ImageButton { + id: back + anchors.bottom: parent.bottom + offImage: '../images/HMI_Settings_X.svg' + onClicked: root.done() + } + } + +} diff --git a/app/Settings.qml b/app/Settings.qml new file mode 100644 index 0000000..42fed66 --- /dev/null +++ b/app/Settings.qml @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 + +import 'datetime' +import 'bluetooth' +import 'wifi' +import 'example' + +ApplicationWindow { + id: root + + StackView { + id: stack + anchors.fill: parent + initialItem: settings + + SettingsLauncher { + id: settings + onLaunch: { + stack.push(app) + } + + Component.onCompleted: { + for (var a in stack.children) { + var app = stack.children[a] + if (!app.isSetting) continue + settingsModel.append({'icon': app.icon, 'title': app.title, 'checkable': app.checkable, 'app': app}) + app.visible = false + } + } + + model: ListModel { id: settingsModel } + } + + DateTime {} + + Bluetooth {} + + Wifi {} + + Example {} + } +} diff --git a/app/SettingsLauncher.qml b/app/SettingsLauncher.qml new file mode 100644 index 0000000..c627324 --- /dev/null +++ b/app/SettingsLauncher.qml @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 + +Page { + id: root + title: 'Settings' + property alias model: view.model + signal launch(var app) + signal toggled(var app, bool on) + ListView { + id: view + anchors.fill: parent + anchors.margins: root.width * 0.075 + clip: true + + delegate: MouseArea { + id: delegate + width: ListView.view.width + height: width / 6 + RowLayout { + anchors.fill: parent + Item { + Layout.preferredWidth: 100 + Layout.preferredHeight: 100 + Image { + anchors.centerIn: parent + source: model.icon + } + } + Label { + Layout.fillWidth: true + text: model.title.toUpperCase() + color: '#59FF7F' + } + Switch { + id: checkedSwitch + visible: model.checkable + onCheckedChanged: model.app.checked = checked + } + Connections { + target: model.app + onCheckableChanged: { + checkedSwitch.visible = model.app.checkable + } + onCheckedChanged: { + checkedSwitch.checked = model.app.checked + } + } + } + Image { + source: '../images/HMI_Settings_DividingLine.svg' + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + visible: model.index > 0 + } + + onClicked: launch(model.app) + } + } +} diff --git a/app/api/Binding.qml b/app/api/Binding.qml new file mode 100644 index 0000000..834bdf8 --- /dev/null +++ b/app/api/Binding.qml @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtWebSockets 1.0 +import 'MessageId.js' as MessageId + +WebSocket { + id: root + active: true + + property string statusString: "waiting..." + + property real fanSpeed: 0.0 + + property Connections c : Connections { + target: root + onFanSpeedChanged: { + var json = [MessageId.call, '9999', 'hvac/set', {'FanSpeed': fanSpeed}] + console.debug(JSON.stringify(json)) + sendTextMessage(JSON.stringify(json)) + } + } + + onTextMessageReceived: { + var json = JSON.parse(message) + var request = json[2].request + var response = json[2].response + switch (json[0]) { + case MessageId.call: + break + case MessageId.retok: + root.statusString = request.info + break + case MessageId.reterr: + root.statusString = "Bad return value, binding probably not installed" + break + case MessageId.event: + break + } + } + onStatusChanged: { + switch (status) { + case WebSocket.Error: + root.statusString = "WebSocket error: " + root.errorString + break + } + } +} diff --git a/app/api/MessageId.js b/app/api/MessageId.js new file mode 100644 index 0000000..001ea93 --- /dev/null +++ b/app/api/MessageId.js @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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. + */ + +.pragma library + +var call = 2 +var retok = 3 +var reterr = 4 +var event = 5 diff --git a/app/app.pri b/app/app.pri new file mode 100644 index 0000000..014646f --- /dev/null +++ b/app/app.pri @@ -0,0 +1,12 @@ +TEMPLATE = app + +load(configure) +qtCompileTest(libhomescreen) + +config_libhomescreen { + CONFIG += link_pkgconfig + PKGCONFIG += homescreen + DEFINES += HAVE_LIBHOMESCREEN +} + +DESTDIR = $${OUT_PWD}/../package/root/bin diff --git a/app/app.pro b/app/app.pro new file mode 100644 index 0000000..b35e40e --- /dev/null +++ b/app/app.pro @@ -0,0 +1,15 @@ +TARGET = settings +QT = quickcontrols2 + +SOURCES = main.cpp + +RESOURCES += \ + settings.qrc \ + images/images.qrc \ + datetime/datetime.qrc \ + wifi/wifi.qrc \ + bluetooth/bluetooth.qrc \ + example/example.qrc + + +include(app.pri) diff --git a/app/bluetooth/Bluetooth.qml b/app/bluetooth/Bluetooth.qml new file mode 100644 index 0000000..ded2c36 --- /dev/null +++ b/app/bluetooth/Bluetooth.qml @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import '..' + +SettingPage { + id: root + icon: '/bluetooth/images/HMI_Settings_BluetoothIcon.svg' + title: 'Bluetooth' + checkable: true + + property string protocol: 'http://' + property string ipAddress: '127.0.0.1' + property string portNumber: Qt.application.arguments[1] + property string tokenString: Qt.application.arguments[2] + property string btAPI: '/api/Bluetooth-manager/' + property string btAPIpath: protocol + ipAddress + ':' + portNumber + btAPI + property var jsonObjectBT + property string currentState: 'idle' + + Text { + id: log + anchors.fill: parent + anchors.margins: 10 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + //text: "log" + } + + onCheckedChanged: { + console.log("Bluetooth set to", checked) + if (checked == true) { + request(btAPIpath + 'power?value=1', function (o) { + // log the json response + console.log(o.responseText) + }) + request(btAPIpath + 'start_discovery', function (o) { + console.log(o.responseText) + }) + currentState = 'discovering' + //search_device() + periodicRefresh.start() + + } else { + //console.log(networkPath) + btDeviceList.clear() + periodicRefresh.stop() + request(btAPIpath + 'stop_discovery', function (o) { + // log the json response + console.log(o.responseText) + }) + request(btAPIpath + 'power?value=0', function (o) { + // log the json response + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + currentState = 'idle' + } + } + + ListModel { + id: btDeviceList + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.margins: 80 + width: buttonScan.width + 10 + height: buttonScan.height + 10 + color: "#222" + border.color: "white" + + Button { + id: buttonScan + anchors.centerIn: parent + width: 100 + text: "SEARCH" + + MouseArea { + //id: mouseArea + anchors.fill: parent + + onClicked: { + if (buttonScan.text == "SEARCH"){ + request(btAPIpath + 'start_discovery', function (o) { + + // log the json response + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + buttonScan.text = "CANCEL" + currentState = 'discovering' + periodicRefresh.start() + }else{ + request(btAPIpath + 'stop_discovery', function (o) { + + // log the json response + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + buttonScan.text = "SEARCH" + currentState = 'idle' + //periodicRefresh.stop() //in order to update the content from bluez + } + } + } + } + } + + function request(url, callback) { + var xhr = new XMLHttpRequest() + xhr.onreadystatechange = (function (myxhr) { + return function () { + if (xhr.readyState == 4 && xhr.status == 200){ + callback(myxhr) + } + } + })(xhr) + xhr.open('GET', url, false) + xhr.send('') + } + + Component { + id:blueToothDevice + Rectangle { + height: 150 + width: parent.width + color: "#222" + + Column { + Text { + id: btName + text: deviceName + font.pointSize: 36 + color: "#ffffff" + } + Text { + id: btAddr + text: deviceAddress + visible: false + } + Text { + text: { + if ((devicePairable === "True") + && (deviceConnect === "False")) + text = "paired" + else if ((devicePairable === "True") + && (deviceConnect === "True") + && (connectAVP) === "True") + text = "AV Connection" + else if ((devicePairable === "True") + && (deviceConnect === "True") + && (connectHFP) === "True") + text = "Handsfree Connection" + else + text = "" + } + font.pointSize: 18 + color: "#ffffff" + font.italic: true + } + Text { + id: btPairable + text: devicePairable + visible: false + } + Text { + id: btConnectstatus + text: deviceConnect + visible: false + } + + } + Button { + id: connectButton + anchors.top:parent.top + anchors.topMargin: 15 + anchors.right: parent.right + anchors.rightMargin: 10 + + text:(btConnectstatus.text == "True")? "Disconnect":((btPairable.text == "True")? "Connect":"Pair") + MouseArea { + anchors.fill: parent + onClicked: { + if (currentState == 'discovering'){ + request(btAPIpath + 'stop_discovery', function (o) { + currentState = "idle" + console.log(o.responseText) + }) + } + if (connectButton.text == "Pair"){ + connectButton.text = "Connect" + request(btAPIpath + 'pair?value=' + btAddr.text, function (o) { + btPairable.text = "True" + console.log(o.responseText) + }) + request(btAPIpath + 'set_property?Address=' + btAddr.text + '\&Property=Trusted\&value=true', function (o) { + console.log(o.responseText) + }) + } + else if (connectButton.text == "Connect"){ + connectButton.text = "Disconnect" + request(btAPIpath + 'connect?value=' + btAddr.text, function (o) { + console.log(o.responseText) + }) + } + else if (connectButton.text == "Disconnect"){ + request(btAPIpath + 'disconnect?value=' + btAddr.text, function (o) { + console.log(o.responseText) + }) + connectButton.text = "Connect" + btDeviceList.remove(findDevice(btAddr.text)) + } + } + } + } + /*Image{ + id: removeDevice + anchors.top:parent.top + anchors.topMargin: 15 + anchors.right: parent.right + anchors.rightMargin: 5 + width: 25 + height: 25 + source: "component/images/trash.png" + + MouseArea { + anchors.fill: parent + onClicked: { + request(btAPIpath + 'remove_device?value=' + btAddr.text, function (o) { + console.log(o.responseText) + }) + btDeviceList.remove(findDevice(btAddr.text)) + } + } + }*/ + } + } + + ListView { + width: parent.width + anchors.top: parent.top + anchors.topMargin: 200 + anchors.bottom: parent.bottom + anchors.bottomMargin: 150 + model: btDeviceList + delegate: blueToothDevice + clip: true + } + + function findDevice(address){ + for (var i = 0; i < jsonObjectBT.length; i++) { + if (address === jsonObjectBT[i].Address){ + return i + } + } + } + function search_device(){ + btDeviceList.clear() + request(btAPIpath + 'discovery_result', function (o) { + + // log the json response + console.log(o.responseText) + + // translate response into object + var jsonObject = eval('(' + o.responseText + ')') + + jsonObjectBT = eval('(' + JSON.stbtPairableringify( + jsonObject.response) + ')') + + console.log("BT list refreshed") + + //console.log(jsonObject.response) + for (var i = 0; i < jsonObjectBT.length; i++) { + btDeviceList.append({ + deviceAddress: jsonObjectBT[i].Address, + deviceName: jsonObjectBT[i].Name, + devicePairable:jsonObjectBT[i].Paired, + deviceConnect: jsonObjectBT[i].Connected, + connectAVP: jsonObjectBT[i].AVPConnected, + connectHFP: jsonObjectBT[i].HFPConnected + }) + } + }) + } + + //Timer for periodic refresh; this is BAD solution, need to figure out how to subscribe for events + Timer { + id: periodicRefresh + interval: (currentState == "idle")? 10000:5000 // 5seconds + onTriggered: { + + btDeviceList.clear() + + request(btAPIpath + 'discovery_result', function (o) { + + // log the json response + console.log(o.responseText) + + // translate response into object + var jsonObject = eval('(' + o.responseText + ')') + + jsonObjectBT = eval('(' + JSON.stringify( + jsonObject.response) + ')') + + console.log("BT list refreshed") + + //console.log(jsonObject.response) + for (var i = 0; i < jsonObjectBT.length; i++) { + btDeviceList.append({ + deviceAddress: jsonObjectBT[i].Address, + deviceName: jsonObjectBT[i].Name, + devicePairable:jsonObjectBT[i].Paired, + deviceConnect: jsonObjectBT[i].Connected, + connectAVP: jsonObjectBT[i].AVPConnected, + connectHFP: jsonObjectBT[i].HFPConnected + }) + } + }) + start() + } + } + } + diff --git a/app/bluetooth/bluetooth.qrc b/app/bluetooth/bluetooth.qrc new file mode 100644 index 0000000..bc8b70a --- /dev/null +++ b/app/bluetooth/bluetooth.qrc @@ -0,0 +1,8 @@ + + + Bluetooth.qml + images/HMI_Pair_Button.svg + images/HMI_Paired_Button.svg + images/HMI_Settings_BluetoothIcon.svg + + diff --git a/app/bluetooth/images/HMI_Pair_Button.svg b/app/bluetooth/images/HMI_Pair_Button.svg new file mode 100644 index 0000000..930a75b --- /dev/null +++ b/app/bluetooth/images/HMI_Pair_Button.svg @@ -0,0 +1,98 @@ + + + +image/svg+xmlPair + \ No newline at end of file diff --git a/app/bluetooth/images/HMI_Paired_Button.svg b/app/bluetooth/images/HMI_Paired_Button.svg new file mode 100644 index 0000000..17419d4 --- /dev/null +++ b/app/bluetooth/images/HMI_Paired_Button.svg @@ -0,0 +1,98 @@ + + + +image/svg+xmlPairED + \ No newline at end of file diff --git a/app/bluetooth/images/HMI_Settings_BluetoothIcon.svg b/app/bluetooth/images/HMI_Settings_BluetoothIcon.svg new file mode 100644 index 0000000..d41de2a --- /dev/null +++ b/app/bluetooth/images/HMI_Settings_BluetoothIcon.svg @@ -0,0 +1,55 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/config.tests/libhomescreen/.qmake.stash b/app/config.tests/libhomescreen/.qmake.stash new file mode 100644 index 0000000..d1c4687 --- /dev/null +++ b/app/config.tests/libhomescreen/.qmake.stash @@ -0,0 +1,14 @@ +QMAKE_DEFAULT_INCDIRS = \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5 \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/x86_64-pc-linux-gnu \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5/backward \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include-fixed \ + /usr/include +QMAKE_DEFAULT_LIBDIRS = \ + /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0 \ + /usr/lib64 \ + /lib64 \ + /usr/x86_64-pc-linux-gnu/lib \ + /usr/lib \ + /lib diff --git a/app/config.tests/libhomescreen/libhomescreen.cpp b/app/config.tests/libhomescreen/libhomescreen.cpp new file mode 100644 index 0000000..d698b05 --- /dev/null +++ b/app/config.tests/libhomescreen/libhomescreen.cpp @@ -0,0 +1,8 @@ +#include + +int main(int argc,char **argv) +{ + LibHomeScreen libHomeScreen; + return 0; +} + diff --git a/app/config.tests/libhomescreen/libhomescreen.pro b/app/config.tests/libhomescreen/libhomescreen.pro new file mode 100644 index 0000000..eb4e8f3 --- /dev/null +++ b/app/config.tests/libhomescreen/libhomescreen.pro @@ -0,0 +1,5 @@ +SOURCES = libhomescreen.cpp + +CONFIG -= qt +CONFIG += link_pkgconfig +PKGCONFIG += homescreen diff --git a/app/datetime/DateEdit.qml b/app/datetime/DateEdit.qml new file mode 100644 index 0000000..f9f75fd --- /dev/null +++ b/app/datetime/DateEdit.qml @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AGL.Demo.Controls 1.0 + +GridLayout { + id: root + flow: GridLayout.TopToBottom + rows: 3 + + property int year: yearControl.model[yearControl.currentIndex] + property int month: monthControl.currentIndex + 1 + property int day: dayControl.currentIndex + 1 + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: monthControl.currentIndex++ + } + Tumbler { + id: monthControl + implicitWidth: 200 + model: ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'] + onCurrentIndexChanged: dayControl.regenerateModel() + + EditSeparator { anchors.fill: parent } + } + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: monthControl.currentIndex-- + } + + Item { width: 10; height: 10 } + Label { text: ':' } + Item { width: 10; height: 10 } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: dayControl.currentIndex++ + } + + Tumbler { + id: dayControl + model: ListModel{ + id: monthModel + } + Component.onCompleted: regenerateModel() + function regenerateModel() { + var eom = 0 + var y = yearControl.model[yearControl.currentIndex] + var m = monthControl.currentIndex + 1 + switch (m) { + case 2: + eom = 28 + parseInt(1 / (y % 4 + 1)) - parseInt(1 - 1 / (y % 100 + 1)) + parseInt(1 / (y % 400 + 1)) + break + case 4: + case 6: + case 9: + case 11: + eom = 30 + break + default: + eom = 31 + break + } + while (monthModel.count < eom) + monthModel.append({modelData: monthModel.count + 1}) + while (monthModel.count > eom) + monthModel.remove(monthModel.count - 1, 1) + } + EditSeparator { anchors.fill: parent } + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: dayControl.currentIndex-- + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: yearControl.currentIndex++ + } + + Tumbler { + id: yearControl + Component.onCompleted: { + var arr = new Array + for (var i = 2010; i < 2050; i++) { + arr.push(i) + } + yearControl.model = arr + } + onCurrentIndexChanged: dayControl.regenerateModel() + EditSeparator { anchors.fill: parent } + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: yearControl.currentIndex-- + } +} diff --git a/app/datetime/DateTime.qml b/app/datetime/DateTime.qml new file mode 100644 index 0000000..5030b1e --- /dev/null +++ b/app/datetime/DateTime.qml @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AGL.Demo.Controls 1.0 +import '..' + +SettingPage { + id: root + icon: '/datetime/images/HMI_Settings_TimeIcon.svg' + title: 'Date & Time' + + ColumnLayout { + anchors.fill: parent + anchors.margins: 100 + Label { text: 'Date'} + DateEdit {} + Image { + source: '../images/HMI_Settings_DividingLine.svg' + } + Label { text: 'Time'} + TimeEdit {} + RowLayout { + anchors.right: parent.right + Button { + text: 'OK' + highlighted: true + onClicked: root.done() + } + } + Item { + Layout.fillHeight: true + } + } +} diff --git a/app/datetime/EditSeparator.qml b/app/datetime/EditSeparator.qml new file mode 100644 index 0000000..e833b52 --- /dev/null +++ b/app/datetime/EditSeparator.qml @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 + +ColumnLayout { + anchors.fill: parent + z: -1 + Item { + Layout.fillHeight: true + Layout.preferredHeight: 1 + } + Repeater { + model: 2 + Image { + Layout.fillHeight: true + Layout.preferredHeight: 2 + Layout.alignment: Layout.Center + source: './images/HMI_Settings_TimeDate_Arrow_DividingLine.svg' + } + } + Item { + Layout.fillHeight: true + Layout.preferredHeight: 1 + } +} diff --git a/app/datetime/TimeEdit.qml b/app/datetime/TimeEdit.qml new file mode 100644 index 0000000..69a049b --- /dev/null +++ b/app/datetime/TimeEdit.qml @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AGL.Demo.Controls 1.0 + +GridLayout { + id: root + flow: GridLayout.TopToBottom + rows: 3 + + property int hour: hourControl.currentIndex + property int minutes: minutesControl.currentIndex + property string ampm: ampmControl.model[ampmControl.currentIndex] + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: hourControl.currentIndex++ + } + Tumbler { + id: hourControl + model: 12 + EditSeparator { anchors.fill: parent } + } + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: hourControl.currentIndex-- + } + + Item { width: 10; height: 10 } + Label { text: ':' } + Item { width: 10; height: 10 } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: minutesControl.currentIndex++ + } + + Tumbler { + id: minutesControl + model: 60 + EditSeparator { anchors.fill: parent } + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: minutesControl.currentIndex-- + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Up.svg' + onClicked: ampmControl.currentIndex++ + } + + Tumbler { + id: ampmControl + model: ['AM', 'PM', 'AM', 'PM'] + EditSeparator { anchors.fill: parent } + } + + ImageButton { + Layout.alignment: Layout.Center + offImage: './images/HMI_Settings_TimeDate_Arrow_Down.svg' + onClicked: ampmControl.currentIndex-- + } +} diff --git a/app/datetime/datetime.qrc b/app/datetime/datetime.qrc new file mode 100644 index 0000000..c60c626 --- /dev/null +++ b/app/datetime/datetime.qrc @@ -0,0 +1,14 @@ + + + DateEdit.qml + DateTime.qml + TimeEdit.qml + EditSeparator.qml + images/HMI_Settings_TimeDate_Arrow_DividingLine.svg + images/HMI_Settings_TimeDate_Arrow_Down.svg + images/HMI_Settings_TimeDate_Arrow_Up.svg + images/HMI_Settings_TimeDate_Button_Cancel.svg + images/HMI_Settings_TimeDate_Button_Set.svg + images/HMI_Settings_TimeIcon.svg + + diff --git a/app/datetime/images/HMI_Settings_TimeDate_Arrow_DividingLine.svg b/app/datetime/images/HMI_Settings_TimeDate_Arrow_DividingLine.svg new file mode 100644 index 0000000..5a7fa7f --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeDate_Arrow_DividingLine.svg @@ -0,0 +1,57 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/datetime/images/HMI_Settings_TimeDate_Arrow_Down.svg b/app/datetime/images/HMI_Settings_TimeDate_Arrow_Down.svg new file mode 100644 index 0000000..a4fad6b --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeDate_Arrow_Down.svg @@ -0,0 +1,56 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/datetime/images/HMI_Settings_TimeDate_Arrow_Up.svg b/app/datetime/images/HMI_Settings_TimeDate_Arrow_Up.svg new file mode 100644 index 0000000..49b0c88 --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeDate_Arrow_Up.svg @@ -0,0 +1,56 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/datetime/images/HMI_Settings_TimeDate_Button_Cancel.svg b/app/datetime/images/HMI_Settings_TimeDate_Button_Cancel.svg new file mode 100644 index 0000000..c04e11e --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeDate_Button_Cancel.svg @@ -0,0 +1,98 @@ + + + +image/svg+xmlCANCEL + \ No newline at end of file diff --git a/app/datetime/images/HMI_Settings_TimeDate_Button_Set.svg b/app/datetime/images/HMI_Settings_TimeDate_Button_Set.svg new file mode 100644 index 0000000..4b103cc --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeDate_Button_Set.svg @@ -0,0 +1,98 @@ + + + +image/svg+xmlSET + \ No newline at end of file diff --git a/app/datetime/images/HMI_Settings_TimeIcon.svg b/app/datetime/images/HMI_Settings_TimeIcon.svg new file mode 100644 index 0000000..d4b2ef6 --- /dev/null +++ b/app/datetime/images/HMI_Settings_TimeIcon.svg @@ -0,0 +1,59 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/example/Example.qml b/app/example/Example.qml new file mode 100644 index 0000000..18e3efc --- /dev/null +++ b/app/example/Example.qml @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import AGL.Demo.Controls 1.0 +import '..' + +SettingPage { + id: root + icon: '/example/images/HMI_Settings_Example.svg' + title: 'Example' + checkable: true + + ColumnLayout { + anchors.fill: parent + anchors.margins: 100 + RowLayout { + spacing: 20 + Button { + text: 'Sushi' + highlighted: true + } + Button { + text: 'Sashimi' + } + Button { + text: 'Ramen' + } + } + + Image { + source: '../images/HMI_Settings_DividingLine.svg' + } + + ListView { + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: 10 + delegate: MouseArea { + width: ListView.view.width + height: 110 + RowLayout { + anchors.fill: parent + anchors.margins: 5 + spacing: 30 + Image { + source: './images/HMI_Settings_Example.svg' + } + + ColumnLayout { + Label { + id: title + Layout.fillWidth: true + text: 'Title' + font.pixelSize: 48 + } + Label { + id: subtitle + Layout.fillWidth: true + text: 'Subtitle' + color: '#66FF99' + font.pixelSize: 24 + } + } + + Button { + text: 'Go' + } + } + + Image { + source: '../images/HMI_Settings_DividingLine.svg' + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + visible: model.index > 0 + } + } + } + } +} diff --git a/app/example/example.qrc b/app/example/example.qrc new file mode 100644 index 0000000..5739f8e --- /dev/null +++ b/app/example/example.qrc @@ -0,0 +1,6 @@ + + + Example.qml + images/HMI_Settings_Example.svg + + diff --git a/app/example/images/HMI_Settings_Example.svg b/app/example/images/HMI_Settings_Example.svg new file mode 100644 index 0000000..5ad9479 --- /dev/null +++ b/app/example/images/HMI_Settings_Example.svg @@ -0,0 +1,72 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/images/HMI_Settings_DividingLine.svg b/app/images/HMI_Settings_DividingLine.svg new file mode 100644 index 0000000..d63589c --- /dev/null +++ b/app/images/HMI_Settings_DividingLine.svg @@ -0,0 +1,58 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/images/HMI_Settings_X.svg b/app/images/HMI_Settings_X.svg new file mode 100644 index 0000000..5ad9479 --- /dev/null +++ b/app/images/HMI_Settings_X.svg @@ -0,0 +1,72 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/images/images.qrc b/app/images/images.qrc new file mode 100644 index 0000000..0bb2c0d --- /dev/null +++ b/app/images/images.qrc @@ -0,0 +1,6 @@ + + + HMI_Settings_DividingLine.svg + HMI_Settings_X.svg + + diff --git a/app/main.cpp b/app/main.cpp new file mode 100644 index 0000000..ff3ca1e --- /dev/null +++ b/app/main.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBHOMESCREEN +#include +#endif + +int main(int argc, char *argv[]) +{ +#ifdef HAVE_LIBHOMESCREEN + LibHomeScreen libHomeScreen; + + if (!libHomeScreen.renderAppToAreaAllowed(0, 1)) { + qWarning() << "renderAppToAreaAllowed is denied"; + return -1; + } +#endif + + QGuiApplication app(argc, argv); + app.setApplicationName(QStringLiteral("HVAC")); + app.setApplicationVersion(QStringLiteral("0.1.0")); + app.setOrganizationDomain(QStringLiteral("automotivelinux.org")); + app.setOrganizationName(QStringLiteral("AutomotiveGradeLinux")); + + QQuickStyle::setStyle("AGL"); + + QCommandLineParser parser; + parser.addPositionalArgument("port", app.translate("main", "port for binding")); + parser.addPositionalArgument("secret", app.translate("main", "secret for binding")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.process(app); + QStringList positionalArguments = parser.positionalArguments(); + + + QQmlApplicationEngine engine; + if (positionalArguments.length() == 2) { + int port = positionalArguments.takeFirst().toInt(); + QString secret = positionalArguments.takeFirst(); + QUrl bindingAddress; + bindingAddress.setScheme(QStringLiteral("ws")); + bindingAddress.setHost(QStringLiteral("localhost")); + bindingAddress.setPort(port); + bindingAddress.setPath(QStringLiteral("/api")); + QUrlQuery query; + query.addQueryItem(QStringLiteral("token"), secret); + bindingAddress.setQuery(query); + QQmlContext *context = engine.rootContext(); + context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress); + } + engine.load(QUrl(QStringLiteral("qrc:/Settings.qml"))); + + return app.exec(); +} + diff --git a/app/settings.qrc b/app/settings.qrc new file mode 100644 index 0000000..189f441 --- /dev/null +++ b/app/settings.qrc @@ -0,0 +1,7 @@ + + + Settings.qml + SettingsLauncher.qml + SettingPage.qml + + diff --git a/app/wifi/Wifi.qml b/app/wifi/Wifi.qml new file mode 100644 index 0000000..7851967 --- /dev/null +++ b/app/wifi/Wifi.qml @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 QtQuick 2.6 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.0 +import '..' + +SettingPage { + id: root + icon: '/wifi/images/HMI_Settings_WifiIcon.svg' + title: 'Wifi' + checkable: true + + property string protocol: 'http://' + property string ipAddress: '127.0.0.1' + property string portNumber: Qt.application.arguments[1] + property string tokenString: Qt.application.arguments[2] + property string wifiAPI: '/api/wifi-manager/' + property string wifiAPIpath: protocol + ipAddress + ':' + portNumber + wifiAPI + + Text { + id: log + anchors.fill: parent + anchors.margins: 10 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + //text: "log" + } + + onCheckedChanged: { + console.log("Wifi set to", checked) + if (checked == true) { + periodicRefresh.start() + request(wifiAPIpath + 'activate', function (o) { + // log the json response + console.log(o.responseText) + }) + + } else { + //console.log(networkPath) + networkList.clear() + request(wifiAPIpath + 'deactivate', function (o) { + // log the json response + console.log(o.responseText) + }) + } + } + function listWifiNetworks() { + console.log("test #4") + } + ListModel { + id: networkList + } + + Rectangle { + id: buttonNetworkList + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.margins: 10 + width: buttonNetworkListText.width + 10 + height: buttonScanText.height + 10 + border.width: buttonNetworkListMouseArea.pressed ? 2 : 1 + radius: 5 + antialiasing: true + color: "#222" + border.color: "white" + Text { + color: "white" + id: buttonNetworkListText + anchors.centerIn: parent + text: "GET NETWORK LIST" + font.pixelSize: 40 + } + ListModel { + id: listModel + } + MouseArea { + id: buttonNetworkListMouseArea + anchors.fill: parent + onClicked: { + log.text = "" + console.log("\n") + networkList.clear() + request(wifiAPIpath + 'scan_result', function (o) { + // log the json response + console.log(o.responseText) + // translate response into object + var jsonObject = eval('(' + o.responseText + ')') + var jsonObjectNetworks = eval( + '(' + JSON.stringify(jsonObject.response) + ')') + //console.log(jsonObject.response) + for (var i = 0; i < jsonObjectNetworks.length; i++) { + networkList.append({ + number: jsonObjectNetworks[i].Number, + name: jsonObjectNetworks[i].ESSID, + strength: jsonObjectNetworks[i].Strength, + serviceState: jsonObjectNetworks[i].State, + security: jsonObjectNetworks[i].Security, + address: jsonObjectNetworks[i].IPAddress + }) + console.log(jsonObjectNetworks[i].Number, + jsonObjectNetworks[i].ESSID, + jsonObjectNetworks[i].Strength, + jsonObjectNetworks[i].State, + jsonObjectNetworks[i].Security, + jsonObjectNetworks[i].IPAddress) + } + }) + } + } + } + Rectangle { + id: buttonScan + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.margins: 80 + width: buttonScanText.width + 10 + height: buttonScanText.height + 10 + border.width: mouseArea.pressed ? 2 : 1 + //radius: 5 + //antialiasing: true + //color: "black" + color: "#222" + border.color: "white" + Text { + id: buttonScanText + anchors.centerIn: parent + text: "SCAN" + color: "white" + font.pixelSize: 40 + } + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: { + log.text = "" + console.log("\n") + request(wifiAPIpath + 'scan', function (o) { + // log the json response + console.log(o.responseText) + }) + } + } + } + function request(url, callback) { + var xhr = new XMLHttpRequest() + xhr.onreadystatechange = (function (myxhr) { + return function () { + if (xhr.readyState == 4 && xhr.status == 200) + callback(myxhr) + } + }) + (xhr) + xhr.open('GET', url, false) + xhr.send('') + } + + function securityType(security) { + if (security === "Open") + return "unsecured" + else + return "secured" + } + + Component { + id: wifiDevice + Rectangle { + height: 150 + width: parent.width + color: "#222" + Image { + anchors.top: parent.top + anchors.topMargin: 7 + anchors.left: parent.left + width: 70 + height: 50 + id: icon + source: { + if (securityType(security) === "unsecured") { + if (strength < 30) + source = "images/HMI_Settings_Wifi_1Bar.svg" + else if (strength >= 30 && strength < 50) + source = "images/HMI_Settings_Wifi_2Bars.svg" + else if (strength >= 50 && strength < 70) + source = "images/HMI_Settings_Wifi_3Bars.svg" + else + source = "images/HMI_Settings_Wifi_Full.svg" + } else { + if (strength < 30) + source = "images/HMI_Settings_Wifi_Locked_1Bar.svg" + else if (strength >= 30 && strength < 50) + source = "images/HMI_Settings_Wifi_Locked_2Bars.svg" + else if (strength >= 50 && strength < 70) + source = "images/HMI_Settings_Wifi_Locked_3Bars.svg" + else + source = "images/HMI_Settings_Wifi_Locked_Full.svg" + } + } + } + Column { + anchors.left: icon.right + anchors.leftMargin: 10 + Text { + text: name + font.pointSize: 30 + font.bold: { + if ((serviceState === "ready") + || serviceState === "online") + font.bold = true + else + font.bold = false + } + color: { + if ((serviceState === "ready") + || serviceState === "online") + color = "#00ff00" + else + color = "#ffffff" + } + } + Text { + visible: ((serviceState === "ready") + || serviceState === "online") ? true : false + text: "connected, " + address + font.pointSize: 18 + color: "#ffffff" + font.italic: true + } + } + Button { + id: connectButton + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: 5 + width: 250 + + MouseArea { + anchors.fill: parent + + Text { + anchors.fill: parent + id: buttonTextLabel + font.pixelSize: 15 + font.bold: true + color: "black" + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + text: { + if ((serviceState === "ready") + || serviceState === "online") + text = "Forget" + else + text = "Connect" + } + } + + onClicked: { + + //connectButton.border.color = "steelblue" + if ((serviceState === "ready") + || serviceState === "online") { + + //means we are connected + console.log("Disconnecting from", index, " ,", name) + request(wifiAPIpath + 'disconnect?network=' + index, + function (o) { + + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + } else { + console.log("Conect to", index, " ,", name) + + //passwordDialog.open() + request(wifiAPIpath + 'connect?network=' + index, + function (o) { + + // log the json response + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + } + } + } + } + + Button { + id: passwordButton + anchors.top: parent.top + anchors.right: parent.right + width: 40 + visible: (securityType(security) === "unsecured") ? false : true + + //anchors.rightMargin: connectButton.width + 5 + //buttonText: "Connect" + text: { + "Key" //or some icon? + } + + MouseArea { + anchors.fill: parent + + onClicked: { + + //connectButton.border.color = "steelblue" + passwordInputText.visible = true + connectButton.visible = false + passwordValidateButton.visible = true + + System.showKeyboard = visible + + //passwordInputText.o + periodicRefresh.stop() + + var passkey = passwordInputText.text.valueOf() + + //var passkey = 'randompassword' + console.log("Disconnecting from", index, " ,", name) + } + } + } + + Button { + id: passwordValidateButton + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: connectButton.width + 5 + width: 40 + visible: false + + //anchors.rightMargin: connectButton.width + 5 + //buttonText: "Connect" + text: { + "ok" //or some icon? + } + + MouseArea { + anchors.fill: parent + + onClicked: { + //passwordInputText = "" + var passkey = passwordInputText.text.valueOf() + console.log("Validating", passkey) + System.showKeyboard = false + + console.log("Passkey is", passkey) + request(wifiAPIpath + 'security?passkey=' + passkey, + function (o) { + + //showRequestInfo(o.responseText) + console.log(o.responseText) + }) + passwordValidateButton.visible = false + passwordInputText.visible = false + connectButton.visible = true + + keyboard.currentString = "" + + periodicRefresh.start() + } + } + } + + TextInput { + id: passwordInputText + anchors.top: parent.top + anchors.right: parent.right + anchors.rightMargin: 5 + + font.pointSize: 15 + color: "#ffffff" + + width: connectButton.width + visible: false + text: keyboard.currentString + } + } + } + ListView { + width: parent.width + anchors.top: parent.top + anchors.topMargin: 70 + anchors.bottom: parent.bottom + anchors.bottomMargin: 150 + model: networkList //WifiList {} + delegate: wifiDevice + clip: true + } + + //Timer for periodic refresh; this is BAD solution, need to figure out how to subscribe for events + Timer { + id: periodicRefresh + interval: 5000 // 5seconds + onTriggered: { + + networkList.clear() + request(wifiAPIpath + 'scan_result', function (o) { + // log the json response + console.log(o.responseText) + + // translate response into object + var jsonObject = eval('(' + o.responseText + ')') + var jsonObjectNetworks = eval('(' + JSON.stringify( + jsonObject.response) + ')') + console.log("WiFi list refreshed") + //console.log(jsonObject.response) + for (var i = 0; i < jsonObjectNetworks.length; i++) { + networkList.append({ + number: jsonObjectNetworks[i].Number, + name: jsonObjectNetworks[i].ESSID, + strength: jsonObjectNetworks[i].Strength, + serviceState: jsonObjectNetworks[i].State, + security: jsonObjectNetworks[i].Security, + address: jsonObjectNetworks[i].IPAddress + }) + } + }) + start() + } + } +} diff --git a/app/wifi/images/HMI_Settings_WifiIcon.svg b/app/wifi/images/HMI_Settings_WifiIcon.svg new file mode 100644 index 0000000..4314729 --- /dev/null +++ b/app/wifi/images/HMI_Settings_WifiIcon.svg @@ -0,0 +1,61 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_1Bar.svg b/app/wifi/images/HMI_Settings_Wifi_1Bar.svg new file mode 100644 index 0000000..e692c69 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_1Bar.svg @@ -0,0 +1,71 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_2Bars.svg b/app/wifi/images/HMI_Settings_Wifi_2Bars.svg new file mode 100644 index 0000000..f7cf642 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_2Bars.svg @@ -0,0 +1,71 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_3Bars.svg b/app/wifi/images/HMI_Settings_Wifi_3Bars.svg new file mode 100644 index 0000000..8a26f3f --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_3Bars.svg @@ -0,0 +1,71 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Full.svg b/app/wifi/images/HMI_Settings_Wifi_Full.svg new file mode 100644 index 0000000..9ad1869 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Full.svg @@ -0,0 +1,70 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg b/app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg new file mode 100644 index 0000000..5da957f --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg @@ -0,0 +1,78 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg b/app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg new file mode 100644 index 0000000..7f180aa --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg @@ -0,0 +1,78 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg b/app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg new file mode 100644 index 0000000..276c758 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg @@ -0,0 +1,78 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg b/app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg new file mode 100644 index 0000000..9058511 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg @@ -0,0 +1,77 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_Locked_NoBars.svg b/app/wifi/images/HMI_Settings_Wifi_Locked_NoBars.svg new file mode 100644 index 0000000..6f389c6 --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_Locked_NoBars.svg @@ -0,0 +1,79 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/images/HMI_Settings_Wifi_NoBars.svg b/app/wifi/images/HMI_Settings_Wifi_NoBars.svg new file mode 100644 index 0000000..e23fc1d --- /dev/null +++ b/app/wifi/images/HMI_Settings_Wifi_NoBars.svg @@ -0,0 +1,70 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/wifi/wifi.qrc b/app/wifi/wifi.qrc new file mode 100644 index 0000000..063088a --- /dev/null +++ b/app/wifi/wifi.qrc @@ -0,0 +1,16 @@ + + + Wifi.qml + images/HMI_Settings_Wifi_1Bar.svg + images/HMI_Settings_Wifi_2Bars.svg + images/HMI_Settings_Wifi_3Bars.svg + images/HMI_Settings_Wifi_Full.svg + images/HMI_Settings_Wifi_Locked_1Bar.svg + images/HMI_Settings_Wifi_Locked_2Bars.svg + images/HMI_Settings_Wifi_Locked_3Bars.svg + images/HMI_Settings_Wifi_Locked_Full.svg + images/HMI_Settings_Wifi_Locked_NoBars.svg + images/HMI_Settings_Wifi_NoBars.svg + images/HMI_Settings_WifiIcon.svg + + diff --git a/binding-bluetooth/binding-bluetooth.pro b/binding-bluetooth/binding-bluetooth.pro new file mode 100644 index 0000000..9dba7a1 --- /dev/null +++ b/binding-bluetooth/binding-bluetooth.pro @@ -0,0 +1,11 @@ +TARGET = settings-bluetooth-binding + +HEADERS = bluetooth-api.h bluetooth-manager.h +SOURCES = bluetooth-api.c bluetooth-manager.c + +LIBS += -Wl,--version-script=$$PWD/export.map + +CONFIG += link_pkgconfig +PKGCONFIG += json-c afb-daemon glib-2.0 gio-2.0 gobject-2.0 zlib + +include(binding.pri) diff --git a/binding-bluetooth/binding.pri b/binding-bluetooth/binding.pri new file mode 100644 index 0000000..3448a56 --- /dev/null +++ b/binding-bluetooth/binding.pri @@ -0,0 +1,6 @@ +TEMPLATE = lib +CONFIG += plugin use_c_linker +CONFIG -= qt +QMAKE_CFLAGS += -Wextra -Wconversion -Wno-unused-parameter -Werror=maybe-uninitialized -Werror=implicit-function-declaration -ffunction-sections -fdata-sections -Wl,--as-needed -Wl,--gc-sections + +DESTDIR = $${OUT_PWD}/../package/root/lib diff --git a/binding-bluetooth/bluetooth-api.c b/binding-bluetooth/bluetooth-api.c new file mode 100644 index 0000000..f7e2d9a --- /dev/null +++ b/binding-bluetooth/bluetooth-api.c @@ -0,0 +1,503 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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. +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include "bluetooth-api.h" +#include "bluetooth-manager.h" + + +/* + * the interface to afb-daemon + */ +const struct afb_binding_interface *afbitf; + + +/* ------ PUBLIC PLUGIN FUNCTIONS --------- */ + +/**/ +static void bt_power (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + json_object *jresp = NULL; + int ret = 0; + + jresp = json_object_new_object(); + + /* no "?value=" parameter : return current state */ + if (!value) { + gboolean power_value; + ret = adapter_get_powered(&power_value); + + if (0==ret) + { + (TRUE==power_value)?json_object_object_add (jresp, "power", json_object_new_string ("on")) + : json_object_object_add (jresp, "power", json_object_new_string ("off")); + } + else + { + afb_req_fail (request, "failed", "Unable to get power status"); + return; + } + + } + + /* "?value=" parameter is "1" or "true" */ + else if ( atoi(value) == 1 || !strcasecmp(value, "true") ) + { + if (adapter_set_powered (TRUE)) + { + afb_req_fail (request, "failed", "no more radio devices available"); + return; + } + json_object_object_add (jresp, "power", json_object_new_string ("on")); + } + + /* "?value=" parameter is "0" or "false" */ + else if ( atoi(value) == 0 || !strcasecmp(value, "false") ) + { + if (adapter_set_powered (FALSE)) + { + afb_req_fail (request, "failed", "Unable to release radio device"); + return; + } + + json_object_object_add (jresp, "power", json_object_new_string ("off")); + } + else + { + afb_req_fail (request, "failed", "Invalid value"); + return; + } + + afb_req_success (request, jresp, "Radio - Power set"); +} + +/**/ +static void bt_start_discovery (struct afb_req request) +{ + D_PRINTF("\n"); + int ret = 0; + + ret = adapter_start_discovery(); + + if (ret) + { + afb_req_fail (request, "failed", "Unable to start discovery"); + return; + } + + afb_req_success (request, NULL, NULL); +} + +/**/ +static void bt_stop_discovery (struct afb_req request) +{ + D_PRINTF("\n"); + int ret = 0; + + ret = adapter_stop_discovery(); + + if (ret) + { + afb_req_fail (request, "failed", "Unable to stop discovery"); + return; + } + + afb_req_success (request, NULL, NULL); +} + + +/**/ +static void bt_discovery_result (struct afb_req request) +{ + D_PRINTF("\n"); + GSList *list = NULL; + adapter_update_devices(); + list = adapter_get_devices_list(); + if (NULL == list) + { + afb_req_fail (request, "failed", "No find devices"); + return; + } + + json_object *my_array = json_object_new_array(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + //D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + + json_object *jresp = json_object_new_object(); + json_object *jstring1 = NULL; + json_object *jstring2 = NULL; + json_object *jstring3 = NULL; + json_object *jstring4 = NULL; + json_object *jstring5 = NULL; + json_object *jstring6 = NULL; + + + + if (BDdevice->bdaddr) + { + jstring1 = json_object_new_string(BDdevice->bdaddr); + } + else + { + jstring1 = json_object_new_string(""); + } + + + if (BDdevice->name) + { + jstring2 = json_object_new_string(BDdevice->name); + } + else + { + jstring2 = json_object_new_string(""); + } + + jstring3 = (TRUE == BDdevice->paired) ? json_object_new_string("True"):json_object_new_string("False"); + jstring4 = (TRUE == BDdevice->connected) ? json_object_new_string("True"):json_object_new_string("False"); + jstring5 = (TRUE == isAVPConnected(BDdevice)) ? json_object_new_string("True"):json_object_new_string("False"); + jstring6 = (TRUE == isHFPConnected(BDdevice)) ? json_object_new_string("True"):json_object_new_string("False"); + + + json_object_object_add(jresp, "Address", jstring1); + json_object_object_add(jresp, "Name", jstring2); + json_object_object_add(jresp, "Paired", jstring3); + json_object_object_add(jresp, "Connected", jstring4); + json_object_object_add(jresp, "AVPConnected", jstring5); + json_object_object_add(jresp, "HFPConnected", jstring6); + json_object_array_add(my_array, jresp); + } + + afb_req_success(request, my_array, "BT - Scan Result is Displayed"); +} + +/**/ +static void bt_pair (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == value) + { + afb_req_fail (request, "failed", "Please Input the Device Address"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,value)) + { + D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = device_pair(BDdevice); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device pairing failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); + +} + +/**/ +static void bt_cancel_pairing (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == value) + { + afb_req_fail (request, "failed", "Please Input the Device Address"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,value)) + { + D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = device_cancelPairing(BDdevice); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device pairing failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); + +} + +/**/ +static void bt_connect (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == value) + { + afb_req_fail (request, "failed", "Please Input the Device Address"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,value)) + { + D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = device_connect(BDdevice); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device pairing failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); +} + +/**/ +static void bt_disconnect (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == value) + { + afb_req_fail (request, "failed", "Please Input the Device Address"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,value)) + { + D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = device_disconnect(BDdevice); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device pairing failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); +} + +/**/ +static void bt_remove_device (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == value) + { + afb_req_fail (request, "failed", "Please Input the Device Address"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,value)) + { + D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = adapter_remove_device(BDdevice); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device pairing failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); +} + + +/**/ +static void bt_set_property (struct afb_req request) +{ + D_PRINTF("\n"); + + const char *address = afb_req_value (request, "Address"); + const char *property = afb_req_value (request, "Property"); + const char *value = afb_req_value (request, "value"); + int ret = 0; + GSList *list = NULL; + + if (NULL == address || NULL==property || NULL==value) + { + afb_req_fail (request, "failed", "Please Check Input Parameter"); + return; + } + + list = adapter_get_devices_list(); + + for(;list;list=list->next) + { + struct btd_device *BDdevice = list->data; + + if ((NULL!=BDdevice->bdaddr)&&g_strrstr(BDdevice->bdaddr,address)) + { + //D_PRINTF("\n%s\t%s\n",BDdevice->bdaddr,BDdevice->name); + ret = device_set_property(BDdevice, property, value); + if (0 == ret) + { + afb_req_success (request, NULL, NULL); + } + else + { + afb_req_fail (request, "failed", "Device set property failed"); + } + return; + } + } + + afb_req_fail (request, "failed", "Not found device"); +} + + + +/* + * array of the verbs exported to afb-daemon + */ +static const struct afb_verb_desc_v1 binding_verbs[]= { +/* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ +{ .name = "power", .session = AFB_SESSION_NONE, .callback = bt_power, .info = "Set Bluetooth Power ON or OFF" }, +{ .name = "start_discovery", .session = AFB_SESSION_NONE, .callback = bt_start_discovery, .info = "Start discovery" }, +{ .name = "stop_discovery", .session = AFB_SESSION_NONE, .callback = bt_stop_discovery, .info = "Stop discovery" }, +{ .name = "discovery_result", .session = AFB_SESSION_NONE, .callback = bt_discovery_result, .info = "Get discovery result" }, +{ .name = "remove_device", .session = AFB_SESSION_NONE, .callback = bt_remove_device, .info = "Remove the special device" }, +{ .name = "pair", .session = AFB_SESSION_NONE, .callback = bt_pair, .info = "Pair to special device" }, +{ .name = "cancel_pair", .session = AFB_SESSION_NONE, .callback = bt_cancel_pairing, .info = "Cancel the pairing process" }, +{ .name = "connect", .session = AFB_SESSION_NONE, .callback = bt_connect, .info = "Connect to special device" }, +{ .name = "disconnect", .session = AFB_SESSION_NONE, .callback = bt_disconnect, .info = "Disconnect special device" }, +{ .name = "set_property", .session = AFB_SESSION_NONE, .callback = bt_set_property, .info = "Set special device property" }, + +{ .name = NULL } /* marker for end of the array */ +}; + +/* + * description of the binding for afb-daemon + */ +static const struct afb_binding binding_description = +{ + .type = AFB_BINDING_VERSION_1, + .v1 = { + .info = "Application Framework Binder - Bluetooth Manager plugin", + .prefix = "Bluetooth-Manager", + .verbs = binding_verbs + } +}; + +/* + * activation function for registering the binding called by afb-daemon + */ +const struct afb_binding *afbBindingV1Register (const struct afb_binding_interface *itf) +{ + afbitf = itf; // records the interface for accessing afb-daemon + //D_PRINTF("\n"); +#if 1 +//temp solution to fix configure Bluetooth USB Dongle + system("rfkill unblock bluetooth"); + system("hciconfig hci0 up"); +#endif + BluetoothManageInit(); + return &binding_description; +} + +#if 0 +int afbBindingV1ServiceInit(struct afb_service service) +{ + return BluetoothManageInit(); +} +#endif + + +/************************************** The End Of File **************************************/ + diff --git a/binding-bluetooth/bluetooth-api.h b/binding-bluetooth/bluetooth-api.h new file mode 100644 index 0000000..8a7e593 --- /dev/null +++ b/binding-bluetooth/bluetooth-api.h @@ -0,0 +1,50 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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. +*/ + + +#ifndef BLUETOOTH_API_H +#define BLUETOOTH_API_H + + + + +//#define _DEBUG +#ifdef _DEBUG +#define D_PRINTF(fmt, args...) \ + printf("[DEBUG][%s:%d:%s]"fmt, __FILE__, __LINE__, __FUNCTION__, ## args) +#define D_PRINTF_RAW(fmt, args...) \ + printf(""fmt, ## args) +#else /* ifdef _DEBUG */ +#define D_PRINTF(fmt, args...) +#define D_PRINTF_RAW(fmt, args...) +#endif /* ifdef _DEBUG */ +#define E_PRINTF(fmt, args...) \ + printf("[ERROR][%s:%d:%s]"fmt, __FILE__, __LINE__, __FUNCTION__, ## args) + + +/* -------------- PLUGIN DEFINITIONS ----------------- */ + +typedef struct { + void *bt_server; /* handle to implementation */ + unsigned int index; /* currently selected media file */ +} BtCtxHandleT; + +#endif /* BLUETOOTH_API_H */ + + + +/************************************** The End Of File **************************************/ + + diff --git a/binding-bluetooth/bluetooth-manager.c b/binding-bluetooth/bluetooth-manager.c new file mode 100644 index 0000000..4c49196 --- /dev/null +++ b/binding-bluetooth/bluetooth-manager.c @@ -0,0 +1,747 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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 +#include +#include +#include +#include +#include +#include + +#include "bluetooth-api.h" +#include "bluetooth-manager.h" + +Client cli = { 0 }; + +stBluetoothManage BluetoothManage = { 0 }; + +/* ------ LOCAL FUNCTIONS --------- */ + +/* + register the agent, and register signal watch + */ +void bt_manage_dbus_init(void) { + D_PRINTF("\n"); + + //InitDBusCommunication(); + +} +/* ------ PUBLIC PLUGIN FUNCTIONS --------- */ + +/* + * Init the Bluetooth Manager + * Note: bluetooth-api shall do BluetoothManageInit() first before call other APIs. + */ +int BluetoothManageInit() { + D_PRINTF("\n"); + + BluetoothManage.device = NULL; + g_mutex_init(&(BluetoothManage.m)); + + bt_manage_dbus_init(); + + return 0; +} + +/* + * Set the Bluez Adapter Property "Powered" value + * If success return 0, else return -1; + */ +int adapter_set_powered(gboolean powervalue) { + D_PRINTF("value:%d\n",powervalue); + GDBusConnection *connection; + GError *error = NULL; + + GVariant *value; + gboolean result; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, ADAPTER_PATH, + FREEDESKTOP_PROPERTIES, "Set", + g_variant_new("(ssv)", ADAPTER_INTERFACE, "Powered", + g_variant_new("b", powervalue)), NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; +} + +/* + * Get the Bluez Adapter Property "Powered" value + * If success return 0, else return -1; + */ +int adapter_get_powered(gboolean *powervalue) { + D_PRINTF("\n"); + GDBusConnection *connection; + GError *error = NULL; + GVariant *value = NULL; + GVariant *subValue = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, ADAPTER_PATH, + FREEDESKTOP_PROPERTIES, "Get", + g_variant_new("(ss)", ADAPTER_INTERFACE, "Powered"), NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + g_error_free(error); + return -1; + } + + g_variant_get(value, "(v)", &subValue); + g_variant_get(subValue, "b", powervalue); + g_variant_unref(value); + + D_PRINTF("get ret :%d\n",*powervalue); + return 0; +} + +/* + * Call the Bluez Adapter Method "StartDiscovery" + * If success return 0, else return -1; + */ +int adapter_start_discovery() { + D_PRINTF("\n"); + GDBusConnection *connection = NULL; + GError *error = NULL; + GVariant *value = NULL; + GVariant *subValue = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, ADAPTER_PATH, + ADAPTER_INTERFACE, "StartDiscovery", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; +} + +/* + * Call the Bluez Adapter Method "StopDiscovery" + * If success return 0, else return -1; + */ +int adapter_stop_discovery() { + D_PRINTF("\n"); + GDBusConnection *connection = NULL; + GError *error = NULL; + GVariant *value = NULL; + GVariant *subValue = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, ADAPTER_PATH, + ADAPTER_INTERFACE, "StopDiscovery", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + + return 0; +} + +/* + * Call the Bluez Adapter Method "RemoveDevice" + * If success return 0, else return -1; + */ +int adapter_remove_device(struct btd_device * addr) { + D_PRINTF("\n%s\t%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *value; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, ADAPTER_PATH, + ADAPTER_INTERFACE, "RemoveDevice", g_variant_new("(o)", addr->path), NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; + +} + +/* + * Get the store device list. + */ +//FIXME: gdevices should be added the lock/unlock +GSList* adapter_get_devices_list() { + return BluetoothManage.device; +} + +void lock_devices_list(void) { + g_mutex_lock(&(BluetoothManage.m)); +} + +void unlock_devices_list(void) { + g_mutex_unlock(&(BluetoothManage.m)); +} + +/* + * Update the device list + * Call GetManagedObjects + * reply type is "Dict of {Object Path, Dict of {String, Dict of {String, Variant}}}" + */ +#if 0 +// Test Function +/* recursively iterate a container */ +void iterate_container_recursive (GVariant *container) +{ + GVariantIter iter; + GVariant *child; + + g_variant_iter_init (&iter, container); + while ((child = g_variant_iter_next_value (&iter))) + { + g_print ("type '%s'\n", g_variant_get_type_string (child)); + + if (g_variant_is_container (child)) + iterate_container_recursive (child); + + g_variant_unref (child); + } +} +#endif + +int adapter_update_devices() { + D_PRINTF("\n"); + GDBusConnection *connection = NULL; + GError *error = NULL; + GVariant *value = NULL; + GSList *newDeviceList = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, "/", + "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", NULL, + NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + g_error_free(error); + return -1; + } + + GVariant *subValue = NULL; + GVariant *subValue_1 = NULL; + GVariantIter *subValueIter; + + g_variant_get(value, "(*)", &subValue); + + g_variant_get(subValue, "a*", &subValueIter); + while (g_variant_iter_loop(subValueIter, "*", &subValue_1)) { + +#if 0 + iterate_container_recursive(subValue_1); +#else + +//FIXME:Bad solution to get the BT address and name + GVariantIter dbus_object_iter; + GVariant *dbusObjecValue; + GVariant *dbusObjecSubValue; + gchar *dbusObjecPath; + struct btd_device *device; + + g_variant_iter_init(&dbus_object_iter, subValue_1); + + //DBus Object + dbusObjecValue = g_variant_iter_next_value(&dbus_object_iter); + + g_variant_get(dbusObjecValue, "o", &dbusObjecPath); + + //ObjectPath is /org/bluez/hci0/dev_xx_xx_xx_xx_xx_xx + if ((37 != strlen(dbusObjecPath)) + || (NULL + == g_strrstr_len(dbusObjecPath, 19, + "/org/bluez/hci0/dev"))) { + g_variant_unref(dbusObjecValue); + continue; + } + device = g_try_malloc0(sizeof(struct btd_device)); + device->path = g_strdup(dbusObjecPath); + g_variant_unref(dbusObjecValue); + D_PRINTF("Found new device%s\n",device->path ); + + //DBus Interfaces and Method/Properties under Interface + dbusObjecSubValue = g_variant_iter_next_value(&dbus_object_iter); + + GVariantIter *interfaces_iter; + GVariant *interfaces_subValue; + g_variant_get(dbusObjecSubValue, "a*", &interfaces_iter); + + while (g_variant_iter_loop(interfaces_iter, "*", &interfaces_subValue)) { + // D_PRINTF("\t%s\n",g_variant_get_type_string(interfaces_subValue)); + + GVariantIter MethodsSignalProperties_iter; + GVariant *MethodsSignalProperties_name; + GVariant *MethodsSignalProperties_value; + gchar *properties_name; + + g_variant_iter_init(&MethodsSignalProperties_iter, + interfaces_subValue); + + //DBus Interfaces + MethodsSignalProperties_name = g_variant_iter_next_value( + &MethodsSignalProperties_iter); + + g_variant_get(MethodsSignalProperties_name, "s", &properties_name); + //D_PRINTF("\t%s\n",properties_name); + g_variant_unref(MethodsSignalProperties_name); + + if (NULL + == g_strrstr_len(properties_name, 20, + "org.bluez.Device1")) { + continue; + } + + D_PRINTF("\t%s\n",properties_name); + + //DBus XXX + MethodsSignalProperties_value = g_variant_iter_next_value( + &MethodsSignalProperties_iter); + + GVariantIter *subValue_iter; + GVariant *subValueVariant; + g_variant_get(MethodsSignalProperties_value, "a*", &subValue_iter); + + while (g_variant_iter_loop(subValue_iter, "*", &subValueVariant)) { + GVariantIter sub_subValue_iter; + GVariant *sub_subValue_name; + GVariant *sub_subValue_value; + gchar *key_1 = NULL; + gchar *key_2 = NULL; + + g_variant_iter_init(&sub_subValue_iter, subValueVariant); + + //DBus Interfaces + sub_subValue_name = g_variant_iter_next_value( + &sub_subValue_iter); + + g_variant_get(sub_subValue_name, "s", &key_1); + D_PRINTF("\t\t%s\n",key_1); + + //DBus XXX + sub_subValue_value = g_variant_iter_next_value( + &sub_subValue_iter); + + GVariant *dbus_value; + dbus_value = g_variant_get_variant(sub_subValue_value); + + if (g_variant_is_of_type(dbus_value, G_VARIANT_TYPE_STRING)) { + g_variant_get(dbus_value, "s", &key_2); + //D_PRINTF("\t\t\t%s\ts%s\n",key_1,key_2); + + if (g_strrstr_len(key_1, 10, "Address")) { + device->bdaddr = g_strdup(key_2); + } else if (g_strrstr_len(key_1, 10, "Name")) { + device->name = g_strdup(key_2); + } + g_free(key_2); + + } else if (g_variant_is_of_type(dbus_value, + G_VARIANT_TYPE_BOOLEAN)) { + gboolean properties_value; + g_variant_get(dbus_value, "b", &properties_value); + + if (g_strrstr_len(key_1, 10, "Paired")) { + device->paired = properties_value; + } else if (g_strrstr_len(key_1, 10, "Blocked")) { + device->blocked = properties_value; + } else if (g_strrstr_len(key_1, 10, "Connected")) { + device->connected = properties_value; + } else if (g_strrstr_len(key_1, 10, "Trusted")) { + device->trusted = properties_value; + } + + } + g_variant_unref(sub_subValue_name); + g_variant_unref(sub_subValue_value); + + } + g_variant_iter_free(subValue_iter); + + g_variant_unref(MethodsSignalProperties_value); + + } + g_variant_iter_free(interfaces_iter); + + g_variant_unref(dbusObjecSubValue); + +#endif + + newDeviceList = g_slist_append(newDeviceList, device); + + } + + g_variant_iter_free(subValueIter); + + g_variant_unref(value); + + //clean first + GSList * temp = BluetoothManage.device; + while (temp) { + struct btd_device *BDdevice = temp->data; + temp = temp->next; + + BluetoothManage.device = g_slist_remove_all(BluetoothManage.device, + BDdevice); + //D_PRINTF("\n%s\n%s\n",BDdevice->bdaddr,BDdevice->name); + if (BDdevice->bdaddr) { + g_free(BDdevice->bdaddr); + } + if (BDdevice->name) { + g_free(BDdevice->name); + } + if (BDdevice->path) { + g_free(BDdevice->path); + } + g_free(BDdevice); + + } + + BluetoothManage.device = newDeviceList; + +} + +/* + * send pairing command + * If success return 0, else return -1; + */ +int device_pair(struct btd_device * addr) { + D_PRINTF("\n%s\n%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *value; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + "org.bluez.Device1", "Pair", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; + +} + +/* + * send cancel pairing command + * If success return 0, else return -1; + */ +int device_cancelPairing(struct btd_device * addr) { + D_PRINTF("\n%s\n%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *value; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + "org.bluez.Device1", "CancelPairing", NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; + +} +/* + * send connect command + * If success return 0, else return -1; + */ +int device_connect(struct btd_device * addr) { + D_PRINTF("\n%s\n%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *value; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + "org.bluez.Device1", "Connect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; + +} + +/* + * send disconnect command + * If success return 0, else return -1; + */ +int device_disconnect(struct btd_device * addr) { + D_PRINTF("\n%s\n%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *value; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + "org.bluez.Device1", "Disconnect", NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(value); + return 0; + +} + +/* + * set remote device property + * If success return 0, else return -1; + */ +int device_set_property(struct btd_device * addr, const char *property_name, + const char *property_value) { + D_PRINTF("\n%s\n%s\t%s\n",addr->bdaddr,addr->name,addr->path); + + GDBusConnection *connection; + GError *error = NULL; + GVariant *ret; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + //Only support set "Trusted" + if (strcmp(property_name, "Trusted")) { + D_PRINTF("Not support property name\n"); + return -1; + } + + gboolean value; + if (atoi(property_value) == 1 || !strcasecmp(property_value, "true")) { + value = TRUE; + } else if (atoi(property_value) == 0 + || !strcasecmp(property_value, "false")) { + value = FALSE; + } else { + D_PRINTF("Not support property value\n"); + return -1; + } + + ret = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + FREEDESKTOP_PROPERTIES, "Set", + g_variant_new("(ssv)", DEVICE_INTERFACE, property_name, + g_variant_new("b", value)), NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == ret) { + D_PRINTF ("Error getting object manager client: %s", error->message); + g_error_free(error); + return -1; + } + + g_variant_unref(ret); + return 0; +} + +int isAVPConnected(struct btd_device *addr) { + + GDBusConnection *connection; + + GError *error = NULL; + GVariant *value; + GVariant *variantValue; + gboolean status; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + +// value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, BDdevice->path, FREEDESKTOP_PROPERTIES, +// "Get", g_variant_new("(ss)",MEDIA_CONTROL1_INTERFACE,"Connected"), +// NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + value = g_dbus_connection_call_sync(connection, BLUEZ_SERVICE, addr->path, + FREEDESKTOP_PROPERTIES, "Get", + g_variant_new("(ss)", MEDIA_CONTROL1_INTERFACE, "Connected"), NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + + g_error_free(error); + return -1; + } + + else { + g_variant_get(value, "(v)", &variantValue); + g_variant_get(variantValue, "b", &status); + printf("Address: %s:%i",addr->bdaddr, status); + return status; + } + + return 0; + +} + +int isHFPConnected(struct btd_device *addr) { + + GDBusConnection *connection; + + GError *error = NULL; + GVariant *value; + gchar *ofono_path; + gboolean status; + + GVariantIter *array; + GVariant *var = NULL; + const gchar *key = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (NULL == connection) { + D_PRINTF("GDBusconnection is NULL\n"); + return -1; + } + + +//path=/hfp/org/bluez/hci0/dev_E0_98_61_7D_D3_1E; interface=org.ofono.Modem; member=GetProperties + + ofono_path = g_strconcat("/hfp", addr->path, NULL); + + + value = g_dbus_connection_call_sync(connection, OFONO_SERVICE, ofono_path, + OFONO_MODEM_INTERFACE, "GetProperties", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (NULL == value) { + D_PRINTF ("Error getting object manager client: %s\n", error->message); + + g_error_free(error); + return -1; + } + + else { + + g_variant_get(value, "(a{sv})", &array); + while (g_variant_iter_loop(array, "{sv}", &key, &var)) { + if (g_strcmp0(key, "Powered") == 0) { + + g_variant_get(var, "b", &status); + + return status; + + } + } + g_variant_iter_free(array); + g_variant_unref(value); + g_free(ofono_path); + + return status; + } + + return 0; + +} + +/************************************** The End Of File **************************************/ + diff --git a/binding-bluetooth/bluetooth-manager.h b/binding-bluetooth/bluetooth-manager.h new file mode 100644 index 0000000..cb018b0 --- /dev/null +++ b/binding-bluetooth/bluetooth-manager.h @@ -0,0 +1,143 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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. +*/ + + +#ifndef BLUETOOTH_MANAGER_H +#define BLUETOOTH_MANAGER_H + +#include +#include +//#include +#include +#include +#include +//service +#define AGENT_SERVICE "org.agent" + +//remote service +#define BLUEZ_SERVICE "org.bluez" +#define OFONO_SERVICE "org.ofono" +#define CLIENT_SERVICE "org.bluez.obex" + +//object path +#define OFONO_MANAGER_PATH "/" +#define ADAPTER_PATH "/org/bluez/hci0" +#define OBEX_CLIENT_PATH "/org/bluez/obex" +#define AGENT_PATH "/org/bluez" + +//interface +#define ADAPTER_INTERFACE "org.bluez.Adapter1" +#define DEVICE_INTERFACE "org.bluez.Device1" +#define AGENT_MANAGER_INTERFACE "org.bluez.AgentManager" +#define SERVICE_INTERFACE "org.bluez.Service" +#define AGENT_INTERFACE "org.bluez.Agent" + +#define CLIENT_INTERFACE "org.bluez.obex.Client" +#define TRANSFER_INTERFACE "org.bluez.obex.Transfer" +#define SESSION_INTERFACE "org.bluez.obex.Session" +#define OBEX_ERROR_INTERFACE "org.bluez.obex.Error" +#define BLUEZ_ERROR_INTERFACE "org.bluez.Error" +#define PBAP_INTERFACE "org.bluez.obex.PhonebookAccess" +#define MAP_INTERFACE "org.bluez.obex.MessageAccess" +#define MAP_MSG_INTERFACE "org.bluez.obex.Message" + +#define MEDIA_PLAYER_INTERFACE "org.bluez.MediaPlayer" +#define MEDIA_FOLDER_INTERFACE "org.bluez.MediaFolder" +#define MEDIA_ITEM_INTERFACE "org.bluez.MediaItem" +#define MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport" +#define MEDIA_CONTROL1_INTERFACE "org.bluez.MediaControl1" + + +#define OFONO_HANDSFREE_INTERFACE "org.ofono.Handsfree" +#define OFONO_MANAGER_INTERFACE "org.ofono.Manager" +#define OFONO_MODEM_INTERFACE "org.ofono.Modem" +#define OFONO_VOICECALL_INTERFACE "org.ofono.VoiceCall" +#define OFONO_VOICECALL_MANAGER_INTERFACE "org.ofono.VoiceCallManager" +#define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration" +#define OFONO_NETWORK_OPERATOR_INTERFACE "org.ofono.NetworkOperator" +#define OFONO_CALL_VOLUME_INTERFACE "org.ofono.CallVolume" + +#define FREEDESKTOP_INTROSPECT "org.freedesktop.DBus.Introspectable" +#define FREEDESKTOP_PROPERTIES "org.freedesktop.DBus.Properties" + + +#define CONVERTER_CONN (cli.sys_conn) +#define AGENT_CONN (cli.agent_conn) +#define OBEX_CONN (cli.obex_conn) + +#define DBUS_REPLY_TIMEOUT (120 * 1000) +#define DBUS_REPLY_TIMEOUT_SHORT (10 * 1000) + +//typedef void(*callback)(void); +typedef void(*callback)(int password_rejected_flag); +void register_callback(callback ptr); + + +typedef struct _client +{ + GDBusConnection *sys_conn; + GDBusConnection *agent_conn; + GDBusConnection *obex_conn; + GMainLoop *clientloop; +// FILE *fd; +// int conn_fd; +} Client; + +//Bluetooth Device Properties +struct btd_device { + gchar *bdaddr; + gchar *path; + gchar *name; + gboolean paired; + gboolean trusted; + gboolean blocked; + gboolean connected; + gboolean avconnected; + gboolean hfpconnected; + GSList *uuids; +}; + +typedef struct { + gboolean inited; + GMutex m; + GSList * device; +} stBluetoothManage; + +int BluetoothManageInit(void); + +int adapter_set_powered(gboolean value); +int adapter_get_powered(gboolean *value); +int adapter_set_discoverable(gboolean value); +int adapter_start_discovery(); +int adapter_stop_discovery(); +int adapter_update_devices(); +GSList* adapter_get_devices_list(); +int adapter_remove_device(struct btd_device * addr); +int device_pair(struct btd_device * addr); +int device_cancelPairing(struct btd_device * addr); +int device_connect(struct btd_device * addr); +//int device_connectProfile(); +int device_disconnect(struct btd_device * addr); +//int device_disconnectProfile(); +int device_set_property(struct btd_device * addr, const char *property, const char *value); + +int isAVPConnected(struct btd_device *BDdevice); +int isHFPConnected(struct btd_device *BDdevice); + +#endif /* BLUETOOTH_MANAGER_H */ + + +/************************************** The End Of File **************************************/ + diff --git a/binding-bluetooth/export.map b/binding-bluetooth/export.map new file mode 100644 index 0000000..0ef1ac7 --- /dev/null +++ b/binding-bluetooth/export.map @@ -0,0 +1 @@ +{ global: afbBindingV1Register; local: *; }; diff --git a/binding-wifi/agent.c b/binding-wifi/agent.c new file mode 100644 index 0000000..a22dc31 --- /dev/null +++ b/binding-wifi/agent.c @@ -0,0 +1,262 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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 +#include + +#include +#include "wifi-connman.h" + +static GMainLoop *loop = NULL; + +static GDBusNodeInfo *introspection_data = NULL; + +GDBusMethodInvocation *invocation_passkey = NULL; + +/* Introspection data for the agent service */ +static const gchar introspection_xml[] = "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +callback password_callback; + +static void handle_method_call(GDBusConnection *connection, const gchar *sender, + const gchar *object_path, const gchar *interface_name, + const gchar *method_name, GVariant *parameters, + GDBusMethodInvocation *invocation, gpointer user_data) { + //MyObject *myobj = user_data; + + if (g_strcmp0(method_name, "RequestInput") == 0) { + printf("Input requested\n"); + + invocation_passkey = invocation; + + //TODO: send the name of the network to callback + + (*password_callback)(0); + + GVariantIter *array; + gchar * object_path; + g_variant_get(parameters, "(oa{sv})", &object_path, &array); + //TODO: get only object path for now, complete parameters are + + /* + object path "/net/connman/service/wifi_d85d4c880b1a_4c656e6f766f204b3520506c7573_managed_psk" + array [ + dict entry( + string "Passphrase" + variant array [ + dict entry( + string "Type" + variant string "psk" + ) + dict entry( + string "Requirement" + variant string "mandatory" + ) + ] + ) + ] + */ + printf("Passphrase requested for network : %s\n", object_path); + + } + + if (g_strcmp0(method_name, "ReportError") == 0) { + printf("Error reported\n"); + + gchar *error_string; // = NULL; + + gchar * object_path; + g_variant_get(parameters, "(os)", &object_path, &error_string); + + printf("Error %s for %s\n", error_string, object_path); + + if (g_strcmp0(error_string, "invalid-key") == 0) { + + printf("Passkey is not correct.\n"); + (*password_callback)(1); + + } + + } +} + +GError* sendPasskey(gchar *passkey) { + + GVariantBuilder *builder; + GVariant *value = NULL; + + printf("Passkey to send: %s\n", passkey); + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + g_variant_builder_add(builder, "{sv}", "Passphrase", + g_variant_new_string(passkey)); + + value = g_variant_new("(a{sv})", builder); + + g_dbus_method_invocation_return_value(invocation_passkey, value); + + return NULL; + +} + +static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, + NULL }; + +static void on_bus_acquired(GDBusConnection *connection, const gchar *name, + gpointer user_data) { + //MyObject *myobj = user_data; + guint registration_id; + + registration_id = g_dbus_connection_register_object(connection, + "/net/connman/Agent", introspection_data->interfaces[0], + &interface_vtable, NULL, NULL, /* user_data_free_func */ + NULL); /* GError** */ + //TODO: make some proper error message rather than exiting + //g_assert(registration_id > 0); + + return NULL; +} + +void* register_agent(void *data) { + + //printf("Loop start\n"); + + guint owner_id; + //MyObject *myobj; + + introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); + g_assert(introspection_data != NULL); + + //myobj = g_object_new(my_object_get_type(), NULL); + +// owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.agent", +// G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, +// on_name_lost, myobj, +// NULL); + +//FIXME: ALLOW_REPLACEMENT for now, make proper deinitialization + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, AGENT_SERVICE, + G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, NULL, NULL, NULL, + NULL); + //G_BUS_NAME_OWNER_FLAGS_NONE G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT + + loop = g_main_loop_new(NULL, FALSE); + + //sleep(10); + g_main_loop_run(loop); + + printf("Loop running\n"); + + g_bus_unown_name(owner_id); + + g_dbus_node_info_unref(introspection_data); + + //g_object_unref(myobj); + + //printf("Loop end\n"); + + return NULL; + +} + +GError* create_agent(GDBusConnection *connection) { + + int err = -1; + pthread_t tid[1]; + + //struct callbackData *threadData; + + err = pthread_create((&tid[0]), NULL, register_agent, NULL); + + if (err != 0) { + printf("\ncan't create thread :[%d]", err); + printf("Fatal error!\n\n"); + return NULL; + } + + GVariant *message = NULL; + GError *error = NULL; + + GVariant *params = NULL; + + char *agent_path = AGENT_PATH; + + params = g_variant_new("(o)", agent_path); + + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "RegisterAgent", params, + NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (error) { + printf("error: %d:%s\n", error->code, error->message); + + return error; + + } else { + printf("Agent registered\n"); + return NULL; + } + +} + +GError* stop_agent(GDBusConnection *connection) { + + GVariant *message = NULL; + GError *error = NULL; + + + GVariant *params = NULL; + + char *agent_path = AGENT_PATH; + + + params = g_variant_new("(o)", agent_path); + + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "UnregisterAgent", params, + NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + if (error) { + printf("error: %d:%s\n", error->code, error->message); + return error; + + } else { + printf("Agent unregistered\n"); + return NULL; + } + +} + +void register_callback(callback callback_function) { + + password_callback = callback_function; + +} + diff --git a/binding-wifi/binding-wifi.pro b/binding-wifi/binding-wifi.pro new file mode 100644 index 0000000..09c54b4 --- /dev/null +++ b/binding-wifi/binding-wifi.pro @@ -0,0 +1,11 @@ +TARGET = serttings-wifi-binding + +HEADERS = wifi-api.h wifi-connman.h +SOURCES = agent.c wifi-api.c wifi-connman.c + +LIBS += -Wl,--version-script=$$PWD/export.map + +CONFIG += link_pkgconfig +PKGCONFIG += json-c afb-daemon glib-2.0 gio-2.0 gobject-2.0 zlib + +include(binding.pri) diff --git a/binding-wifi/binding.pri b/binding-wifi/binding.pri new file mode 100644 index 0000000..3448a56 --- /dev/null +++ b/binding-wifi/binding.pri @@ -0,0 +1,6 @@ +TEMPLATE = lib +CONFIG += plugin use_c_linker +CONFIG -= qt +QMAKE_CFLAGS += -Wextra -Wconversion -Wno-unused-parameter -Werror=maybe-uninitialized -Werror=implicit-function-declaration -ffunction-sections -fdata-sections -Wl,--as-needed -Wl,--gc-sections + +DESTDIR = $${OUT_PWD}/../package/root/lib diff --git a/binding-wifi/export.map b/binding-wifi/export.map new file mode 100644 index 0000000..0ef1ac7 --- /dev/null +++ b/binding-wifi/export.map @@ -0,0 +1 @@ +{ global: afbBindingV1Register; local: *; }; diff --git a/binding-wifi/wifi-api.c b/binding-wifi/wifi-api.c new file mode 100644 index 0000000..2d9748f --- /dev/null +++ b/binding-wifi/wifi-api.c @@ -0,0 +1,489 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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. +*/ + +/** + * file + * + * \brief Implementation of WiFi Binder for AGL's App Framework + * + * \author ALPS Electric + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include "wifi-api.h" +#include "wifi-connman.h" + +/* + * the interface to afb-daemon + */ +const struct afb_binding_interface *afbitf; + +static int need_password_flag = 0; +static int password_not_correct_flag = 0; + +char *passkey; +callback ptr_my_callback; + +GSList *wifi_list = NULL; + +/** + * \brief Read out the passkey from the use and pass it to Agent + * + * \todo Since I do not know how to subscribe for the events from framework, + * it is necessary first to register the password http://IP_ADDRESS:PORT/api/wifi-manager/security?passkey=mypassword. + * Then this function is called automatically. + * + * + * */ +void passkey_inserted(void) { + + printf("Passkey inserted: %s\n", passkey); + + if (passkey != NULL) { + + registerPasskey(passkey); + } else { + printf("Please enter the password first\n"); + + } +} + +/** + * \brief Notify user that password is necessary + * + * This function is called from the registered agent on RequestInput() call. + * \todo Subscribe for this event from GUI. + * + * */ +void ask_for_passkey(int password_rejected_flag) { + //TODO: show network we are asking password for + printf("Insert passkey.\n"); + + if (!password_rejected_flag) { + need_password_flag = 1; + password_not_correct_flag = 0; + //sleep(1); + passkey_inserted(); + + } + + else if (password_rejected_flag) { + need_password_flag = 1; + printf("Password not correct!\n"); + + } + +} + +/** + * \brief Insert passkey that will be used for connections to secured AP. + * + * \TODO Only temporary, user should enter the password on ask_for_passkey() callback + * + * */ +void wifi_insertpasskey(struct afb_req request) { + + const char *passkey_from_user; + + /* retrieves the argument, expects password string */ + passkey_from_user = afb_req_value(request, "passkey"); + + if (passkey_from_user == NULL) { + //TODO:better error message + afb_req_fail(request, "failed", "specify a security key"); + + } else { + + passkey = g_try_malloc0(256); + strcpy(passkey, passkey_from_user); + printf("Passkey is %s\n", passkey); + + } + + afb_req_success(request, NULL, NULL); +} + +/** + * \brief initialize the binder and activates the WiFi HW, should be called first + * + * This will fail if + * - agent for handling password requests cannot be registered + * - some error is returned from connman + * + * + * \return result of the request, either "success" or "failed" with description + */ +static void wifi_activate(struct afb_req request) /*AFB_SESSION_CHECK*/ +{ + json_object *jresp; + GError *error = NULL; + + if (ptr_my_callback == NULL) { + + printf("Registering callback\n"); + + ptr_my_callback = ask_for_passkey; + register_callback(ptr_my_callback); + + } + + jresp = json_object_new_object(); + json_object_object_add(jresp, "activation", json_object_new_string("on")); + + error = do_wifiActivate(); + + if (error == NULL) { + + afb_req_success(request, jresp, "Wi-Fi - Activated"); + + } else + + afb_req_fail(request, "failed", error->message); + +} + +/** + * \brief deinitialize the binder and activates the WiFi HW + * + * This will fail if + * - agent for handling password requests cannot be unregistered + * - some error is returned from connman + * + * + * \return result of the request, either "success" or "failed" with description + */ +static void wifi_deactivate(struct afb_req request) /*AFB_SESSION_CHECK*/ +{ + + json_object *jresp; + GError *error = NULL; + + ptr_my_callback = NULL; + + jresp = json_object_new_object(); + json_object_object_add(jresp, "deactivation", json_object_new_string("on")); + + error = do_wifiDeactivate(); + + if (error == NULL) { + + afb_req_success(request, jresp, "Wi-Fi - Activated"); + + } else + + afb_req_fail(request, "failed", error->message); +} + +/** + * \brief starts scan + * + * \return result of the request, either "success" or "failed" with description + */ +void wifi_scan(struct afb_req request) /*AFB_SESSION_NONE*/ +{ + GError *error = NULL; + + error = do_wifiScan(); + + if (error == NULL) { + + afb_req_success(request, NULL, "Wi-Fi - Scan success"); + + } else + + afb_req_fail(request, "failed", error->message); + +} + +/** + * \brief return network list + * + * + * \return result of the request, either "success" or "failed" with description + */ +void wifi_scanResult(struct afb_req request) /*AFB_SESSION_CHECK*/ +{ + struct wifi_profile_info *wifiProfile = NULL; + GSList *list = NULL; + GSList *holdMe = NULL; + wifi_list = NULL; + char *essid = NULL; + char *address = NULL; + char *security = NULL; + char *state = NULL; + int strength = 0; + int number = 0; + GError *error = NULL; + + error = do_displayScan(&wifi_list); /*Get wifi scan list*/ + if (error == NULL) { + json_object *my_array = json_object_new_array(); + + for (list = wifi_list; list; list = list->next) { /*extract wifi scan result*/ + wifiProfile = (struct wifi_profile_info *) list->data; + security = wifiProfile->Security.sec_type; + strength = wifiProfile->Strength; + //if (essid == NULL || security == NULL) + // continue; + + essid = wifiProfile->ESSID == NULL ? + "HiddenSSID" : wifiProfile->ESSID; + address = + wifiProfile->wifiNetwork.IPaddress == NULL ? + "unsigned" : wifiProfile->wifiNetwork.IPaddress; + state = wifiProfile->state; + //TODO: is there a case when security is NULL? + + json_object *int1 = json_object_new_int(number); + json_object *int2 = json_object_new_int(strength); + json_object *jstring1 = json_object_new_string(essid); + json_object *jstring2 = json_object_new_string(security); + json_object *jstring3 = json_object_new_string(address); + json_object *jstring4 = json_object_new_string(state); + + json_object *jresp = json_object_new_object(); + json_object_object_add(jresp, "Number", int1); + json_object_object_add(jresp, "Strength", int2); + json_object_object_add(jresp, "ESSID", jstring1); + json_object_object_add(jresp, "Security", jstring2); + json_object_object_add(jresp, "IPAddress", jstring3); + json_object_object_add(jresp, "State", jstring4); + + printf("The object json: %s\n", json_object_to_json_string(jresp)); + /*input each scan result into my_array*/ + json_object_array_add(my_array, jresp); + number += 1; + } + while (list != NULL) { + printf("Should be freed"); + holdMe = list->next; + g_free(list); + list = holdMe; + } + afb_req_success(request, my_array, "Wi-Fi - Scan Result is Displayed"); + } else + afb_req_fail(request, "failed", error->message); +} + +/** + * \brief connects to network + * + * \param[in] request number of network to connect to + * + * specify number of network to connect to obtained by scan_result() like this, + * http://IP_ADDRESS:PORT/api/wifi-manager/connect?network=1 + */ +void wifi_connect(struct afb_req request) { + + struct wifi_profile_info *wifiProfileToConnect = NULL; + + const char *network; + int network_index = 0; + GError *error = NULL; + GSList *item = NULL; + + /* retrieves the argument, expects the network number */ + network = afb_req_value(request, "network"); + + if (network == NULL) + //TODO:better error message + afb_req_fail(request, "failed", + "specify a network number to connect to"); + + else { + network_index = atoi(network); + printf("Joining network number %d\n", network_index); + + } + + //get information about desired network + item = g_slist_nth_data(wifi_list, network_index); + + if (item == NULL) { + //Index starts from 1 + printf("Network with number %d not found.\n", network_index + 1); + //TODO:better error message + afb_req_fail(request, "failed", "bad arguments"); + } + + else { + wifiProfileToConnect = (struct wifi_profile_info *) item; + printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID, + wifiProfileToConnect->Strength, + wifiProfileToConnect->NetworkPath); + //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath); + } + error = do_connectNetwork(wifiProfileToConnect->NetworkPath); + + if (error == NULL) + afb_req_success(request, NULL, NULL); + + else if (password_not_correct_flag) { + need_password_flag = 0; + password_not_correct_flag = 0; + afb_req_fail(request, "password-incorrect", NULL); + } else if (need_password_flag) { + need_password_flag = 0; + afb_req_fail(request, "need-password", NULL); + + } else + afb_req_fail(request, "failed", error->message); +} + +/** + * \brief disconnect from network + * + * \param[in] request number of network to disconnect from + * + * specify number of network to disconnect from obtained by scan_result() like this, + * http://IP_ADDRESS:PORT/api/wifi-manager/discnnect?network=1 + */ +void wifi_disconnect(struct afb_req request) { + + struct wifi_profile_info *wifiProfileToConnect = NULL; + + const char *network; + int network_index = 0; + GError *error = NULL; + GSList *item = NULL; + + /* retrieves the argument, expects the network number */ + network = afb_req_value(request, "network"); + + if (network == NULL) + //TODO:better error message + afb_req_fail(request, "failed", + "specify a network number to disconnect from"); + + else { + network_index = atoi(network); + printf("Joining network number %d\n", network_index); + + } + + //get information about desired network + item = g_slist_nth_data(wifi_list, network_index); + + if (item == NULL) { + //Index starts from 1 + printf("Network with number %d not found.\n", network_index + 1); + //TODO:better error message + afb_req_fail(request, "failed", "bad arguments"); + } + + else { + wifiProfileToConnect = (struct wifi_profile_info *) item; + printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID, + wifiProfileToConnect->Strength, + wifiProfileToConnect->NetworkPath); + //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath); + } + error = do_disconnectNetwork(wifiProfileToConnect->NetworkPath); + + if (error == NULL) + afb_req_success(request, NULL, NULL); + else + afb_req_fail(request, "failed", error->message); +} + +/** + * \brief return current status of connection + * + * \return result of the request, either "success" or "failed" with description + */ +void wifi_status(struct afb_req request) { + int error = 0; + wifi_list = NULL; + struct wifiStatus *status; + json_object *jresp = json_object_new_object(); + + status = g_try_malloc0(sizeof(struct wifiStatus)); + error = wifi_state(status); /*get current status of power and connection*/ + if (!error) { + if (status->state == 0) {/*Wi-Fi is OFF*/ + json_object_object_add(jresp, "Power", + json_object_new_string("OFF")); + //json_object_object_add(jresp, "Connection", json_object_new_string("Disconnected")); + printf("Wi-Fi OFF\n"); + } else {/*Wi-Fi is ON*/ + json_object_object_add(jresp, "Power", + json_object_new_string("ON")); + if (status->connected == 0) {/*disconnected*/ + json_object_object_add(jresp, "Connection", + json_object_new_string("Disconnected")); + printf("Wi-Fi ON - Disconnected \n"); + } else {/*Connected*/ + json_object_object_add(jresp, "Connection", + json_object_new_string("Connected")); + printf("Wi-Fi ON - Connected \n"); + } + } + afb_req_success(request, jresp, "Wi-Fi - Connection Status Checked"); + } else { + afb_req_fail(request, "failed", "Wi-Fi - Connection Status unknown"); + } +} + +void wifi_reconnect() { + /*TBD*/ +} + + + +/* + * array of the verbs exported to afb-daemon + */ +static const struct afb_verb_desc_v1 binding_verbs[] = { +/* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ +{ .name = "activate", .session = AFB_SESSION_NONE, .callback = wifi_activate, .info = "Activate Wi-Fi" }, +{ .name = "deactivate", .session = AFB_SESSION_NONE, .callback = wifi_deactivate, .info ="Deactivate Wi-Fi" }, +{ .name = "scan", .session = AFB_SESSION_NONE, .callback = wifi_scan, .info = "Scanning Wi-Fi" }, +{ .name = "scan_result",.session = AFB_SESSION_NONE, .callback = wifi_scanResult, .info = "Get scan result Wi-Fi" }, +{ .name = "connect", .session = AFB_SESSION_NONE, .callback = wifi_connect, .info ="Connecting to Access Point" }, +{ .name = "status", .session = AFB_SESSION_NONE, .callback = wifi_status, .info ="Check connection status" }, +{ .name = "disconnect", .session = AFB_SESSION_NONE, .callback = wifi_disconnect, .info ="Disconnecting connection" }, +{ .name = "reconnect", .session = AFB_SESSION_NONE, .callback = wifi_reconnect, .info ="Reconnecting to Access Point" }, +{ .name = "security", .session = AFB_SESSION_NONE, .callback = wifi_insertpasskey, .info ="Insert passkey" }, + +{ .name = NULL } /* marker for end of the array */ +}; + +/* + * description of the binding for afb-daemon + */ +static const struct afb_binding binding_description = { +/* description conforms to VERSION 1 */ +.type = AFB_BINDING_VERSION_1, .v1 = { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */ +.prefix = "wifi-manager", /* the API name (or binding name or prefix) */ +.info = "wifi API", /* short description of of the binding */ +.verbs = binding_verbs /* the array describing the verbs of the API */ +} }; + +/* + * activation function for registering the binding called by afb-daemon + */ +const struct afb_binding *afbBindingV1Register( + const struct afb_binding_interface *itf) { + afbitf = itf; // records the interface for accessing afb-daemon + return &binding_description; // returns the description of the binding +} + diff --git a/binding-wifi/wifi-api.h b/binding-wifi/wifi-api.h new file mode 100644 index 0000000..429211b --- /dev/null +++ b/binding-wifi/wifi-api.h @@ -0,0 +1,38 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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. +*/ + +#ifndef WIFI_API_H +#define WIFI_API_H + +/* global plugin handle, should store everything we may need */ +typedef struct { + int devCount; +} pluginHandleT; + +/* private client context [will be destroyed when client leaves] */ +typedef struct { + unsigned char activate; + unsigned char connected; +} wifiCtxHandleT; + + +struct scan_list_info { + int number; + char *SSID; + char *Security; + int Strength; +}; + +#endif /* AUDIO_API_H */ diff --git a/binding-wifi/wifi-connman.c b/binding-wifi/wifi-connman.c new file mode 100644 index 0000000..74d2be7 --- /dev/null +++ b/binding-wifi/wifi-connman.c @@ -0,0 +1,354 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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 +#include +#include +#include +#include +//#include +#include +#include + +#include "wifi-api.h" +#include "wifi-connman.h" + +static __thread struct security_profile Security = { NULL, NULL, NULL, NULL, 0, + 0 }; + +int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile) { + GVariant *var = NULL; + GVariant *subvar = NULL; + GVariantIter *array; + const gchar *key = NULL; + const gchar *subkey = NULL; + const gchar *value_char = NULL; + GVariantIter *content_sub; + int value_int; + gsize length; + + while (g_variant_iter_loop(content, "{sv}", &key, &var)) { + if (g_strcmp0(key, "Name") == 0) { + value_char = g_variant_get_string(var, &length); + wifiProfile->ESSID = (char *) value_char; + } else if (g_strcmp0(key, "Security") == 0) { + g_variant_get(var, "as", &content_sub); + while (g_variant_iter_loop(content_sub, "s", &value_char)) { + if (g_strcmp0(value_char, "none") == 0) + wifiProfile->Security.sec_type = "Open"; + else if (g_strcmp0(value_char, "wep") == 0) + wifiProfile->Security.sec_type = "WEP"; + else if (g_strcmp0(value_char, "psk") == 0) + wifiProfile->Security.sec_type = "WPA-PSK"; + else if (g_strcmp0(value_char, "ieee8021x") == 0) + wifiProfile->Security.sec_type = "ieee8021x"; + else if (g_strcmp0(value_char, "wpa") == 0) + wifiProfile->Security.sec_type = "WPA-PSK"; + else if (g_strcmp0(value_char, "rsn") == 0) + wifiProfile->Security.sec_type = "WPA2-PSK"; + else if (g_strcmp0(value_char, "wps") == 0) + wifiProfile->Security.wps_support = 1; + else + Security.sec_type = "Open"; + } + } else if (g_strcmp0(key, "Strength") == 0) { + value_int = (unsigned int) g_variant_get_byte(var); + wifiProfile->Strength = value_int; + } else if (g_strcmp0(key, "State") == 0) { + value_char = g_variant_get_string(var, &length); + wifiProfile->state = (char *) value_char; + } else if (g_strcmp0(key, "IPv4") == 0) { + g_variant_get(var, "a{sv}", &array); + while (g_variant_iter_loop(array, "{sv}", &subkey, &subvar)) { + if (g_strcmp0(subkey, "Method") == 0) { + value_char = g_variant_get_string(subvar, &length); + if (g_strcmp0(value_char, "dhcp") == 0) + wifiProfile->wifiNetwork.method = "dhcp"; + else if (g_strcmp0(value_char, "manual") == 0) + wifiProfile->wifiNetwork.method = "manual"; + else if (g_strcmp0(value_char, "fixed") == 0) + wifiProfile->wifiNetwork.method = "fix"; + else if (g_strcmp0(value_char, "off") == 0) + wifiProfile->wifiNetwork.method = "off"; + } else if (g_strcmp0(subkey, "Address") == 0) { + value_char = g_variant_get_string(subvar, &length); + wifiProfile->wifiNetwork.IPaddress = (char *) value_char; + } else if (g_strcmp0(subkey, "Netmask") == 0) { + value_char = g_variant_get_string(subvar, &length); + wifiProfile->wifiNetwork.netmask = (char *) value_char; + } + } + } + } + //printf ("SSID= %s, security= %s, Strength= %d, wps support= %d\n", wifiProfile->ESSID, wifiProfile->Security.sec_type, wifiProfile->Strength, wifiProfile->Security.wps_support); + return 0; +} + +int wifi_state(struct wifiStatus *status) { + GError *error = NULL; + GVariant *message = NULL; + GVariantIter *array; + GDBusConnection *connection; + GVariant *var = NULL; + const gchar *key = NULL; + gboolean value_bool; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + printf("GDBusconnection is NULL"); + return -1; + } + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + CONNMAN_TECHNOLOGY_PATH, CONNMAN_TECHNOLOGY_INTERFACE, "GetProperties", + NULL, NULL, G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + if (message == NULL) { + printf("message is NULL"); + return -1; + } + g_variant_get(message, "(a{sv})", &array); + while (g_variant_iter_loop(array, "{sv}", &key, &var)) { + if (g_strcmp0(key, "Powered") == 0) { + value_bool = g_variant_get_boolean(var); + if (value_bool) + status->state = 1; + else + status->state = 0; + } else if (g_strcmp0(key, "Connected") == 0) { + value_bool = g_variant_get_boolean(var); + if (value_bool) + status->connected = 1; + else + status->connected = 0; + } + } + g_variant_iter_free(array); + g_variant_unref(message); + + return 0; +} + +GError* do_wifiActivate() { + GVariant *params = NULL; + params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(TRUE)); + GDBusConnection *connection; + GError *error = NULL; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + if (connection == NULL) { + printf("GDBusconnection is NULL"); + return error; + } + + //create the agent to handle security + error = create_agent(connection); + + if (error) + //This is fatal error, without agent secured networks can not be handled + return error; + + g_dbus_connection_call(connection, CONNMAN_SERVICE, + CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty", + params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error); + + if (error) { + printf("error: %d:%s\n", error->code, error->message); + + return error; + } + + else { + printf("Power ON succeeded\n"); + return NULL; + } + +} + +GError* do_wifiDeactivate() { + GVariant *params = NULL; + params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(FALSE)); + GDBusConnection *connection; + GError *error = NULL; + + /*connection = gdbus_conn->connection;*/ + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + printf("GDBusconnection is NULL"); + return error; + } + + //create the agent to handle security + error = stop_agent(connection); + + if (error) { + printf("Error while unregistering the agent, ignoring."); + + } + + g_dbus_connection_call(connection, CONNMAN_SERVICE, + CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty", + params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error); + + if (error) { + printf("error: %d:%s\n", error->code, error->message); + + return error; + } + + else { + printf("Power OFF succeeded\n"); + return NULL; + } +} + +GError* do_wifiScan() { + GDBusConnection *connection; + GError *error = NULL; + + /*connection = gdbus_conn->connection;*/ + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + printf("GDBusconnection is NULL"); + return error; + } + + g_dbus_connection_call(connection, CONNMAN_SERVICE, + CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL, + NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, NULL, &error); + if (error) { + printf("error: %d:%s\n", error->code, error->message); + + return error; + } + + else { + printf("Scan succeeded\n"); + return NULL; + } +} + +GError* do_displayScan(GSList **wifi_list) { + GError *error = NULL; + GVariant *message = NULL; + GVariantIter *array; + gchar *object; + GVariantIter *content = NULL; + GDBusConnection *connection; + struct wifi_profile_info *wifiProfile = NULL; + + /*connection = gdbus_conn->connection;*/ + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + printf("GDBusconnection is NULL"); + return error; + } + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "GetServices", NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + if (message == NULL) { + printf("message is NULL"); + return error; + } + g_variant_get(message, "(a(oa{sv}))", &array); + while (g_variant_iter_loop(array, "(oa{sv})", &object, &content)) { + if (g_str_has_prefix(object, + CONNMAN_WIFI_SERVICE_PROFILE_PREFIX) == TRUE) { + wifiProfile = g_try_malloc0(sizeof(struct wifi_profile_info)); + + extract_values(content, wifiProfile); + wifiProfile->NetworkPath = g_try_malloc0(strlen(object)); + strcpy(wifiProfile->NetworkPath, object); + printf( + "SSID= %s, security= %s, path= %s, Strength= %d, wps support= %d\n", + wifiProfile->ESSID, wifiProfile->Security.sec_type, + wifiProfile->NetworkPath, wifiProfile->Strength, + wifiProfile->Security.wps_support); + printf("method= %s, ip address= %s, netmask= %s\n", + wifiProfile->wifiNetwork.method, + wifiProfile->wifiNetwork.IPaddress, + wifiProfile->wifiNetwork.netmask); + *wifi_list = g_slist_append(*wifi_list, + (struct wifi_profile_info *) wifiProfile); + } + } + g_variant_iter_free(array); + + return NULL; +} + +GError* do_connectNetwork(gchar *networkPath) { + + printf("Connecting to: %s\n", networkPath); + + GVariant *message = NULL; + GError *error = NULL; + GDBusConnection *connection; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + networkPath, CONNMAN_SERVICE_INTERFACE, "Connect", NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT_SHORT, NULL, &error); + + //printf("message error %s\n", message); + //TODO: do we need retunrn value in message + + if (error) { + printf("do_connectNetwork error: %s\n", error->message); + return error; + } else { + printf("Connection succeeded\n"); + return NULL; + } + +} + +GError* do_disconnectNetwork(gchar *networkPath) { + + printf("Connecting to: %s\n", networkPath); + + GVariant *message = NULL; + GError *error = NULL; + GDBusConnection *connection; + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + + message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE, + networkPath, CONNMAN_SERVICE_INTERFACE, "Disconnect", NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, NULL, &error); + + //TODO: do we need return value in message + + if (error) { + printf("error: %s\n", error->message); + return error; + } else { + printf("Disconnected\n"); + return NULL; + } + +} + +void registerPasskey(gchar *passkey) { + + printf("Passkey: %s\n", passkey); + sendPasskey(passkey); + +} + diff --git a/binding-wifi/wifi-connman.h b/binding-wifi/wifi-connman.h new file mode 100644 index 0000000..bd83821 --- /dev/null +++ b/binding-wifi/wifi-connman.h @@ -0,0 +1,126 @@ +/* Copyright 2016 ALPS ELECTRIC CO., LTD. +* +* 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 +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Maximum Profile Count */ +#define CONNMAN_MAX_BUFLEN 512 + +#define CONNMAN_STATE_STRLEN 16 + +#define CONNMAN_SERVICE "net.connman" +#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager" +#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology" +#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service" +#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile" +#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter" +#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error" +#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent" + +#define CONNMAN_MANAGER_PATH "/" +#define CONNMAN_PATH "/net/connman" +#define CONNMAN_TECHNOLOGY_PATH "/net/connman/technology/wifi" + +/** ConnMan technology and profile prefixes for ConnMan 0.78 */ + +#define CONNMAN_WIFI_TECHNOLOGY_PREFIX CONNMAN_PATH "/technology/wifi" +#define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/wifi_" + +#define WIFI_ESSID_LEN 128 +#define WIFI_MAX_WPSPIN_LEN 8 +#define WIFI_BSSID_LEN 17 +#define WIFI_MAX_PSK_PASSPHRASE_LEN 65 +#define WIFI_MAX_WEP_KEY_LEN 26 + +#define AGENT_PATH "/net/connman/Agent" +#define AGENT_SERVICE "org.agent" + +#define DBUS_REPLY_TIMEOUT (120 * 1000) +#define DBUS_REPLY_TIMEOUT_SHORT (10 * 1000) + + +struct gdbus_connection_data_s{ + GDBusConnection *connection; + int conn_ref_count; + GCancellable *cancellable; + void *handle_libnetwork; +}; + + +struct wifiStatus { + unsigned int state; + unsigned int connected; +}; + +struct security_profile{ + char *sec_type; + char *enc_type; + char *wepKey; + char *pskKey; + unsigned int PassphraseRequired; + unsigned int wps_support; +}; + +struct wifi_net{ + char *method; + char *IPaddress; + char *netmask; +}; + +struct wifi_profile_info{ + char *ESSID; + char *NetworkPath; + char *state; + unsigned int Strength; + struct security_profile Security; + struct wifi_net wifiNetwork; +}; + +//typedef void(*callback)(void); +typedef void(*callback)(int password_rejected_flag); +void register_callback(callback ptr); + + +int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile); +int wifi_state(struct wifiStatus *status); +GError* do_wifiActivate(); +GError* do_wifiDeactivate(); +GError* do_wifiScan(); +GError* do_displayScan(GSList **wifi_list); +GError* do_connectNetwork(gchar *object); +GError* do_disconnectNetwork(gchar *object); + +GError* create_agent(GDBusConnection *connection); +GError* stop_agent(GDBusConnection *connection); + + +void registerPasskey(gchar *object); +GError* sendPasskey(gchar *object); + +GError* do_initialize(); +GError* do_initialize(); + + + + + diff --git a/package/config.xml b/package/config.xml new file mode 100644 index 0000000..fa31f2a --- /dev/null +++ b/package/config.xml @@ -0,0 +1,11 @@ + + + Settings + + + This is the settings application for date & time, wifi and bluetooth + Tasuku Suzuki <tasuku.suzuki@qt.io> + APL 2.0 + + + diff --git a/package/icon.svg b/package/icon.svg new file mode 100644 index 0000000..6628784 --- /dev/null +++ b/package/icon.svg @@ -0,0 +1,283 @@ + + + +image/svg+xmlSETTINGS + \ No newline at end of file diff --git a/package/package.pro b/package/package.pro new file mode 100644 index 0000000..125a378 --- /dev/null +++ b/package/package.pro @@ -0,0 +1,21 @@ + +DISTFILES = icon.svg config.xml + +!equals($$_PRO_FILE_PWD_, $$OUT_PWD) { + copy_icon.target = $$OUT_PWD/root/icon.svg + copy_icon.depends = $$_PRO_FILE_PWD_/icon.svg + copy_icon.commands = $(COPY_FILE) \"$$replace(copy_icon.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_icon.target, /, $$QMAKE_DIR_SEP)\" + QMAKE_EXTRA_TARGETS += copy_icon + PRE_TARGETDEPS += $$copy_icon.target + + copy_config.target = $$OUT_PWD/root/config.xml + copy_config.depends = $$_PRO_FILE_PWD_/config.xml + copy_config.commands = $(COPY_FILE) \"$$replace(copy_config.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_config.target, /, $$QMAKE_DIR_SEP)\" + QMAKE_EXTRA_TARGETS += copy_config + PRE_TARGETDEPS += $$copy_config.target +} + +wgt.target = package +wgt.commands = wgtpkg-pack -f -o settings.wgt root + +QMAKE_EXTRA_TARGETS += wgt diff --git a/settings.pro b/settings.pro new file mode 100644 index 0000000..b04be4a --- /dev/null +++ b/settings.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = app binding-wifi binding-bluetooth package +package.depends += app binding-wifi binding-bluetooth -- cgit 1.2.3-korg