merge the Settings in CES2017 and bindings from ALPS 91/7591/2
authorTasuku Suzuki <tasuku.suzuki@qt.io>
Wed, 14 Dec 2016 09:10:54 +0000 (18:10 +0900)
committerTasuku Suzuki <tasuku.suzuki@qt.io>
Wed, 14 Dec 2016 14:23:02 +0000 (23:23 +0900)
Change-Id: I00a7a6c5dae1cd579f91d543b0f5fba4616a633b
Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
66 files changed:
app/SettingPage.qml [new file with mode: 0644]
app/Settings.qml [new file with mode: 0644]
app/SettingsLauncher.qml [new file with mode: 0644]
app/api/Binding.qml [new file with mode: 0644]
app/api/MessageId.js [new file with mode: 0644]
app/app.pri [new file with mode: 0644]
app/app.pro [new file with mode: 0644]
app/bluetooth/Bluetooth.qml [new file with mode: 0644]
app/bluetooth/bluetooth.qrc [new file with mode: 0644]
app/bluetooth/images/HMI_Pair_Button.svg [new file with mode: 0644]
app/bluetooth/images/HMI_Paired_Button.svg [new file with mode: 0644]
app/bluetooth/images/HMI_Settings_BluetoothIcon.svg [new file with mode: 0644]
app/config.tests/libhomescreen/.qmake.stash [new file with mode: 0644]
app/config.tests/libhomescreen/libhomescreen.cpp [new file with mode: 0644]
app/config.tests/libhomescreen/libhomescreen.pro [new file with mode: 0644]
app/datetime/DateEdit.qml [new file with mode: 0644]
app/datetime/DateTime.qml [new file with mode: 0644]
app/datetime/EditSeparator.qml [new file with mode: 0644]
app/datetime/TimeEdit.qml [new file with mode: 0644]
app/datetime/datetime.qrc [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeDate_Arrow_DividingLine.svg [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeDate_Arrow_Down.svg [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeDate_Arrow_Up.svg [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeDate_Button_Cancel.svg [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeDate_Button_Set.svg [new file with mode: 0644]
app/datetime/images/HMI_Settings_TimeIcon.svg [new file with mode: 0644]
app/example/Example.qml [new file with mode: 0644]
app/example/example.qrc [new file with mode: 0644]
app/example/images/HMI_Settings_Example.svg [new file with mode: 0644]
app/images/HMI_Settings_DividingLine.svg [new file with mode: 0644]
app/images/HMI_Settings_X.svg [new file with mode: 0644]
app/images/images.qrc [new file with mode: 0644]
app/main.cpp [new file with mode: 0644]
app/settings.qrc [new file with mode: 0644]
app/wifi/Wifi.qml [new file with mode: 0644]
app/wifi/images/HMI_Settings_WifiIcon.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_1Bar.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_2Bars.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_3Bars.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Full.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Locked_1Bar.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Locked_2Bars.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Locked_3Bars.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Locked_Full.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_Locked_NoBars.svg [new file with mode: 0644]
app/wifi/images/HMI_Settings_Wifi_NoBars.svg [new file with mode: 0644]
app/wifi/wifi.qrc [new file with mode: 0644]
binding-bluetooth/binding-bluetooth.pro [new file with mode: 0644]
binding-bluetooth/binding.pri [new file with mode: 0644]
binding-bluetooth/bluetooth-api.c [new file with mode: 0644]
binding-bluetooth/bluetooth-api.h [new file with mode: 0644]
binding-bluetooth/bluetooth-manager.c [new file with mode: 0644]
binding-bluetooth/bluetooth-manager.h [new file with mode: 0644]
binding-bluetooth/export.map [new file with mode: 0644]
binding-wifi/agent.c [new file with mode: 0644]
binding-wifi/binding-wifi.pro [new file with mode: 0644]
binding-wifi/binding.pri [new file with mode: 0644]
binding-wifi/export.map [new file with mode: 0644]
binding-wifi/wifi-api.c [new file with mode: 0644]
binding-wifi/wifi-api.h [new file with mode: 0644]
binding-wifi/wifi-connman.c [new file with mode: 0644]
binding-wifi/wifi-connman.h [new file with mode: 0644]
package/config.xml [new file with mode: 0644]
package/icon.svg [new file with mode: 0644]
package/package.pro [new file with mode: 0644]
settings.pro [new file with mode: 0644]

diff --git a/app/SettingPage.qml b/app/SettingPage.qml
new file mode 100644 (file)
index 0000000..10aea21
--- /dev/null
@@ -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 (file)
index 0000000..42fed66
--- /dev/null
@@ -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 (file)
index 0000000..c627324
--- /dev/null
@@ -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 (file)
index 0000000..834bdf8
--- /dev/null
@@ -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 (file)
index 0000000..001ea93
--- /dev/null
@@ -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 (file)
index 0000000..014646f
--- /dev/null
@@ -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 (file)
index 0000000..b35e40e
--- /dev/null
@@ -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 (file)
index 0000000..ded2c36
--- /dev/null
@@ -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 (file)
index 0000000..bc8b70a
--- /dev/null
@@ -0,0 +1,8 @@
+<RCC>
+    <qresource prefix="/bluetooth">
+        <file>Bluetooth.qml</file>
+        <file>images/HMI_Pair_Button.svg</file>
+        <file>images/HMI_Paired_Button.svg</file>
+        <file>images/HMI_Settings_BluetoothIcon.svg</file>
+    </qresource>
+</RCC>
diff --git a/app/bluetooth/images/HMI_Pair_Button.svg b/app/bluetooth/images/HMI_Pair_Button.svg
new file mode 100644 (file)
index 0000000..930a75b
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 151 51"
+   style="enable-background:new 0 0 151 51;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Pair_Button.svg"><metadata
+     id="metadata33"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs31" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview29"
+     showgrid="false"
+     inkscape:zoom="4.4503311"
+     inkscape:cx="-17.97619"
+     inkscape:cy="25.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:none;stroke:url(#SVGID_1_);stroke-miterlimit:10;}
+       .st1{opacity:0.3;fill:url(#SVGID_2_);}
+       .st2{fill:#FFFFFF;}
+       .st3{font-family:'Roboto-Regular';}
+       .st4{font-size:19.7348px;}
+       .st5{letter-spacing:3;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><linearGradient
+           id="SVGID_1_"
+           gradientUnits="userSpaceOnUse"
+           x1="24.7258"
+           y1="75.9063"
+           x2="126.2742"
+           y2="-24.9063"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop12" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop14" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st0"
+           width="150"
+           height="50"
+           id="rect16" /><linearGradient
+           id="SVGID_2_"
+           gradientUnits="userSpaceOnUse"
+           x1="-25.8746"
+           y1="126.14"
+           x2="190.2191"
+           y2="-88.3878"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop19" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop21" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st1"
+           width="150"
+           height="50"
+           id="rect23" /><g
+           id="g25"><text
+             transform="matrix(1 0 0 1 46.5699 33.9046)"
+             class="st2 st3 st4 st5"
+             id="text27">Pair</text>
+</g></g></g></switch></svg>
\ 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 (file)
index 0000000..17419d4
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 151 51"
+   style="enable-background:new 0 0 151 51;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Paired_Button.svg"><metadata
+     id="metadata33"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs31" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview29"
+     showgrid="false"
+     inkscape:zoom="4.4503311"
+     inkscape:cx="-11.909226"
+     inkscape:cy="25.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:none;stroke:url(#SVGID_1_);stroke-miterlimit:10;}
+       .st1{opacity:0.84;fill:url(#SVGID_2_);}
+       .st2{fill:#27232B;}
+       .st3{font-family:'Roboto-Regular';}
+       .st4{font-size:19.7348px;}
+       .st5{letter-spacing:2.9;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><linearGradient
+           id="SVGID_1_"
+           gradientUnits="userSpaceOnUse"
+           x1="24.7258"
+           y1="75.9063"
+           x2="126.2742"
+           y2="-24.9063"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop12" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop14" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st0"
+           width="150"
+           height="50"
+           id="rect16" /><linearGradient
+           id="SVGID_2_"
+           gradientUnits="userSpaceOnUse"
+           x1="-25.8746"
+           y1="126.14"
+           x2="190.2191"
+           y2="-88.3878"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop19" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop21" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st1"
+           width="150"
+           height="50"
+           id="rect23" /><g
+           id="g25"><text
+             transform="matrix(1.0253 0 0 1 33.1099 33.9038)"
+             class="st2 st3 st4 st5"
+             id="text27">PairED</text>
+</g></g></g></switch></svg>
\ 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 (file)
index 0000000..d41de2a
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 100"
+   style="enable-background:new 0 0 100 100;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_BluetoothIcon.svg"><metadata
+     id="metadata16"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs14" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview12"
+     showgrid="false"
+     inkscape:zoom="2.36"
+     inkscape:cx="-130.29661"
+     inkscape:cy="50"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="Bluetooth_Icon"><path
+           class="st0"
+           d="M48.3,86.9V53.4L30.9,69.7l-1.4-1.5l18.8-17.6v-0.2L27.9,36.4l1.1-1.6L48.3,48v-35l23.6,18.2l-20.3,19     l20.5,14.1L48.3,86.9z M50.3,51.8v30.5l18.6-17.6L50.3,51.8z M50.3,17.1v31.6l18.5-17.3L50.3,17.1z"
+           id="path10" /></g></g></switch></svg>
\ 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 (file)
index 0000000..d1c4687
--- /dev/null
@@ -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 (file)
index 0000000..d698b05
--- /dev/null
@@ -0,0 +1,8 @@
+#include <libhomescreen.hpp>
+
+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 (file)
index 0000000..eb4e8f3
--- /dev/null
@@ -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 (file)
index 0000000..f9f75fd
--- /dev/null
@@ -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 (file)
index 0000000..5030b1e
--- /dev/null
@@ -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 (file)
index 0000000..e833b52
--- /dev/null
@@ -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 (file)
index 0000000..69a049b
--- /dev/null
@@ -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 (file)
index 0000000..c60c626
--- /dev/null
@@ -0,0 +1,14 @@
+<RCC>
+    <qresource prefix="/datetime">
+        <file>DateEdit.qml</file>
+        <file>DateTime.qml</file>
+        <file>TimeEdit.qml</file>
+        <file>EditSeparator.qml</file>
+        <file>images/HMI_Settings_TimeDate_Arrow_DividingLine.svg</file>
+        <file>images/HMI_Settings_TimeDate_Arrow_Down.svg</file>
+        <file>images/HMI_Settings_TimeDate_Arrow_Up.svg</file>
+        <file>images/HMI_Settings_TimeDate_Button_Cancel.svg</file>
+        <file>images/HMI_Settings_TimeDate_Button_Set.svg</file>
+        <file>images/HMI_Settings_TimeIcon.svg</file>
+    </qresource>
+</RCC>
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 (file)
index 0000000..5a7fa7f
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 93 20"
+   style="enable-background:new 0 0 93 20;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeDate_Arrow_DividingLine.svg"><metadata
+     id="metadata15"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs13" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview11"
+     showgrid="false"
+     inkscape:zoom="7.2258065"
+     inkscape:cx="-15.569196"
+     inkscape:cy="10"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:none;stroke:#66FF99;stroke-miterlimit:10;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><line
+         class="st0"
+         x1="0.3"
+         y1="10"
+         x2="92.7"
+         y2="10"
+         id="line9" /></g></switch></svg>
\ 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 (file)
index 0000000..a4fad6b
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 70"
+   style="enable-background:new 0 0 90 70;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeDate_Arrow_Down.svg"><metadata
+     id="metadata18"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs16" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview14"
+     showgrid="false"
+     inkscape:zoom="3.3714286"
+     inkscape:cx="-85.95339"
+     inkscape:cy="35"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#66FF99;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="previous_11_"><g
+           id="g10"><path
+             class="st0"
+             d="M45,46.4L23.9,25.7c0,0,4.2-2.1,4.3-2.1c0,0,16.8,16.5,16.8,16.5c0,0,16.9-16.5,16.9-16.5      c0,0,4.2,2.1,4.2,2.1L45,46.4z"
+             id="path12" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..49b0c88
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 70"
+   style="enable-background:new 0 0 90 70;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeDate_Arrow_Up.svg"><metadata
+     id="metadata18"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs16" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview14"
+     showgrid="false"
+     inkscape:zoom="3.3714286"
+     inkscape:cx="-118.4322"
+     inkscape:cy="35"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#66FF99;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="previous_11_"><g
+           id="g10"><path
+             class="st0"
+             d="M45,23.6L23.9,44.3c0,0,4.2,2.1,4.3,2.1c0,0,16.8-16.5,16.8-16.5c0,0,16.9,16.5,16.9,16.5      c0,0,4.2-2.1,4.2-2.1L45,23.6z"
+             id="path12" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..c04e11e
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 151 51"
+   style="enable-background:new 0 0 151 51;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeDate_Button_Cancel.svg"><metadata
+     id="metadata33"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs31" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview29"
+     showgrid="false"
+     inkscape:zoom="4.4503311"
+     inkscape:cx="-33.143601"
+     inkscape:cy="25.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:none;stroke:url(#SVGID_1_);stroke-miterlimit:10;}
+       .st1{opacity:0.3;fill:url(#SVGID_2_);}
+       .st2{fill:#FFFFFF;}
+       .st3{font-family:'Roboto-Regular';}
+       .st4{font-size:20px;}
+       .st5{letter-spacing:3;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><linearGradient
+           id="SVGID_1_"
+           gradientUnits="userSpaceOnUse"
+           x1="24.7258"
+           y1="75.9063"
+           x2="126.2742"
+           y2="-24.9063"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop12" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop14" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st0"
+           width="150"
+           height="50"
+           id="rect16" /><linearGradient
+           id="SVGID_2_"
+           gradientUnits="userSpaceOnUse"
+           x1="-25.8746"
+           y1="126.14"
+           x2="190.2191"
+           y2="-88.3878"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop19" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop21" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st1"
+           width="150"
+           height="50"
+           id="rect23" /><g
+           id="g25"><text
+             transform="matrix(1 0 0 1 29.5984 34.017)"
+             class="st2 st3 st4 st5"
+             id="text27">CANCEL</text>
+</g></g></g></switch></svg>
\ 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 (file)
index 0000000..4b103cc
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 151 51"
+   style="enable-background:new 0 0 151 51;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeDate_Button_Set.svg"><metadata
+     id="metadata33"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs31" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview29"
+     showgrid="false"
+     inkscape:zoom="4.4503311"
+     inkscape:cx="-24.941964"
+     inkscape:cy="25.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:none;stroke:url(#SVGID_1_);stroke-miterlimit:10;}
+       .st1{opacity:0.84;fill:url(#SVGID_2_);}
+       .st2{fill:#27232B;}
+       .st3{font-family:'Roboto-Regular';}
+       .st4{font-size:20px;}
+       .st5{letter-spacing:3;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><linearGradient
+           id="SVGID_1_"
+           gradientUnits="userSpaceOnUse"
+           x1="24.7258"
+           y1="75.9063"
+           x2="126.2742"
+           y2="-24.9063"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop12" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop14" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st0"
+           width="150"
+           height="50"
+           id="rect16" /><linearGradient
+           id="SVGID_2_"
+           gradientUnits="userSpaceOnUse"
+           x1="-25.8746"
+           y1="126.14"
+           x2="190.2191"
+           y2="-88.3878"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop19" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop21" /></linearGradient><rect
+           x="0.5"
+           y="0.5"
+           class="st1"
+           width="150"
+           height="50"
+           id="rect23" /><g
+           id="g25"><text
+             transform="matrix(1 0 0 1 53.2699 34.0168)"
+             class="st2 st3 st4 st5"
+             id="text27">SET</text>
+</g></g></g></switch></svg>
\ 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 (file)
index 0000000..d4b2ef6
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 100"
+   style="enable-background:new 0 0 100 100;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_TimeIcon.svg"><metadata
+     id="metadata21"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs19" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview17"
+     showgrid="false"
+     inkscape:zoom="2.36"
+     inkscape:cx="-145.55085"
+     inkscape:cy="50"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><g
+           id="g11"><path
+             class="st0"
+             d="M50,81.2c-17.3,0-31.4-14-31.4-31.2c0-1.3,0.1-2.7,0.3-4l1.9,0.2c-0.2,1.3-0.2,2.5-0.2,3.8      c0,16.2,13.2,29.3,29.5,29.3S79.5,66.2,79.5,50c0-16.2-13.2-29.3-29.5-29.3c-7.2,0-14.1,2.6-19.5,7.3l-1.2-1.4      c5.7-5,13.1-7.8,20.7-7.8c17.3,0,31.4,14,31.4,31.2C81.4,67.2,67.3,81.2,50,81.2z"
+             id="path13" /></g><polygon
+           class="st0"
+           points="51,49.8 51,33.7 49,33.7 49,51.7 50,51.7 51,51.7 60,51.7 60,49.8    "
+           id="polygon15" /></g></g></switch></svg>
\ No newline at end of file
diff --git a/app/example/Example.qml b/app/example/Example.qml
new file mode 100644 (file)
index 0000000..18e3efc
--- /dev/null
@@ -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 (file)
index 0000000..5739f8e
--- /dev/null
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/example">
+        <file>Example.qml</file>
+        <file>images/HMI_Settings_Example.svg</file>
+    </qresource>
+</RCC>
diff --git a/app/example/images/HMI_Settings_Example.svg b/app/example/images/HMI_Settings_Example.svg
new file mode 100644 (file)
index 0000000..5ad9479
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;#38;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 45 45"
+   style="enable-background:new 0 0 45 45;"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_ContactScreen_X-01.svg"><metadata
+     id="metadata66"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs64" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview62"
+     showgrid="false"
+     inkscape:zoom="5.2444444"
+     inkscape:cx="-132.61653"
+     inkscape:cy="22.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><style
+     type="text/css"
+     id="style4">
+       .st0{fill:none;stroke:#FFFFFF;stroke-miterlimit:10;}
+       .st1{display:none;}
+       .st2{display:inline;opacity:0.15;fill:url(#SVGID_1_);}
+       .st3{display:inline;opacity:0.35;fill:url(#SVGID_2_);}
+       .st4{display:inline;}
+       .st5{opacity:0.15;fill:url(#SVGID_3_);}
+       .st6{opacity:0.15;fill:url(#SVGID_4_);stroke:url(#SVGID_5_);stroke-miterlimit:10;}
+       .st7{fill:url(#SVGID_6_);}
+</style><switch
+     id="switch6"><g
+       i:extraneous="self"
+       id="g8"><g
+         id="Inactive"><g
+           id="g11"><line
+             class="st0"
+             x1="44.8"
+             y1="44.8"
+             x2="0.2"
+             y2="0.2"
+             id="line13" /><line
+             class="st0"
+             x1="45"
+             y1="0"
+             x2="0"
+             y2="45"
+             id="line15" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..d63589c
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 932.8 1"
+   style="enable-background:new 0 0 932.8 1;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_DividingLine.svg"><metadata
+     id="metadata18"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs16" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview14"
+     showgrid="false"
+     inkscape:zoom="0.72041167"
+     inkscape:cx="-116.6"
+     inkscape:cy="0.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{opacity:0.302;}
+       .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#A8A8A8;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="Divider_2_"
+         class="st0"><g
+           id="g10"><polygon
+             class="st1"
+             points="719.7,0 0,0 0,1 932.8,1     "
+             id="polygon12" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..5ad9479
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;#38;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 45 45"
+   style="enable-background:new 0 0 45 45;"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_ContactScreen_X-01.svg"><metadata
+     id="metadata66"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs64" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview62"
+     showgrid="false"
+     inkscape:zoom="5.2444444"
+     inkscape:cx="-132.61653"
+     inkscape:cy="22.5"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><style
+     type="text/css"
+     id="style4">
+       .st0{fill:none;stroke:#FFFFFF;stroke-miterlimit:10;}
+       .st1{display:none;}
+       .st2{display:inline;opacity:0.15;fill:url(#SVGID_1_);}
+       .st3{display:inline;opacity:0.35;fill:url(#SVGID_2_);}
+       .st4{display:inline;}
+       .st5{opacity:0.15;fill:url(#SVGID_3_);}
+       .st6{opacity:0.15;fill:url(#SVGID_4_);stroke:url(#SVGID_5_);stroke-miterlimit:10;}
+       .st7{fill:url(#SVGID_6_);}
+</style><switch
+     id="switch6"><g
+       i:extraneous="self"
+       id="g8"><g
+         id="Inactive"><g
+           id="g11"><line
+             class="st0"
+             x1="44.8"
+             y1="44.8"
+             x2="0.2"
+             y2="0.2"
+             id="line13" /><line
+             class="st0"
+             x1="45"
+             y1="0"
+             x2="0"
+             y2="45"
+             id="line15" /></g></g></g></switch></svg>
\ No newline at end of file
diff --git a/app/images/images.qrc b/app/images/images.qrc
new file mode 100644 (file)
index 0000000..0bb2c0d
--- /dev/null
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/images">
+        <file>HMI_Settings_DividingLine.svg</file>
+        <file>HMI_Settings_X.svg</file>
+    </qresource>
+</RCC>
diff --git a/app/main.cpp b/app/main.cpp
new file mode 100644 (file)
index 0000000..ff3ca1e
--- /dev/null
@@ -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 <QtCore/QDebug>
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QUrlQuery>
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtQml/QQmlContext>
+#include <QtQuickControls2/QQuickStyle>
+
+#ifdef HAVE_LIBHOMESCREEN
+#include <libhomescreen.hpp>
+#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 (file)
index 0000000..189f441
--- /dev/null
@@ -0,0 +1,7 @@
+<RCC>
+    <qresource prefix="/">
+        <file>Settings.qml</file>
+        <file>SettingsLauncher.qml</file>
+        <file>SettingPage.qml</file>
+    </qresource>
+</RCC>
diff --git a/app/wifi/Wifi.qml b/app/wifi/Wifi.qml
new file mode 100644 (file)
index 0000000..7851967
--- /dev/null
@@ -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 (file)
index 0000000..4314729
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 100 100"
+   style="enable-background:new 0 0 100 100;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_WifiIcon.svg"><metadata
+     id="metadata20"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs18" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview16"
+     showgrid="false"
+     inkscape:zoom="2.36"
+     inkscape:cx="-191.52542"
+     inkscape:cy="50"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="Wifi_Icon"><path
+           class="st0"
+           d="M49.6,32.8c10.8-0.2,21.2,4.3,31,13.4l1.6-1.6C72,35,61,30.2,49.6,30.5c-15.2,0.4-26.9,9.4-31.8,13.9     l1.6,1.6C24.1,41.7,35.4,33.1,49.6,32.8z"
+           id="path10" /><path
+           class="st0"
+           d="M29,55.8l1.6,1.6c2.9-2.7,10.1-8.2,19.1-8.4c6.9-0.2,13.4,2.7,19.6,8.5L71,56c-6.7-6.3-13.9-9.4-21.3-9.2     C39.7,47,32.1,52.9,29,55.8z"
+           id="path12" /><path
+           class="st0"
+           d="M49.8,63.5c-4.7,0.1-8.2,3.3-9,4.2l1.6,1.6c0.7-0.7,3.6-3.4,7.5-3.5c2.6,0,5.3,1.2,7.7,3.7l1.6-1.6     C56.3,64.9,53.2,63.5,49.8,63.5z"
+           id="path14" /></g></g></switch></svg>
\ 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 (file)
index 0000000..e692c69
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 80 80"
+   style="enable-background:new 0 0 80 80;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_1Bar.svg"><metadata
+     id="metadata29"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs27" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview25"
+     showgrid="false"
+     inkscape:zoom="2.95"
+     inkscape:cx="-129.15254"
+     inkscape:cy="40"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="64.2"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st1"
+             d="M7.9,39.8c7.7-8.3,18.9-13.6,31.4-13.6c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8c-9.1-11.2-23.1-18.3-38.9-18.3      C25,19.1,12,25.1,3,34.6L7.9,39.8z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st1"
+             d="M17.1,49.3c5.3-6.2,13.3-10.2,22.2-10.2c9.8,0,18.4,4.8,23.7,12l5.3-4.8c-6.6-8.6-17.1-14.2-29-14.2      c-10.9,0-20.6,4.7-27.2,12L17.1,49.3z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st1"
+             d="M27.1,59.8c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9c-3.8-5.9-10.6-9.8-18.3-9.8      c-7.1,0-13.3,3.3-17.3,8.4L27.1,59.8z"
+             id="path23" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..f7cf642
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 80 80"
+   style="enable-background:new 0 0 80 80;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_2Bars.svg"><metadata
+     id="metadata29"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs27" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview25"
+     showgrid="false"
+     inkscape:zoom="2.95"
+     inkscape:cx="-131.86441"
+     inkscape:cy="40"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="64.2"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st1"
+             d="M7.9,39.8c7.7-8.3,18.9-13.6,31.4-13.6c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8c-9.1-11.2-23.1-18.3-38.9-18.3      C25,19.1,12,25.1,3,34.6L7.9,39.8z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st1"
+             d="M17.1,49.3c5.3-6.2,13.3-10.2,22.2-10.2c9.8,0,18.4,4.8,23.7,12l5.3-4.8c-6.6-8.6-17.1-14.2-29-14.2      c-10.9,0-20.6,4.7-27.2,12L17.1,49.3z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st0"
+             d="M27.1,59.8c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9c-3.8-5.9-10.6-9.8-18.3-9.8      c-7.1,0-13.3,3.3-17.3,8.4L27.1,59.8z"
+             id="path23" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..8a26f3f
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 80 80"
+   style="enable-background:new 0 0 80 80;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_3Bars.svg"><metadata
+     id="metadata29"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs27" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview25"
+     showgrid="false"
+     inkscape:zoom="2.95"
+     inkscape:cx="-135.76271"
+     inkscape:cy="40"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="64.2"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st1"
+             d="M7.9,39.8c7.7-8.3,18.9-13.6,31.4-13.6c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8c-9.1-11.2-23.1-18.3-38.9-18.3      C25,19.1,12,25.1,3,34.6L7.9,39.8z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st0"
+             d="M17.1,49.3c5.3-6.2,13.3-10.2,22.2-10.2c9.8,0,18.4,4.8,23.7,12l5.3-4.8c-6.6-8.6-17.1-14.2-29-14.2      c-10.9,0-20.6,4.7-27.2,12L17.1,49.3z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st0"
+             d="M27.1,59.8c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9c-3.8-5.9-10.6-9.8-18.3-9.8      c-7.1,0-13.3,3.3-17.3,8.4L27.1,59.8z"
+             id="path23" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..9ad1869
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 80 80"
+   style="enable-background:new 0 0 80 80;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Full.svg"><metadata
+     id="metadata29"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs27" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview25"
+     showgrid="false"
+     inkscape:zoom="2.95"
+     inkscape:cx="-164.40678"
+     inkscape:cy="40"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="64.2"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st0"
+             d="M7.9,39.8c7.7-8.3,18.9-13.6,31.4-13.6c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8c-9.1-11.2-23.1-18.3-38.9-18.3      C25,19.1,12,25.1,3,34.6L7.9,39.8z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st0"
+             d="M17.1,49.3c5.3-6.2,13.3-10.2,22.2-10.2c9.8,0,18.4,4.8,23.7,12l5.3-4.8c-6.6-8.6-17.1-14.2-29-14.2      c-10.9,0-20.6,4.7-27.2,12L17.1,49.3z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st0"
+             d="M27.1,59.8c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9c-3.8-5.9-10.6-9.8-18.3-9.8      c-7.1,0-13.3,3.3-17.3,8.4L27.1,59.8z"
+             id="path23" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..5da957f
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 90"
+   style="enable-background:new 0 0 90 90;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Locked_1Bar.svg"><metadata
+     id="metadata35"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs33" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview31"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-164.74576"
+     inkscape:cy="45"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><ellipse
+         class="st0"
+         cx="39.3"
+         cy="69"
+         rx="5.2"
+         ry="5"
+         id="ellipse9" /><g
+         id="g11"><path
+           class="st1"
+           d="M7.9,44.6C15.7,36.3,26.9,31,39.3,31c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8C69.1,31.2,55.1,24,39.3,24     C25,24,12,29.9,3,39.4L7.9,44.6z"
+           id="path13" /></g><g
+         id="g15"><path
+           class="st1"
+           d="M17.1,54.2C22.4,48,30.4,44,39.3,44c9.8,0,18.4,4.8,23.7,12l5.3-4.8C61.8,42.6,51.2,37,39.3,37     c-10.9,0-20.6,4.7-27.2,12L17.1,54.2z"
+           id="path17" /></g><g
+         id="g19"><path
+           class="st1"
+           d="M27.1,64.7c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9C53.8,54.9,47,51,39.3,51     c-7.1,0-13.3,3.3-17.3,8.4L27.1,64.7z"
+           id="path21" /></g><g
+         id="g23"><path
+           class="st0"
+           d="M87.9,74H75.4c-0.7,0-1.2-0.6-1.2-1.2v-6.6h2V72h10.9v-9H75.4c0.1,0,0.1,0,0.2,0h-1.4v-0.7     c0-0.7,0.6-1.2,1.2-1.2h12.4c0.7,0,1.2,0.6,1.2,1.2v10.5C89.1,73.4,88.5,74,87.9,74z"
+           id="path25" /></g><g
+         id="g27"><path
+           class="st0"
+           d="M87.2,60h-2v-3.5c0-1.9-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5V60h-2v-3.5c0-3,2.5-5.5,5.5-5.5s5.5,2.5,5.5,5.5     V60z"
+           id="path29" /></g></g></switch></svg>
\ 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 (file)
index 0000000..7f180aa
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 90"
+   style="enable-background:new 0 0 90 90;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Locked_2Bars.svg"><metadata
+     id="metadata35"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs33" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview31"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-135.38136"
+     inkscape:cy="45"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><ellipse
+         class="st0"
+         cx="39.3"
+         cy="69"
+         rx="5.2"
+         ry="5"
+         id="ellipse9" /><g
+         id="g11"><path
+           class="st1"
+           d="M7.9,44.6C15.7,36.3,26.9,31,39.3,31c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8C69.1,31.2,55.1,24,39.3,24     C25,24,12,29.9,3,39.4L7.9,44.6z"
+           id="path13" /></g><g
+         id="g15"><path
+           class="st1"
+           d="M17.1,54.2C22.4,48,30.4,44,39.3,44c9.8,0,18.4,4.8,23.7,12l5.3-4.8C61.8,42.6,51.2,37,39.3,37     c-10.9,0-20.6,4.7-27.2,12L17.1,54.2z"
+           id="path17" /></g><g
+         id="g19"><path
+           class="st0"
+           d="M27.1,64.7c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9C53.8,54.9,47,51,39.3,51     c-7.1,0-13.3,3.3-17.3,8.4L27.1,64.7z"
+           id="path21" /></g><g
+         id="g23"><path
+           class="st0"
+           d="M87.9,74H75.4c-0.7,0-1.2-0.6-1.2-1.2v-6.6h2V72h10.9v-9H75.4c0.1,0,0.1,0,0.2,0h-1.4v-0.7     c0-0.7,0.6-1.2,1.2-1.2h12.4c0.7,0,1.2,0.6,1.2,1.2v10.5C89.1,73.4,88.5,74,87.9,74z"
+           id="path25" /></g><g
+         id="g27"><path
+           class="st0"
+           d="M87.2,60h-2v-3.5c0-1.9-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5V60h-2v-3.5c0-3,2.5-5.5,5.5-5.5s5.5,2.5,5.5,5.5     V60z"
+           id="path29" /></g></g></switch></svg>
\ 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 (file)
index 0000000..276c758
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 90"
+   style="enable-background:new 0 0 90 90;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Locked_3Bars.svg"><metadata
+     id="metadata35"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs33" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview31"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-125.65678"
+     inkscape:cy="45"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+       .st1{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><ellipse
+         class="st0"
+         cx="39.3"
+         cy="69"
+         rx="5.2"
+         ry="5"
+         id="ellipse9" /><g
+         id="g11"><path
+           class="st1"
+           d="M7.9,44.6C15.7,36.3,26.9,31,39.3,31c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8C69.1,31.2,55.1,24,39.3,24     C25,24,12,29.9,3,39.4L7.9,44.6z"
+           id="path13" /></g><g
+         id="g15"><path
+           class="st0"
+           d="M17.1,54.2C22.4,48,30.4,44,39.3,44c9.8,0,18.4,4.8,23.7,12l5.3-4.8C61.8,42.6,51.2,37,39.3,37     c-10.9,0-20.6,4.7-27.2,12L17.1,54.2z"
+           id="path17" /></g><g
+         id="g19"><path
+           class="st0"
+           d="M27.1,64.7c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9C53.8,54.9,47,51,39.3,51     c-7.1,0-13.3,3.3-17.3,8.4L27.1,64.7z"
+           id="path21" /></g><g
+         id="g23"><path
+           class="st0"
+           d="M87.9,74H75.4c-0.7,0-1.2-0.6-1.2-1.2v-6.6h2V72h10.9v-9H75.4c0.1,0,0.1,0,0.2,0h-1.4v-0.7     c0-0.7,0.6-1.2,1.2-1.2h12.4c0.7,0,1.2,0.6,1.2,1.2v10.5C89.1,73.4,88.5,74,87.9,74z"
+           id="path25" /></g><g
+         id="g27"><path
+           class="st0"
+           d="M87.2,60h-2v-3.5c0-1.9-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5V60h-2v-3.5c0-3,2.5-5.5,5.5-5.5s5.5,2.5,5.5,5.5     V60z"
+           id="path29" /></g></g></switch></svg>
\ 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 (file)
index 0000000..9058511
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 90"
+   style="enable-background:new 0 0 90 90;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Locked_Full.svg"><metadata
+     id="metadata35"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs33" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview31"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-130.80508"
+     inkscape:cy="45"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#FFFFFF;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><ellipse
+         class="st0"
+         cx="39.3"
+         cy="69"
+         rx="5.2"
+         ry="5"
+         id="ellipse9" /><g
+         id="g11"><path
+           class="st0"
+           d="M7.9,44.6C15.7,36.3,26.9,31,39.3,31c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8C69.1,31.2,55.1,24,39.3,24     C25,24,12,29.9,3,39.4L7.9,44.6z"
+           id="path13" /></g><g
+         id="g15"><path
+           class="st0"
+           d="M17.1,54.2C22.4,48,30.4,44,39.3,44c9.8,0,18.4,4.8,23.7,12l5.3-4.8C61.8,42.6,51.2,37,39.3,37     c-10.9,0-20.6,4.7-27.2,12L17.1,54.2z"
+           id="path17" /></g><g
+         id="g19"><path
+           class="st0"
+           d="M27.1,64.7c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9C53.8,54.9,47,51,39.3,51     c-7.1,0-13.3,3.3-17.3,8.4L27.1,64.7z"
+           id="path21" /></g><g
+         id="g23"><path
+           class="st0"
+           d="M87.9,74H75.4c-0.7,0-1.2-0.6-1.2-1.2v-6.6h2V72h10.9v-9H75.4c0.1,0,0.1,0,0.2,0h-1.4v-0.7     c0-0.7,0.6-1.2,1.2-1.2h12.4c0.7,0,1.2,0.6,1.2,1.2v10.5C89.1,73.4,88.5,74,87.9,74z"
+           id="path25" /></g><g
+         id="g27"><path
+           class="st0"
+           d="M87.2,60h-2v-3.5c0-1.9-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5V60h-2v-3.5c0-3,2.5-5.5,5.5-5.5s5.5,2.5,5.5,5.5     V60z"
+           id="path29" /></g></g></switch></svg>
\ 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 (file)
index 0000000..6f389c6
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 90 90"
+   style="enable-background:new 0 0 90 90;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_Locked_NoBars.svg"><metadata
+     id="metadata39"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs37" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview35"
+     showgrid="false"
+     inkscape:zoom="2.6222222"
+     inkscape:cx="-110.21186"
+     inkscape:cy="45"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="69"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st0"
+             d="M7.9,44.6C15.7,36.3,26.9,31,39.3,31c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8C69.1,31.2,55.1,24,39.3,24      C25,24,12,29.9,3,39.4L7.9,44.6z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st0"
+             d="M17.1,54.2C22.4,48,30.4,44,39.3,44c9.8,0,18.4,4.8,23.7,12l5.3-4.8C61.8,42.6,51.2,37,39.3,37      c-10.9,0-20.6,4.7-27.2,12L17.1,54.2z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st0"
+             d="M27.1,64.7c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9C53.8,54.9,47,51,39.3,51      c-7.1,0-13.3,3.3-17.3,8.4L27.1,64.7z"
+             id="path23" /></g></g><g
+         id="g25"><g
+           id="g27"><path
+             class="st0"
+             d="M87.9,74H75.4c-0.7,0-1.2-0.6-1.2-1.2v-6.6h2V72h10.9v-9H75.4c0.1,0,0.1,0,0.2,0h-1.4v-0.7      c0-0.7,0.6-1.2,1.2-1.2h12.4c0.7,0,1.2,0.6,1.2,1.2v10.5C89.1,73.4,88.5,74,87.9,74z"
+             id="path29" /></g><g
+           id="g31"><path
+             class="st0"
+             d="M87.2,60h-2v-3.5c0-1.9-1.6-3.5-3.5-3.5s-3.5,1.6-3.5,3.5V60h-2v-3.5c0-3,2.5-5.5,5.5-5.5s5.5,2.5,5.5,5.5      V60z"
+             id="path33" /></g></g></g></switch></svg>
\ 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 (file)
index 0000000..e23fc1d
--- /dev/null
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 80 80"
+   style="enable-background:new 0 0 80 80;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="HMI_Settings_Wifi_NoBars.svg"><metadata
+     id="metadata29"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs27" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview25"
+     showgrid="false"
+     inkscape:zoom="2.95"
+     inkscape:cx="-152.20339"
+     inkscape:cy="40"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Layer_1" /><style
+     type="text/css"
+     id="style3">
+       .st0{fill:#545157;}
+</style><switch
+     id="switch5"><g
+       i:extraneous="self"
+       id="g7"><g
+         id="g9"><ellipse
+           class="st0"
+           cx="39.3"
+           cy="64.2"
+           rx="5.2"
+           ry="5"
+           id="ellipse11" /><g
+           id="g13"><path
+             class="st0"
+             d="M7.9,39.8c7.7-8.3,18.9-13.6,31.4-13.6c13.7,0,25.8,6.3,33.5,16.1l5.3-4.8c-9.1-11.2-23.1-18.3-38.9-18.3      C25,19.1,12,25.1,3,34.6L7.9,39.8z"
+             id="path15" /></g><g
+           id="g17"><path
+             class="st0"
+             d="M17.1,49.3c5.3-6.2,13.3-10.2,22.2-10.2c9.8,0,18.4,4.8,23.7,12l5.3-4.8c-6.6-8.6-17.1-14.2-29-14.2      c-10.9,0-20.6,4.7-27.2,12L17.1,49.3z"
+             id="path19" /></g><g
+           id="g21"><path
+             class="st0"
+             d="M27.1,59.8c2.6-4,7.1-6.6,12.2-6.6c5.6,0,10.5,3.1,12.9,7.7l5.4-4.9c-3.8-5.9-10.6-9.8-18.3-9.8      c-7.1,0-13.3,3.3-17.3,8.4L27.1,59.8z"
+             id="path23" /></g></g></g></switch></svg>
\ No newline at end of file
diff --git a/app/wifi/wifi.qrc b/app/wifi/wifi.qrc
new file mode 100644 (file)
index 0000000..063088a
--- /dev/null
@@ -0,0 +1,16 @@
+<RCC>
+    <qresource prefix="/wifi">
+        <file>Wifi.qml</file>
+        <file>images/HMI_Settings_Wifi_1Bar.svg</file>
+        <file>images/HMI_Settings_Wifi_2Bars.svg</file>
+        <file>images/HMI_Settings_Wifi_3Bars.svg</file>
+        <file>images/HMI_Settings_Wifi_Full.svg</file>
+        <file>images/HMI_Settings_Wifi_Locked_1Bar.svg</file>
+        <file>images/HMI_Settings_Wifi_Locked_2Bars.svg</file>
+        <file>images/HMI_Settings_Wifi_Locked_3Bars.svg</file>
+        <file>images/HMI_Settings_Wifi_Locked_Full.svg</file>
+        <file>images/HMI_Settings_Wifi_Locked_NoBars.svg</file>
+        <file>images/HMI_Settings_Wifi_NoBars.svg</file>
+        <file>images/HMI_Settings_WifiIcon.svg</file>
+    </qresource>
+</RCC>
diff --git a/binding-bluetooth/binding-bluetooth.pro b/binding-bluetooth/binding-bluetooth.pro
new file mode 100644 (file)
index 0000000..9dba7a1
--- /dev/null
@@ -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 (file)
index 0000000..3448a56
--- /dev/null
@@ -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 (file)
index 0000000..f7e2d9a
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+#include <afb/afb-service-itf.h>
+#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 (file)
index 0000000..8a7e593
--- /dev/null
@@ -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 (file)
index 0000000..4c49196
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#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 <method>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 (file)
index 0000000..cb018b0
--- /dev/null
@@ -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 <glib.h>
+#include <glib-object.h>
+//#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+//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 (file)
index 0000000..0ef1ac7
--- /dev/null
@@ -0,0 +1 @@
+{ global: afbBindingV1Register; local: *; };
diff --git a/binding-wifi/agent.c b/binding-wifi/agent.c
new file mode 100644 (file)
index 0000000..a22dc31
--- /dev/null
@@ -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 <stdio.h>
+#include <errno.h>
+
+#include <gio/gio.h>
+#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[] = "<node>"
+               "  <interface name='net.connman.Agent'>"
+               "    <method name='RequestInput'>"
+               "          <arg type='o' name='service' direction='in'/>"
+               "          <arg type='a{sv}' name='fields' direction='in'/>"
+               "          <arg type='a{sv}' name='fields' direction='out'/>"
+               "    </method>"
+               "    <method name='ReportError'>"
+               "          <arg type='o' name='service' direction='in'/>"
+               "          <arg type='s' name='error' direction='in'/>"
+               "    </method>"
+               "  </interface>"
+               "</node>";
+
+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 (file)
index 0000000..09c54b4
--- /dev/null
@@ -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 (file)
index 0000000..3448a56
--- /dev/null
@@ -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 (file)
index 0000000..0ef1ac7
--- /dev/null
@@ -0,0 +1 @@
+{ global: afbBindingV1Register; local: *; };
diff --git a/binding-wifi/wifi-api.c b/binding-wifi/wifi-api.c
new file mode 100644 (file)
index 0000000..2d9748f
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+
+#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 (file)
index 0000000..429211b
--- /dev/null
@@ -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 (file)
index 0000000..74d2be7
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+//#include <dbus/dbus.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#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 (file)
index 0000000..bd83821
--- /dev/null
@@ -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 <dlog.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#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 (file)
index 0000000..fa31f2a
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" id="settings" version="0.1">
+  <name>Settings</name>
+  <icon src="icon.svg"/>
+  <content src="bin/settings" type="application/vnd.agl.native"/>
+  <description>This is the settings application for date &amp; time, wifi and bluetooth</description>
+  <author>Tasuku Suzuki &lt;tasuku.suzuki@qt.io&gt;</author>
+  <license>APL 2.0</license>
+</widget>
+
+
diff --git a/package/icon.svg b/package/icon.svg
new file mode 100644 (file)
index 0000000..6628784
--- /dev/null
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:i="&amp;ns_ai;"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 320 320"
+   style="enable-background:new 0 0 320 320;"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="icon.svg"><metadata
+     id="metadata1292"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs1290" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="2560"
+     inkscape:window-height="1464"
+     id="namedview1288"
+     showgrid="false"
+     inkscape:zoom="0.7375"
+     inkscape:cx="-697.62712"
+     inkscape:cy="160"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" /><style
+     type="text/css"
+     id="style4">
+       .st0{display:none;}
+       .st1{display:inline;}
+       .st2{opacity:0.4;fill:url(#SVGID_1_);}
+       .st3{fill:url(#SVGID_2_);}
+       .st4{fill:#FFFFFF;}
+       .st5{font-family:'Roboto-Regular';}
+       .st6{font-size:25px;}
+       .st7{letter-spacing:6;}
+       .st8{fill:url(#SVGID_3_);}
+       .st9{fill:url(#SVGID_4_);}
+       .st10{fill:url(#SVGID_5_);}
+       .st11{fill:url(#SVGID_6_);}
+       .st12{fill:url(#SVGID_7_);}
+       .st13{fill:url(#SVGID_8_);}
+       .st14{fill:url(#SVGID_9_);}
+       .st15{fill:url(#SVGID_10_);}
+       .st16{fill:url(#SVGID_11_);}
+       .st17{fill:url(#SVGID_12_);}
+       .st18{fill:url(#SVGID_13_);}
+       .st19{fill:url(#SVGID_14_);}
+       .st20{fill:url(#SVGID_15_);}
+       .st21{fill:url(#SVGID_16_);}
+       .st22{fill:url(#SVGID_17_);}
+       .st23{fill:url(#SVGID_18_);}
+       .st24{opacity:0.29;}
+       .st25{fill:url(#SVGID_19_);}
+       .st26{fill:url(#SVGID_20_);}
+       .st27{fill:url(#SVGID_21_);}
+       .st28{fill:url(#SVGID_22_);}
+       .st29{fill:url(#SVGID_23_);}
+       .st30{fill:url(#SVGID_24_);}
+       .st31{fill:url(#SVGID_25_);}
+       .st32{fill:url(#SVGID_26_);}
+       .st33{fill:url(#SVGID_27_);}
+       .st34{fill:url(#SVGID_28_);}
+       .st35{fill:url(#SVGID_29_);}
+       .st36{fill:url(#SVGID_30_);}
+       .st37{fill:url(#SVGID_31_);}
+       .st38{fill:url(#SVGID_32_);}
+       .st39{fill:url(#SVGID_33_);}
+       .st40{fill:url(#SVGID_34_);}
+       .st41{fill:url(#SVGID_35_);}
+       .st42{fill:url(#SVGID_36_);}
+       .st43{opacity:0.4;fill:url(#SVGID_37_);}
+       .st44{fill:url(#SVGID_38_);}
+       .st45{fill:url(#SVGID_39_);}
+       .st46{fill:url(#SVGID_40_);}
+       .st47{fill:url(#SVGID_41_);}
+       .st48{fill:url(#SVGID_42_);}
+       .st49{fill:url(#SVGID_43_);}
+       .st50{fill:url(#SVGID_44_);}
+       .st51{display:inline;opacity:0.29;}
+       .st52{display:inline;fill:url(#SVGID_45_);}
+       .st53{display:inline;fill:url(#SVGID_46_);}
+       .st54{display:inline;fill:#FFFFFF;}
+       .st55{display:inline;fill:url(#SVGID_47_);}
+       .st56{display:inline;fill:url(#SVGID_48_);}
+       .st57{display:inline;fill:url(#SVGID_49_);}
+       .st58{display:inline;fill:url(#SVGID_50_);}
+       .st59{display:inline;fill:url(#SVGID_51_);}
+       .st60{display:inline;fill:url(#SVGID_52_);}
+       .st61{opacity:0.4;fill:url(#SVGID_53_);}
+       .st62{fill:url(#SVGID_54_);}
+       .st63{fill:url(#SVGID_55_);}
+       .st64{fill:url(#SVGID_56_);}
+       .st65{fill:url(#SVGID_57_);}
+       .st66{fill:url(#SVGID_58_);}
+       .st67{opacity:0.4;fill:url(#SVGID_59_);}
+       .st68{fill:url(#SVGID_60_);}
+       .st69{fill:url(#SVGID_61_);}
+       .st70{fill:url(#SVGID_62_);}
+       .st71{fill:url(#SVGID_63_);}
+       .st72{fill:url(#SVGID_64_);}
+       .st73{fill:url(#SVGID_65_);}
+       .st74{fill:url(#SVGID_66_);}
+       .st75{fill:url(#SVGID_67_);}
+       .st76{fill:url(#SVGID_68_);}
+       .st77{fill:url(#SVGID_69_);}
+       .st78{fill:url(#SVGID_70_);}
+       .st79{fill:url(#SVGID_71_);}
+       .st80{fill:url(#SVGID_72_);}
+       .st81{fill:url(#SVGID_73_);}
+       .st82{fill:url(#SVGID_74_);}
+       .st83{fill:url(#SVGID_75_);}
+       .st84{fill:url(#SVGID_76_);}
+       .st85{fill:url(#SVGID_77_);}
+       .st86{fill:url(#SVGID_78_);}
+       .st87{fill:url(#SVGID_79_);}
+       .st88{fill:url(#SVGID_80_);}
+       .st89{fill:url(#SVGID_81_);}
+       .st90{fill:url(#SVGID_82_);}
+       .st91{fill:url(#SVGID_83_);}
+       .st92{fill:url(#SVGID_84_);}
+       .st93{fill:url(#SVGID_85_);}
+       .st94{fill:url(#SVGID_86_);}
+       .st95{opacity:0.4;fill:url(#SVGID_87_);}
+       .st96{fill:url(#SVGID_88_);}
+       .st97{fill:url(#SVGID_89_);}
+       .st98{fill:url(#SVGID_90_);}
+       .st99{display:inline;fill:url(#SVGID_91_);}
+       .st100{display:inline;fill:url(#SVGID_92_);}
+       .st101{fill:url(#SVGID_93_);}
+       .st102{fill:url(#SVGID_94_);}
+       .st103{opacity:0.4;fill:url(#SVGID_95_);}
+       .st104{fill:url(#SVGID_96_);}
+       .st105{fill:url(#SVGID_97_);}
+       .st106{fill:url(#SVGID_98_);}
+       .st107{fill:url(#SVGID_99_);}
+       .st108{fill:url(#SVGID_100_);}
+       .st109{fill:url(#SVGID_101_);}
+       .st110{display:inline;fill:url(#SVGID_102_);}
+       .st111{display:inline;fill:url(#SVGID_103_);}
+       .st112{fill:url(#SVGID_104_);}
+       .st113{fill:url(#SVGID_105_);}
+       .st114{fill:url(#SVGID_106_);}
+       .st115{fill:url(#SVGID_107_);}
+       .st116{fill:url(#SVGID_108_);}
+       .st117{opacity:0.4;fill:url(#SVGID_109_);}
+       .st118{fill:url(#SVGID_110_);}
+       .st119{fill:url(#SVGID_111_);}
+       .st120{fill:url(#SVGID_112_);}
+       .st121{fill:url(#SVGID_113_);}
+       .st122{fill:url(#SVGID_114_);}
+       .st123{opacity:0.4;fill:url(#SVGID_115_);}
+       .st124{fill:url(#SVGID_116_);}
+       .st125{fill:url(#SVGID_117_);}
+       .st126{fill:url(#SVGID_118_);}
+       .st127{fill:url(#SVGID_119_);}
+       .st128{fill:url(#SVGID_120_);}
+       .st129{fill:url(#SVGID_121_);}
+       .st130{fill:url(#SVGID_122_);}
+</style><switch
+     id="switch6"><g
+       i:extraneous="self"
+       id="g8"><g
+         id="Settings_Active"><circle
+           class="st24"
+           cx="159.7"
+           cy="133.4"
+           r="101.9"
+           id="circle1230" /><linearGradient
+           id="SVGID_119_"
+           gradientUnits="userSpaceOnUse"
+           x1="115.9317"
+           y1="254.1836"
+           x2="256.3852"
+           y2="-133.5267"><stop
+             offset="0"
+             style="stop-color:#8BC53F"
+             id="stop1233" /><stop
+             offset="2.015080e-02"
+             style="stop-color:#7CCB56;stop-opacity:0.9678"
+             id="stop1235" /><stop
+             offset="6.089833e-02"
+             style="stop-color:#62D67D;stop-opacity:0.9028"
+             id="stop1237" /><stop
+             offset="0.1057"
+             style="stop-color:#4BDFA0;stop-opacity:0.8312"
+             id="stop1239" /><stop
+             offset="0.1543"
+             style="stop-color:#38E7BE;stop-opacity:0.7537"
+             id="stop1241" /><stop
+             offset="0.2077"
+             style="stop-color:#28EED6;stop-opacity:0.6684"
+             id="stop1243" /><stop
+             offset="0.2681"
+             style="stop-color:#1CF3E8;stop-opacity:0.572"
+             id="stop1245" /><stop
+             offset="0.3394"
+             style="stop-color:#13F6F5;stop-opacity:0.4581"
+             id="stop1247" /><stop
+             offset="0.4323"
+             style="stop-color:#0EF8FD;stop-opacity:0.3098"
+             id="stop1249" /><stop
+             offset="0.6264"
+             style="stop-color:#0DF9FF;stop-opacity:0"
+             id="stop1251" /></linearGradient><circle
+           class="st127"
+           cx="159.7"
+           cy="133.4"
+           r="101.9"
+           id="circle1253" /><linearGradient
+           id="SVGID_120_"
+           gradientUnits="userSpaceOnUse"
+           x1="4.0481"
+           y1="287.9492"
+           x2="320.4859"
+           y2="-15.4029"
+           gradientTransform="matrix(1 5.464556e-03 -5.464556e-03 1 -2.0192 -3.0212)"><stop
+             offset="0"
+             style="stop-color:#59FF7F"
+             id="stop1256" /><stop
+             offset="1"
+             style="stop-color:#6BFBFF"
+             id="stop1258" /></linearGradient><path
+           class="st128"
+           d="M160,238.8c-0.2,0-0.4,0-0.6,0c-58-0.3-104.9-47.7-104.6-105.7C55.2,75.3,102.3,28.5,160,28.5     c0.2,0,0.4,0,0.6,0c58,0.3,104.9,47.7,104.6,105.7l0,0C264.8,192,217.7,238.8,160,238.8z M160,32.2     c-55.7,0-101.2,45.2-101.5,100.9c-0.3,55.9,45,101.7,100.9,102c0.2,0,0.4,0,0.6,0c55.7,0,101.2-45.2,101.5-100.9     c0.3-55.9-45-101.7-100.9-102C160.4,32.2,160.2,32.2,160,32.2z"
+           id="path1260" /><g
+           id="g1262"><text
+             transform="matrix(1 0 0 1 75.4379 284.7129)"
+             class="st4 st5 st6 st7"
+             id="text1264">SETTINGS</text>
+<g
+             id="g1266"><g
+               id="g1268"><g
+                 id="g1270"><linearGradient
+                   id="SVGID_121_"
+                   gradientUnits="userSpaceOnUse"
+                   x1="79.1804"
+                   y1="226.0817"
+                   x2="282.752"
+                   y2="-4.8609"><stop
+                     offset="0"
+                     style="stop-color:#59FF7F"
+                     id="stop1273" /><stop
+                     offset="1"
+                     style="stop-color:#6BFBFF"
+                     id="stop1275" /></linearGradient><path
+                   class="st129"
+                   d="M159.9,163.9c-16.3,0-29.5-13.2-29.5-29.4s13.2-29.4,29.5-29.4v3.9c-14.1,0-25.5,11.4-25.5,25.5         c0,14,11.5,25.5,25.5,25.5c14.1,0,25.6-11.4,25.6-25.5h3.9C189.4,150.7,176.2,163.9,159.9,163.9z"
+                   id="path1277" /></g><g
+                 id="g1279"><linearGradient
+                   id="SVGID_122_"
+                   gradientUnits="userSpaceOnUse"
+                   x1="79.2457"
+                   y1="226.1393"
+                   x2="282.8174"
+                   y2="-4.8033"><stop
+                     offset="0"
+                     style="stop-color:#59FF7F"
+                     id="stop1282" /><stop
+                     offset="1"
+                     style="stop-color:#6BFBFF"
+                     id="stop1284" /></linearGradient><path
+                   class="st130"
+                   d="M171.7,197.4h-23.4c-2.2,0-4-1.8-4-3.9V181c-2-0.7-4-1.5-6-2.5l-8.8,8.8c-1.5,1.5-4,1.5-5.6-0.1         l-16.6-16.6c-1.6-1.6-1.6-4.1-0.1-5.6l8.7-8.7c-1-2-1.8-4-2.5-6.1h-12.3c-2.2,0-3.9-1.8-3.9-4v-23.4c0-2.2,1.8-4,3.9-4h12.3         c0.9-2.6,1.9-5.1,3.2-7.4l3.5,1.8c-1.4,2.6-2.5,5.3-3.4,8.1l-0.4,1.4h-15.2l0,23.5l15.2,0.1l0.4,1.4c0.9,2.8,2,5.5,3.4,8         l0.7,1.3L110,167.8l16.6,16.6l10.9-10.8l1.3,0.7c2.6,1.4,5.2,2.5,8,3.3l1.4,0.4v15.4l23.5,0l0.1-15.4l1.4-0.4         c2.7-0.8,5.4-1.9,7.9-3.3l1.3-0.7l10.9,10.9l16.6-16.6l-10.8-11l0.7-1.3c1.4-2.6,2.5-5.2,3.3-7.9l0.4-1.4h15.4l0-23.5         l-15.3-0.1l-0.4-1.4c-0.8-2.8-1.9-5.5-3.3-8l-0.7-1.3l10.8-10.8l-16.6-16.6l-10.8,10.7l-1.3-0.7c-2.6-1.4-5.3-2.5-8.1-3.4         l-1.4-0.4V75.6l-23.5,0l-0.1,15.1l-1.4,0.4c-2.8,0.9-5.6,2-8.1,3.4l-1.3,0.7l-10.7-10.7L107.2,104c-1.5-1.5-1.5-4,0.1-5.6         l16.5-16.5c0.8-0.8,1.8-1.3,2.9-1.2c1,0,2,0.4,2.7,1.1l8.7,8.6c2-1,4-1.8,6.2-2.5V75.6c0-2.2,1.8-3.9,4-3.9h23.4         c2.2,0,4,1.8,4,3.9v12.3c2.1,0.7,4.1,1.6,6.1,2.5l8.7-8.7c0.7-0.7,1.7-1.1,2.7-1.1h0c1.1,0,2.1,0.4,2.9,1.2l16.6,16.6         c0.8,0.8,1.2,1.8,1.2,2.9c0,1-0.4,2-1.1,2.7l-8.8,8.8c1,2,1.8,4,2.5,6h12.4c2.2,0,3.9,1.8,3.9,4v23.4c0,2.2-1.8,4-3.9,4         h-12.5c-0.7,2-1.5,4-2.5,6l8.9,8.9c1.5,1.5,1.5,4-0.1,5.6l-16.6,16.6c-0.8,0.8-1.8,1.2-2.9,1.2h0c-1,0-2-0.4-2.7-1.1         l-8.9-8.9c-1.9,1-3.9,1.8-5.9,2.5v12.5C175.7,195.6,173.9,197.4,171.7,197.4z"
+                   id="path1286" /></g></g></g></g></g></g></switch></svg>
\ No newline at end of file
diff --git a/package/package.pro b/package/package.pro
new file mode 100644 (file)
index 0000000..125a378
--- /dev/null
@@ -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 (file)
index 0000000..b04be4a
--- /dev/null
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = app binding-wifi binding-bluetooth package
+package.depends += app binding-wifi binding-bluetooth