summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Viironen <kalle.viironen@digia.com>2014-04-15 15:16:02 +0300
committerKalle Viironen <kalle.viironen@digia.com>2014-04-15 15:16:16 +0300
commit9627172876cd2a387d44b5a9a6ce0a3867ebc730 (patch)
treeea7b4382c6390ece7e9588e7e71ad7357b13b338
parent436af494659d416cfbd531b8d3ba9fc49e2fa710 (diff)
parentf9da7d90608cb4ce511770f5da8ef666e8a3e1b0 (diff)
Merge branch 'stable' into releaseQtEE_v2.1.0
* stable: Doc: Add ChangeLog for Qt Enterprise Embedded 2.1.0 Doc: Disable code highlighting for command-line instructions doc: update version number to 2.1.0 [Wifi] Add new enums and make some API changes Doc: Add documentation on custom build & deploy steps Doc: Create QML Type reference page Doc: Add information about licenses in embedded Linux images Doc: Improve instructions for deploying existing projects Doc: Separate Building Your Own Linux Image into its own page doc: use same directory for yocto and qt doc: config.<MACHINE> needed only once doc: guide for imx53 and how to setup QtCreator Doc: Be more precise on screen content for Nexus7 Add documentation to QtWifi library Doc: Add note for users to not use root for installation doc: describe how to use network connection for adb Rename misleading class name Remove unnecessary roles from QWifiNetworkList Document C++11 usage doc: how to use rebuilt yocto images and BYOS Change-Id: If51af9f476d05e7d147d93670d36ca1b99e03d8c
-rw-r--r--src/doc/config/b2qt.qdocconf15
-rw-r--r--src/doc/config/html-offline.qdocconf2
-rw-r--r--src/doc/src/b2qt-external-pages.qdoc10
-rw-r--r--src/doc/src/b2qt-post-install-setup.qdocinc4
-rw-r--r--src/doc/src/b2qt.qdoc409
-rw-r--r--src/imports/wifi/pluginmain.cpp31
-rw-r--r--src/imports/wifi/qwifimanager.cpp339
-rw-r--r--src/imports/wifi/qwifimanager.h20
-rw-r--r--src/imports/wifi/qwifinetwork.cpp75
-rw-r--r--src/imports/wifi/qwifinetwork.h8
-rw-r--r--src/imports/wifi/qwifinetworklistmodel.cpp (renamed from src/imports/wifi/qwifinetworklist.cpp)93
-rw-r--r--src/imports/wifi/qwifinetworklistmodel.h (renamed from src/imports/wifi/qwifinetworklist.h)13
-rw-r--r--src/imports/wifi/wifi.pro4
13 files changed, 826 insertions, 197 deletions
diff --git a/src/doc/config/b2qt.qdocconf b/src/doc/config/b2qt.qdocconf
index 7c97275..3f8f92a 100644
--- a/src/doc/config/b2qt.qdocconf
+++ b/src/doc/config/b2qt.qdocconf
@@ -6,20 +6,24 @@ sourceencoding = UTF-8
project = QtEnterpriseEmbedded
description = Qt Enterprise Embedded Documentation
-version = 2.0.0
+version = 2.1.0
-sourcedirs = ../src
-imagedirs += ../images
+sourcedirs = ../src \
+ ../../imports/wifi
+
+headerdirs = ../../imports/wifi
-sources.fileextensions = "*.qdoc"
+imagedirs += ../images
indexes = $QT_INSTALL_DOCS/qtquick/qtquick.index \
+ $QT_INSTALL_DOCS/qtcore/qtcore.index \
+ $QT_INSTALL_DOCS/qtserialport/qtserialport.index \
$QT_INSTALL_DOCS/emulator/emulator.index
qhp.projects = B2Qt
qhp.B2Qt.file = b2qt.qhp
-qhp.B2Qt.namespace = com.digia.b2qt.200
+qhp.B2Qt.namespace = com.digia.b2qt.210
qhp.B2Qt.virtualFolder = b2qt
qhp.B2Qt.indexTitle = Qt Enterprise Embedded Documentation
qhp.B2Qt.indexRoot =
@@ -35,3 +39,4 @@ macro.B2QA = "\\e {Boot to Qt for embedded Android}"
macro.B2QL = "\\e {Boot to Qt for embedded Linux}"
navigation.landingpage = "Qt Enterprise Embedded"
+navigation.qmltypespage = "Add-On QML Types"
diff --git a/src/doc/config/html-offline.qdocconf b/src/doc/config/html-offline.qdocconf
index 29a5613..0e01c05 100644
--- a/src/doc/config/html-offline.qdocconf
+++ b/src/doc/config/html-offline.qdocconf
@@ -1,5 +1,7 @@
# use the global Qt template with modifications to the html footer
include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)
+include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf)
+include($QT_INSTALL_DOCS/global/fileextensions.qdocconf)
HTML.nobreadcrumbs = "true"
diff --git a/src/doc/src/b2qt-external-pages.qdoc b/src/doc/src/b2qt-external-pages.qdoc
index 5196095..694f349 100644
--- a/src/doc/src/b2qt-external-pages.qdoc
+++ b/src/doc/src/b2qt-external-pages.qdoc
@@ -28,6 +28,16 @@
*/
/*!
+ \externalpage https://qtcloudservices.com/products/enginio-data-storage/
+ \title Enginio Data Storage
+*/
+
+/*!
+ \externalpage http://qt.digia.com/Product/Qt-Enterprise-Features/Advanced-Data-Visualization/
+ \title Qt Data Visualization
+*/
+
+/*!
\externalpage http://qt.digia.com/Product/Qt-Enterprise-Features/Qt-Quick-Enterprise-Controls/
\title Qt Quick Enterprise Controls
*/
diff --git a/src/doc/src/b2qt-post-install-setup.qdocinc b/src/doc/src/b2qt-post-install-setup.qdocinc
index 7fac266..ec293de 100644
--- a/src/doc/src/b2qt-post-install-setup.qdocinc
+++ b/src/doc/src/b2qt-post-install-setup.qdocinc
@@ -26,7 +26,7 @@
\li Run the following command in a shell:
- \code
+ \badcode
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", TAG+="udev-acl", TAG+="uaccess"' | sudo tee -a /etc/udev/rules.d/70-boot2qt.rules
\endcode
@@ -65,7 +65,7 @@
//! [steps for device kit]
\list 1
\li Select \b{Tools > Options > Build & Run > Kits}.
- \li Select one of the predefined kits starting with \e{Boot2Qt...}
+ \li Select one of the predefined kits starting with \e{Boot to Qt...}
that matches the type of your device.
\li Select the correct device in the \b{Device} field.
\li Select \b{OK}.
diff --git a/src/doc/src/b2qt.qdoc b/src/doc/src/b2qt.qdoc
index 6f2d44c..7e7bad4 100644
--- a/src/doc/src/b2qt.qdoc
+++ b/src/doc/src/b2qt.qdoc
@@ -49,12 +49,22 @@
\li \l{Preparing BeagleBoard-xM}{BeagleBoard-xM (embedded Linux)}
\li \l{Preparing Raspberry Pi}{Raspberry Pi Model B (embedded Linux)}
\endlist
- \li \l{Building and Running an Example}
+ \li \l{Building and Running Embedded Applications}
+ \list
+ \li \l{Special Build & Run Options}
+ \endlist
\li \l{Customization}
+ \li \l{Building Your Own Embedded Linux Image}
\li \l{ChangeLog}
\li \l{Troubleshooting}
\li \l{License Information}
\endlist
+
+ \section1 Reference Documentation
+
+ \list
+ \li \l{Add-On QML Types}
+ \endlist
*/
/*!
@@ -181,13 +191,13 @@
install the required packages in recent versions of Ubuntu, use
the following command in a terminal:
- \code
+ \badcode
sudo apt-get install g++-multilib zlib1g:i386
\endcode
For older Ubuntu versions such as 12.04, instead do:
- \code
+ \badcode
sudo apt-get install g++-multilib ia32-libs
\endcode
@@ -202,14 +212,14 @@
version of VirtualBox than your distribution does provide.
You have to add a foreign package source:
- \code
+ \badcode
wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
echo "deb http://download.virtualbox.org/virtualbox/debian $(lsb_release -sc) contrib" | sudo tee /etc/apt/sources.list.d/virtualbox.list
sudo apt-get update
\endcode
Now install VirtualBox on your computer
- \code
+ \badcode
sudo apt-get install virtualbox-4.3
\endcode
@@ -253,6 +263,8 @@
\endlist
+ \note Do not execute the installer as root user or with sudo.
+
The installer will let you select a directory where \SDK will be
installed. In this documentation, the installation directory is referred
to as \b{\c{<INSTALL_DIR>}}. The default installation directory is
@@ -329,7 +341,7 @@
\note If the ordinary startup screen appears instead, power off the
device and try again.
\li On the development host, enter the following command:
- \code
+ \badcode
sudo <INSTALL_DIR>/Tools/b2qt/fastboot oem unlock
\endcode
\li Press the power button to confirm that you want to unlock the
@@ -351,7 +363,7 @@
\li Re-flash the \e{boot}, \e{system}, and \e{userdata} partitions on the
device, by entering the following commands in the following order:
- \code
+ \badcode
cd <INSTALL_DIR>
sudo ./Tools/b2qt/fastboot flash boot Boot2Qt-2.x/nexus7-eAndroid/images/boot.img
sudo ./Tools/b2qt/fastboot flash system Boot2Qt-2.x/nexus7-eAndroid/images/system.img
@@ -360,22 +372,22 @@
\li Once the flashing is completed successfully, reboot the device:
- \code
+ \badcode
sudo ./Tools/b2qt/fastboot reboot
\endcode
\endlist
\note You must install proprietary drivers for the Nexus 7 to boot
- correctly. Until then, the screen will only show the "Google" logo,
- instead of the \B2Q welcome screen or demo.
+ correctly. Until then, the screen will briefly show the "Google" logo and then go black,
+ instead of showing the \B2Q welcome screen or demo.
\section1 Installing Proprietary Drivers
Download the proprietary drivers for your Nexus 7. The following script downloads the third
party drivers from \l{https://developers.google.com/android/nexus/drivers#grouperjdq39}
{https://developers.google.com/android/nexus/drivers#grouperjdq39}
- \code
+ \badcode
cd <INSTALL_DIR>
./Boot2Qt-2.x/nexus7-eAndroid/images/download.sh
\endcode
@@ -389,7 +401,7 @@
\li Power on the device and connect it to the development host via USB.
Also check that the device is \e{not} in fastboot mode.
\li Run the driver extractors:
- \code
+ \badcode
cd Boot2Qt-2.x/nexus7-eAndroid/images/drivers
./extract-nvidia-grouper.sh
./extract-asus-grouper.sh
@@ -399,11 +411,11 @@
\note Carefully read the license terms enclosed in each individual
extractor.
\li Find out the serial number of the connected Nexus 7 device:
- \code
+ \badcode
./Tools/b2qt/adb devices
\endcode
\li Deploy the drivers to your device:
- \code
+ \badcode
./Boot2Qt-2.x/nexus7-eAndroid/images/deploy.sh <serial_number>
\endcode
\endlist
@@ -450,7 +462,7 @@
To write the image to the SD card:
- \code
+ \badcode
cd <INSTALL_DIR>
sudo Boot2Qt-2.x/beagleboard-eLinux/images/deploy.sh /dev/<device_name>
\endcode
@@ -507,13 +519,13 @@
\list 1
\li Extract the downloaded package:
- \code
+ \badcode
~/$ mkdir bd-android
~/$ cd bd-android
~/bd-android$ tar zxvf ~/Downloads/imx6-jb-20130628.tar.gz
\endcode
\li Run device/boundary/mksdcard.sh:
- \code
+ \badcode
~/bd-android$ sudo device/boundary/mksdcard.sh /dev/<device_name>
~/bd-android$ sync
\endcode
@@ -523,7 +535,7 @@
Make sure you have the required tools installed in your development machine:
- \code
+ \badcode
sudo apt-get install u-boot-tools
\endcode
@@ -532,12 +544,12 @@
\list
\li \b{\B2QA}
- \code
+ \badcode
cd <INSTALL_DIR>
./Boot2Qt-2.x/iMX6-eAndroid/images/deploy.sh /dev/<device_name>
\endcode
\li \b{\B2QL}
- \code
+ \badcode
cd <INSTALL_DIR>
sudo ./Boot2Qt-2.x/iMX6-eLinux/images/deploy.sh /dev/<device_name>
\endcode
@@ -589,7 +601,7 @@
To write the image to the SD card:
- \code
+ \badcode
cd <INSTALL_DIR>
sudo Boot2Qt-2.x/raspberrypi-eLinux/images/deploy.sh /dev/<device_name>
\endcode
@@ -641,11 +653,11 @@
\list 1
\li Extract the downloaded package:
- \code
+ \badcode
~$ tar zxvf ~/Downloads/TI_Android_JB_4.2.2_DevKit_4.1.1_beagleboneblack.tar.gz
\endcode
\li Run beagleboneblack/mkmmc-android.sh:
- \code
+ \badcode
~$ cd beagleboneblack
~/beagleboneblack$ sudo ./mkmmc-android.sh /dev/<device_name>
\endcode
@@ -658,12 +670,12 @@
\list
\li \b{\B2QA}
- \code
+ \badcode
cd <INSTALL_DIR>
./Boot2Qt-2.x/beaglebone-eAndroid/images/deploy.sh /dev/<device_name>
\endcode
\li \b{\B2QL}
- \code
+ \badcode
cd <INSTALL_DIR>
sudo ./Boot2Qt-2.x/beaglebone-eLinux/images/deploy.sh /dev/<device_name>
\endcode
@@ -685,10 +697,59 @@
*/
/*!
+ \target i.MX53 Quick Start Board (embedded Linux)
+ \page qtee-preparing-hardware-imx53qsb.html
+ \title Preparing i.MX53 Quick Start Board
+ \previouspage qtee-installation-guide.html
+ \nextpage qtee-building-and-running.html
+
+ Take the following steps to prepare a
+ \l{http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX53QSB} {i.MX53 Quick Start Board}
+ for \B2Q.
+
+ \note Ethernet networking is required to connect the device to Qt Creator.
+
+ \note It is important that you repeat the steps in this section after you
+ update \SDK.
+
+ As i.MX53 Quick Start Board is not a \SDK reference board, there is no ready-made
+ image containing a \B2Q stack available. Instead, you must build it yourself using
+ the Yocto recipes and build scripts from the \B2Q source packages.
+ For more information, see \l{Building Your Own Embedded Linux Image}.
+
+ \section1 Preparing an SD Card
+
+ An SD card of at least 512 MB capacity is sufficient.
+
+ \include detect-sd-card-device-name.qdocinc instructions
+
+ \section1 Installing the \B2Q Image
+
+ To write the image to the SD card:
+
+ \badcode
+ cd <QtBuildDir>
+ sudo deploy.sh /dev/<device_name>
+ \endcode
+
+ After the image has been deployed, insert the SD card, power on the device and check that
+ the \B2Q welcome screen and/or demo appear.
+
+ \section1 Configuring a Device Kit in Qt Creator
+
+ \include b2qt-post-install-setup.qdocinc configuring network device
+
+ You are now ready to start developing for your device. For more information,
+ see \l{Building and Running an Example}.
+*/
+
+/*!
\page qtee-building-and-running.html
- \title Building and Running an Example
+ \title Building and Running Embedded Applications
\previouspage qtee-preparing-hardware.html
- \nextpage qtee-customization.html
+ \nextpage qtee-custom-build-steps.html
+
+ \section1 Building and Running an Example
After you complete the installation and configuration steps for \SDK and the
target devices, you can test the setup by creating a simple \l{Qt Quick}
@@ -697,7 +758,7 @@
\list 1
\li Make sure that your device is powered on and connected to the
development host.
- \li In Qt Creator, select \b{File > New File or Project} >
+ \li In Qt Creator, select \b File > \b {New File or Project} >
\b Applications > \b{Qt Quick Application} > \b{Choose}.
\li Choose a location for your new project.
\li In the \b{Qt Quick Component Set} dialog, select \b{Qt Quick 2.0}.
@@ -705,7 +766,7 @@
devices. You can also select the emulator kit to test running the
project in the emulator.
\li Click \b{Next} and finish the wizard.
- \li In \b{Projects > Build & Run}, select the correct kit for your
+ \li In \b Projects > \b {Build & Run}, select the correct kit for your
connected device.
\li To build and run the project, click \inlineimage qtcreator-run.png
\endlist
@@ -718,7 +779,7 @@
\li Go to \b Welcome > \b Examples.
\li Select a \e Boot2Qt Qt version from the drop-down list.
\li Select a demo you want to build.
- \li In \b{Projects > Build & Run}, select the correct kit for your
+ \li In \b Projects > \b {Build & Run}, select the correct kit for your
connected device or emulator.
\li To build and run the project, click \inlineimage qtcreator-run.png
\endlist
@@ -726,34 +787,83 @@
\section1 Setting Up an Already Existing Project for Deployment
New Qt Quick application projects generated by Qt Creator always have the correct
- settings for deployment on the device or emulator. However, other projects may
- need some changes.
+ settings for deployment on the device or emulator. However, other projects need
+ some changes. This includes projects created using the
+ \b File > \b {New File or Project} > \b Applications > \b{Qt Widget Application}
+ template.
- As a general rule, application binaries and resources (such as QML files and
- images) are deployed to the \c {/data/user/qt/<APPLICATION_NAME>} directory.
- Therefore, the \c path variable for the \c INSTALLS targets needs to be adjusted
- accordingly in .pro files.
+ As a general rule, application binaries and resources are deployed to the
+ \c {/data/user/qt/<APPLICATION_NAME>} directory. Therefore, the \c path variable for
+ the \c INSTALLS targets needs to be adjusted accordingly in .pro files.
- For example, change the following \c target.path value:
+ Open the .pro file and define the \c target.path and \c INSTALLS variables as follows:
- \code
- target.path = ...
- INSTALLS += target
+ \badcode
+ target.path = /data/user/qt/$$TARGET
+ INSTALLS += target
\endcode
- to:
+ Above, \c {$$TARGET} expands to the application target (executable) name.
+
+ \section2 Deploying Application Resources
- \code
- target.path = /data/user/qt/<APPLICATION_NAME>
- INSTALLS += target
+ If the application depends on additional resources (such as QML files and
+ images), you need to deploy them as well. For example:
+
+ \badcode
+ appFiles.files = *.png qml
+ appFiles.path = /data/user/qt/$$TARGET
+ INSTALLS += appFiles
\endcode
+
+ Above, all PNG images from the application source directory, and the entire
+ \e qml subdirectory are included in the deployment.
+
+ Alternatively, the files used by the application can be stored into the application
+ executable using the \l{The Qt Resource System}{Qt resource system}. This way, simply
+ deploying the application binary is all that's required.
+*/
+
+/*!
+ \page qtee-custom-build-steps.html
+ \title Special Build & Run Options
+ \previouspage qtee-building-and-running.html
+ \nextpage qtee-customization.html
+
+ Qt Creator allows you to execute custom commands on the embedded device connected
+ to the development host, both during the build process and during deployment of your
+ application.
+
+ \section1 Custom Build Steps
+
+ To add a custom step to be executed during the build:
+
+ \list 1
+ \li In Qt Creator, go to \b Projects > \b {Build Settings}
+ \li Select \b Build configuration for the \e {\B2Q} version you want to customize.
+ \li Click \b {Add Build Step} and select \b {Custom Remote Command (via adb shell)}.
+ \li Enter the command to be executed.
+ \endlist
+
+ \section1 Custom Deployment Steps
+
+ To add a custom step to be executed during deployment:
+
+ \list 1
+ \li In Qt Creator, go to \b Projects > \b {Run Settings}
+ \li Select \b Run configuration for the \e {\B2Q} version you want to customize.
+ \li Click \b {Add Deploy Step} and select \b {Custom Remote Command (via adb shell)}.
+ \li Enter the command to be executed.
+ \endlist
+
+ \sa {Booting to a Custom Application}
*/
/*!
\page qtee-customization.html
\title Customization
\previouspage qtee-building-and-running.html
- \nextpage qtee-changelog.html
+ \nextpage qtee-custom-embedded-linux-image.html
\section1 Environment and Input
@@ -769,13 +879,13 @@
On some devices, the root file system (where this file
resides) is mounted read-only at boot time. To allow modification,
remount it read-write by entering the following command:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb remount
\endcode
In the \c{appcontroller.conf} file, the input devices are
specified by the lines similar to these:
- \code
+ \badcode
env=QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event0
\endcode
@@ -795,12 +905,13 @@
After you have deployed your own application to the device, it will be
launched on boot, instead of the \B2Q demo launcher. To prevent this
- behavior, remove the \b {Make this application the default one} step from
- the \b{Run Settings} for your project in the Qt Creator \b Projects mode.
+ behavior, remove or disable the \b {Make this application the default one}
+ step from the \b{Run Settings} for your project in the Qt Creator \b Projects
+ mode.
To remove your application from the default startup, use the following
command:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb shell appcontroller --remove-default
\endcode
@@ -811,7 +922,7 @@
to change the default view orientation. The following example shows how to rotate your
application in QML.
- \code
+ \qml
import QtQuick 2.0
Item {
@@ -840,7 +951,7 @@
}
}
}
- \endcode
+ \endqml
\section1 Disabling Screen Composer on Embedded Android
@@ -858,8 +969,13 @@
change \c /init.rc, or simply rename the \c
{/system/bin/surfaceflinger} executable.
\endlist
+*/
- \section1 Building Your Own Embedded Linux Image
+/*!
+ \page qtee-custom-embedded-linux-image.html
+ \title Building Your Own Embedded Linux Image
+ \previouspage qtee-customization.html
+ \nextpage qtee-changelog.html
\B2QL is built using the tools and resources from the \l {Yocto Project},
and is based on Yocto's reference distribution (\e Poky). You can
@@ -867,7 +983,15 @@
which packages are included in the build and how the software stack
is configured.
- \section2 Requirements
+ \section2 Note About Support Services for Yocto Tools
+
+ By default, Digia will only provide customer support for the Yocto
+ recipes on the reference platforms, as delivered with \SDK, and
+ setting up the development environment for them. Receiving support
+ for any other configuration requires a separate service agreement
+ between a customer and Digia.
+
+ \section1 Requirements
You should be familiar with the Yocto tools and the concept of
\e {recipes}. For more information, see Yocto Project
@@ -884,27 +1008,27 @@
compatible with \B2Q.
\li Install the dependencies for the Yocto tools. In Ubuntu,
the following packages are required:
- \code
+ \badcode
sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath libsdl1.2-dev xterm
\endcode
\endlist
- \section2 Setting Up Yocto Build Environment
+ \section1 Setting Up Yocto Build Environment
Run the setup script that initializes the Yocto environment:
- \code
- cd <your/yocto/build/directory>
+ \badcode
+ cd <BuildDir>
<INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-yocto-meta/b2qt-init-build-env .
\endcode
- \section2 Building the Image and Toolchain
+ \section1 Building the Image and Toolchain
After the Yocto environment is set up, you need to configure the
build environment for your target device. Using Raspberry Pi as
an example:
- \code
+ \badcode
export TEMPLATECONF=meta-b2qt/conf
export MACHINE=raspberrypi
source poky/oe-init-build-env build-raspberrypi
@@ -914,52 +1038,78 @@
and the external toolchain that is used for building the Qt framework and
applications.
- \code
+ \badcode
bitbake b2qt-embedded-image
bitbake meta-toolchain-b2qt-embedded-sdk
\endcode
+ The target rootfs image is located in the \c <YoctoBuildDir>/tmp/deploy/images/<target>/b2qt-embedded-image-<target>.tar.gz,
+ and the new toolchain is in \c <YoctoBuildDir>/tmp/deploy/sdk/b2qt-eglibc-x86_64-meta-toolchain-b2qt-embedded-sdk-<target-architecture>-toolchain-1.5.sh
+
\note The generated target image does not yet include Qt libraries,
you need to build Qt and add it into the image yourself.
- \section2 Building Qt and Addons
+ \section1 Building Qt and Addons
\e {Build scripts} source package contains scripts that can be used to
build Qt and all additional Qt addons that are part of \B2QL image.
- To setup build environment for your target hardware, create new build
- directory and run the initialization script. Using Raspberry Pi as
- an example:
+ To setup build environment for your target hardware, run the initialization
+ script. Using Raspberry Pi as an example:
- \code
- cd <your/qt/build/directory>
+ \badcode
<INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-common/init_build_env.sh <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/config.raspberrypi
\endcode
+ \note You can use the same build directory for Qt and the Yocto image.
+ The toolchain and the target image are then used from the Yocto build directory.
+
You can use following scripts to build different parts of the \B2Q stack.
- \code
- <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_qt.sh <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/config.raspberrypi
- <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_extras.sh <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/config.raspberrypi
- <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_image.sh <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/config.raspberrypi
+ \badcode
+ <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_qt.sh
+ <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_extras.sh
+ <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-linux/build_image.sh
\endcode
After \e {embedded-linux/build_image.sh} has finished, you can flash the device with
the updated image located in the build folder.
- \section2 Note About Support Services for Yocto Tools
+ \section1 Configuring Qt Creator
- By default, Digia will only provide customer support for the Yocto
- recipes on the reference platforms, as delivered with \SDK, and
- setting up the development environment for them. Receiving support
- for any other configuration requires a separate service agreement
- between a customer and Digia.
+ After you have built the \B2Q stack, you must also set up Qt Creator in order to start
+ developing for your device. The following script does this for you.
+
+ \badcode
+ <INSTALL_DIR>/Boot2Qt-2.x/sources/b2qt-build-scripts/embedded-common/setup_qtcreator.sh
+ \endcode
+
+ This will set up a new kit in Qt Creator, using the toolchain and Qt from
+ your build directory. The new kit is visible under \b Tools > \b Options
+ > \b {Build & Run} > \b Kits.
+
+ \section1 Using Network Connection for ADB
+
+ By default, \B2Q uses USB cable for communication between device and Qt Creator.
+ On \B2QL, you can change the device to use ethernet network connection for the
+ communication. To enable network connection, you need to modify file
+ \c /etc/default/adbd located on the devices, and change value of \c USE_ETHERNET
+ to \c 'yes'. This can also be done with \c adb, while the device is still
+ connected via USB.
+
+ \badcode
+ <INSTALL_DIR>/Tools/b2qt/adb shell sed -i -e 's/USE_ETHERNET=no/USE_ETHERNET=yes/' /etc/default/adbd
+ \endcode
+
+ \note You need to restart the device for this change to take effect.
+
+ \include b2qt-post-install-setup.qdocinc configuring network device
*/
/*!
\page qtee-supported-platforms.html
\title Supported Platforms
\previouspage qtee-installation-guide.html
- \nextpage qtee-changelog.html
+ \nextpage qtee-preparing-hardware.html
\section1 Supported Target Devices
@@ -996,6 +1146,7 @@
\page qtee-licenses.html
\title License Information
\previouspage qtee-troubleshooting.html
+ \nextpage qtee-qml-reference.html
\section1 Licensing
@@ -1015,6 +1166,15 @@
source licenses and notices are collected into the file
\c {/etc/NOTICE.html.gz} in the target images.
+ \section1 Embedded Linux Images
+
+ The embedded Linux platform is built using tools from the \l {Yocto Project}.
+ The open source licenses and notices are located in
+ \list
+ \li \c /usr/share/common-licenses/license.manifest
+ \li \c /usr/share/licenses/*
+ \endlist
+
\section1 Android GNU C++ Run-time Licensing
The Android platform does not provide a full implementation of the C++ run-time. Instead,
@@ -1038,6 +1198,60 @@
\previouspage qtee-customization.html
\nextpage qtee-troubleshooting.html
+ \section1 \B2Q 2.1.0
+
+ \list
+ \li Release date: Apr. 15, 2014
+ \endlist
+
+ \section2 Changes
+ \b {New Features}:
+ \list
+ \li \l {Qt Data Visualization} version 1.0 was added to the \B2Q stack
+ \li \l {Enginio Data Storage} version 1.0 was added to the \B2Q stack
+ \li \l {Qt Quick Enterprise Controls} was updated to version 1.1
+ \li \l {Qt Serial Port} support was added to the \B2Q stack
+ \li Bluetooth on \B2QL: Support for bluez was added
+ \li Added support for building \B2QL for i.MX53 from sources
+ \endlist
+
+ \b {Improvements}:
+ \list
+ \li Qt Creator plugin for \B2Q now supports incremental deployment, custom adb commands
+ \li Adb now easily usable over IP on all devices on \B2QL
+ \li Update new content to device without erasing it first on \B2QL
+ \li All images now contain generally used CA certificates
+ \li Toolchains updated to support Qt WebEngine
+ \li Documentation was added for QML types provided by the \l {WiFi Module}
+ \li Emulator: Debug logging functionality was added
+ \li Various documentation improvements
+ \li \SDK installer error handling was improved
+ \li 3rd party license information was updated
+ \li Launcher Settings application UI was improved
+ \endlist
+
+ \b {Fixed Bugs}:
+ \list
+ \li \B2QL: OpenSSL Heartbleed bug was fixed
+ \li \B2QA: Qt debug symbols were missing
+ \li QEglFSCompositor::render() using incorrect vertices for full-screen quad, resulting in bad texture sampling
+ \li Use damaged rect instead of full texture upload for raster windows
+ \li Emulator: Crash when launching multiple instances
+ \li Emulator: State transitions were not working properly
+ \li \B2QA emulator: C++ debugging was fixed
+ \li Emulators: Qt Quick applications don't exit on Qt.quit()
+ \li Banding was visible on Raspberry Pi
+ \li Qt Creator: adb failed to connect
+ \li QtCreator: Different Virtual Machiness with the same OS were not handled properly
+ \li Qt Creator: Tabstop order in device wizard was incorrect
+ \li Qt 5 Everywhere demo: not all internet radio station were working
+ \endlist
+
+ \b {Fixed Known Issues}:
+ \list
+ \li Embedded Android: Arabic Numbers Not Always Rendered Correctly
+ \endlist
+
\section1 \B2Q 2.0.0
\list
@@ -1159,7 +1373,7 @@
download the correct file for your device. Unpack it, and then enter the
following commands:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb reboot bootloader
<INSTALL_DIR>/Tools/b2qt/fastboot -w update <image-file>.zip
\endcode
@@ -1171,7 +1385,7 @@
Otherwise, make sure the Nexus 7 is connected to the development host, and run
the following command in a terminal:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb shell reboot -p
\endcode
@@ -1201,7 +1415,7 @@
\section2 Something crashed!
The following command shows the system log:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb logcat
\endcode
@@ -1228,6 +1442,16 @@
See \l{Customization}.
+ \section2 C++11 features do not work on Android
+
+ To enable C++11 features in the compiler, add \e{CONFIG += c++11} to the .pro file.
+ On Embedded Linux this will be enough because there the toolchain contains a more
+ recent version of gcc (4.8.x). On Embedded Android however the toolchain is based on
+ gcc 4.6. This offers limited support for C++11 and Qt's own C++11 support is disabled,
+ meaning that adding \e{c++11} to \e{CONFIG} will have no effect. There is still a
+ possibility however to manually enable some level of C++11 support just for the
+ application, by adding \e{QMAKE_CXXFLAGS += -std=c++11} to the .pro file.
+
\section1 Connectivity Issues
\section2 I cannot connect to my hardware device via USB
@@ -1240,7 +1464,7 @@
command to find to see the serial number of the connected
devices:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb devices
\endcode
@@ -1258,18 +1482,18 @@
Check the output of the following command:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb devices
\endcode
If the emulator (192.168.56.101) is not listed there, try connecting to it:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb connect 192.168.56.101
\endcode
If the emulator is already listed, try disconnecting it:
- \code
+ \badcode
<INSTALL_DIR>/Tools/b2qt/adb disconnect 192.168.56.101
\endcode
@@ -1281,3 +1505,18 @@
*/
+
+/*!
+ \page qtee-qml-reference.html
+ \title Add-On QML Types
+ \previouspage qtee-licenses.html
+
+ The following QML modules are included in the \B2Q stack and provide
+ additional QML types that are useful in an embedded application:
+
+ \annotatedlist qtee-qmlmodules
+
+ \section1 WiFi Module
+
+ \annotatedlist wifi-qmltypes
+*/
diff --git a/src/imports/wifi/pluginmain.cpp b/src/imports/wifi/pluginmain.cpp
index 3c560f9..fdf07e9 100644
--- a/src/imports/wifi/pluginmain.cpp
+++ b/src/imports/wifi/pluginmain.cpp
@@ -25,6 +25,35 @@
#include <hardware_legacy/wifi.h>
+/*!
+ \qmltype Interface
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief The Interface element provides the module API.
+
+ This element cannot be directly created. It can only be accessed via a namespace import.
+
+ \code
+ import Qt.labs.wifi 0.1
+ import Qt.labs.wifi 0.1 as Wifi
+
+ Component.onCompleted: {
+ if (Wifi.Interface.wifiSupported()) {
+ var component = Qt.createComponent("WifiMenu.qml")
+ } else {
+ print("WiFi functionality not available on this device.")
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod bool Interface::wifiSupported()
+
+ Returns true if the device is WiFi capable (provides a WiFi driver), otherwise returns false.
+*/
+
+
class QWifiGlobal : public QObject
{
Q_OBJECT
@@ -68,7 +97,7 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.wifi"));
qmlRegisterType<QWifiManager>(uri, 0, 1, "WifiManager");
- qmlRegisterType<QWifiNetworkList>();
+ qmlRegisterType<QWifiNetworkListModel>();
qmlRegisterSingletonType<QWifiGlobal>(uri, 0, 1, "Interface", global_object_wifi);
}
};
diff --git a/src/imports/wifi/qwifimanager.cpp b/src/imports/wifi/qwifimanager.cpp
index 7d6683b..af6f5d3 100644
--- a/src/imports/wifi/qwifimanager.cpp
+++ b/src/imports/wifi/qwifimanager.cpp
@@ -32,6 +32,7 @@ static bool QT_WIFI_DEBUG = !qgetenv("QT_WIFI_DEBUG").isEmpty();
const QEvent::Type WIFI_SCAN_RESULTS = (QEvent::Type) (QEvent::User + 2001);
const QEvent::Type WIFI_CONNECTED = (QEvent::Type) (QEvent::User + 2002);
+const QEvent::Type WIFI_HANDSHAKE_FAILED = (QEvent::Type) (QEvent::User + 2003);
/*
* This function is borrowed from /system/core/libnetutils/dhcp_utils.c
@@ -89,28 +90,30 @@ public:
}
void run() {
- if (QT_WIFI_DEBUG) qDebug("EventReceiver thread is running");
+ if (QT_WIFI_DEBUG) qDebug("WiFi event thread is running");
+ QWifiManagerEvent *event = 0;
char buffer[2048];
while (1) {
int size = wifi_wait_for_event(m_if.constData(), buffer, sizeof(buffer) - 1);
if (size > 0) {
buffer[size] = 0;
-
- if (QT_WIFI_DEBUG) qDebug("EVENT: %s", buffer);
-
- char *event = &buffer[11];
- if (strstr(event, "SCAN-RESULTS")) {
- if (m_manager->exitingEventThread())
+ event = 0;
+ if (strstr(buffer, "SCAN-RESULTS")) {
+ if (m_manager->exitingEventThread()) {
+ if (QT_WIFI_DEBUG) qDebug() << "Exiting WiFi event thread";
return;
- QWifiManagerEvent *e = new QWifiManagerEvent(WIFI_SCAN_RESULTS);
- QCoreApplication::postEvent(m_manager, e);
- } else if (strstr(event, "CONNECTED")) {
- QWifiManagerEvent *e = new QWifiManagerEvent(WIFI_CONNECTED);
- QCoreApplication::postEvent(m_manager, e);
- } else if (strstr(event, "TERMINATING")) {
+ }
+ event = new QWifiManagerEvent(WIFI_SCAN_RESULTS);
+ } else if (strstr(buffer, "CONNECTED")) {
+ event = new QWifiManagerEvent(WIFI_CONNECTED);
+ } else if (strstr(buffer, "Handshake failed")) {
+ event = new QWifiManagerEvent(WIFI_HANDSHAKE_FAILED);
+ } else if (strstr(buffer, "TERMINATING")) {
// stop monitoring for events when supplicant is terminating
return;
}
+ if (event)
+ QCoreApplication::postEvent(m_manager, event);
}
}
}
@@ -119,13 +122,236 @@ public:
QByteArray m_if;
};
+/*!
+ \qmlmodule Qt.labs.wifi 0.1
+ \title WiFi Module
+ \ingroup qtee-qmlmodules
+ \brief Controlling wireless network interfaces.
+
+ Provides QML types for controlling and accessing information about wireless network interfaces.
+
+ The import command for adding these QML types is:
+
+ \code
+ import Qt.labs.wifi 0.1
+ \endcode
+
+ If the module is imported into a namespace, some additional methods become available through the
+ \l Interface element.
+
+ \code
+ import Qt.labs.wifi 0.1 as Wifi
+ \endcode
+
+ \section1 QML Types
+*/
+
+/*!
+
+ \qmltype WifiManager
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief Provides information about the WiFi backend and available networks.
+
+ This element is the main interface to the WiFi functionality.
+
+ */
+
+/*!
+ \qmlproperty enumeration WifiManager::networkState
+
+ This property holds the current state of the network connection.
+
+ \list
+ \li \e WifiManager.Disconnected - Not connected to any network
+ \li \e WifiManager.Authenticating - Verifying password with the network provider
+ \li \e WifiManager.HandshakeFailed - Incorrect password provided
+ \li \e WifiManager.ObtainingIPAddress - Requesting IP address from DHCP server
+ \li \e WifiManager.DhcpRequestFailed - Could not retrieve IP address
+ \li \e WifiManager.Connected - Ready to process network requests
+ \endlist
+*/
+
+/*!
+ \qmlproperty bool WifiManager::backendReady
+
+ This property holds whether or not the backend has been successfully initialized.
+
+ \code
+ WifiManager {
+ id: wifiManager
+ scanning: backendReady
+ }
+
+ Button {
+ id: wifiOnOffButton
+ text: (wifiManager.backendReady) ? "Switch Off" : "Switch On"
+ onClicked: {
+ if (wifiManager.backendReady) {
+ wifiManager.stop()
+ } else {
+ wifiManager.start()
+ }
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty bool WifiManager::scanning
+
+ This property holds whether or not the backend is scanning for WiFi networks. To
+ preserve battery energy, stop scanning for networks once you are done with configuring a network.
+
+ Before starting to scan for networks, you need to initialize the WiFi backend.
+
+ \sa start
+*/
+
+/*!
+ \qmlproperty string WifiManager::connectedSSID
+
+ This property holds the network name.
+*/
+
+/*!
+ \qmlproperty WifiNetworkListModel WifiManager::networks
+
+ This property holds a list of networks that can be sensed by a device. Use the returned
+ model as data model in ListView, model is updated every 5 seconds.
+
+ WifiNetworkListModel is a simple data model consisting of WifiNetwork objects, accessed with
+ the "network" data role. Instances of WifiNetwork cannot be created directly from the QML system.
+
+ \code
+ WifiManager {
+ id: wifiManager
+ scanning: backendReady
+ Component.onCompleted: start()
+ }
+
+ Component {
+ id: listDelegate
+ Rectangle {
+ id: delegateBackground
+ height: 60
+ width: parent.width
+ color: "#5C5C5C"
+ border.color: "black"
+ border.width: 1
+
+ Text {
+ id: ssidLabel
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.margins: 10
+ font.pixelSize: 20
+ font.bold: true
+ color: "#E6E6E6"
+ text: network.ssid
+ }
+
+ Rectangle {
+ width: Math.max(100 + network.signalStrength, 0) / 100 * parent.width;
+ height: 20
+ radius: 10
+ antialiasing: true
+ anchors.margins: 20
+ anchors.right: parent.right
+ anchors.top: parent.top
+ color: "#BF8888"
+ border.color: "#212126"
+ }
+ }
+ }
+
+
+ ListView {
+ id: networkView
+ anchors.fill: parent
+ model: wifiManager.networks
+ delegate: listDelegate
+ }
+ \endcode
+
+*/
+
+/*!
+ \qmlmethod void WifiManager::start()
+
+ Start an initialization of the WiFi backend.
+
+ \sa stop
+ */
+
+/*!
+ \qmlmethod void WifiManager::stop()
+
+ Stop the WiFi backend and shut down all network functionality.
+
+ \sa start
+ */
+
+/*!
+ \qmlmethod void WifiManager::connect(WifiNetwork network, const string passphrase)
+
+ Connect to network \a network and use passphrase \a passphrase for authentication.
+
+ \sa disconnect, networkState
+ */
+
+/*!
+ \qmlmethod void WifiManager::disconnect()
+
+ Disconnect from currently connected network connection.
+
+ \sa connect, networkState
+ */
+
+/*!
+ \qmlsignal void WifiManager::scanningChanged(bool scanning)
+
+ This signal is emitted when device starts or stops to scan for available wifi networks.
+
+ \sa scanning
+
+*/
+
+/*!
+ \qmlsignal void WifiManager::networkStateChanged(WifiNetwork network)
+
+ This signal is emitted whenever changes in a network state occur. Network \a network is the
+ the currently active network connection.
+
+ \sa networkState
+*/
+
+/*!
+ \qmlsignal void WifiManager::backendReadyChanged()
+
+ This signal is emitted when backend has been successfully initialized or shut down.
+
+ \sa start, stop
+*/
+
+/*!
+ \qmlsignal void WifiManager::connectedSSIDChanged(string ssid)
+
+ This signal is emitted when the device has connected to or disconnected from a network.
+ \a ssid contains the name of the connected network, or an empty string if the network was disconnected.
+
+ \sa connect, disconnect
+*/
+
QWifiManager::QWifiManager()
- : m_networks(this)
+ : m_networkListModel(this)
, m_eventThread(0)
, m_scanTimer(0)
, m_scanning(false)
, m_daemonClientSocket(0)
, m_exitingEventThread(false)
+ , m_startingUp(true)
+ , m_network(0)
{
char interface[PROPERTY_VALUE_MAX];
property_get(WIFI_INTERFACE, interface, NULL);
@@ -143,15 +369,15 @@ QWifiManager::QWifiManager()
qWarning() << "QWifiManager: failed to connect to qconnectivity socket";
}
// check if backend has already been initialized
- char backend_status[PROPERTY_VALUE_MAX];
- if (property_get(QT_WIFI_BACKEND, backend_status, NULL)) {
- if (strcmp(backend_status, "running") == 0) {
+ char backendStatus[PROPERTY_VALUE_MAX];
+ if (property_get(QT_WIFI_BACKEND, backendStatus, NULL)) {
+ if (strcmp(backendStatus, "running") == 0) {
// let it re-connect, in most cases this will see that everything is working properly
// and will do nothing. Special case is when process has crashed or was killed by a system
// signal in previous execution, which results in broken connection to a supplicant,
// connectToBackend will fix it..
connectToBackend();
- } else if (strcmp(backend_status, "stopped") == 0) {
+ } else if (strcmp(backendStatus, "stopped") == 0) {
// same here, cleans up the state
disconnectFromBackend();
}
@@ -160,12 +386,7 @@ QWifiManager::QWifiManager()
QWifiManager::~QWifiManager()
{
- // exit event thread if it is running
- if (m_eventThread->isRunning()) {
- m_exitingEventThread = true;
- call("SCAN");
- m_eventThread->wait();
- }
+ exitEventThread();
delete m_eventThread;
delete m_daemonClientSocket;
}
@@ -177,14 +398,12 @@ void QWifiManager::handleDhcpReply()
receivedMessage = m_daemonClientSocket->readLine(m_daemonClientSocket->bytesAvailable());
if (QT_WIFI_DEBUG) qDebug() << "QWifiManager: reply from qconnectivity: " << receivedMessage;
if (receivedMessage == "success") {
- m_state = Connected;
- emit networkStateChanged();
+ updateNetworkState(Connected);
emit connectedSSIDChanged(m_connectedSSID);
// Store settings of a working wifi connection
call("SAVE_CONFIG");
} else if (receivedMessage == "failed") {
- m_state = DhcpRequestFailed;
- emit networkStateChanged();
+ updateNetworkState(DhcpRequestFailed);
} else {
qWarning() << "QWifiManager: unknown message: " << receivedMessage;
}
@@ -210,12 +429,16 @@ void QWifiManager::connectedToDaemon()
void QWifiManager::start()
{
if (QT_WIFI_DEBUG) qDebug("QWifiManager: connecting to the backend");
+ if (m_backendReady)
+ return;
connectToBackend();
}
void QWifiManager::stop()
{
if (QT_WIFI_DEBUG) qDebug("QWifiManager: shutting down");
+ if (!m_backendReady)
+ return;
disconnectFromBackend();
}
@@ -244,15 +467,12 @@ void QWifiManager::connectToBackend()
if (QT_WIFI_DEBUG) qDebug("QWifiManager: started successfully");
m_exitingEventThread = false;
m_eventThread->start();
- handleConnected();
+ call("SCAN");
}
void QWifiManager::disconnectFromBackend()
{
- m_exitingEventThread = true;
- call("SCAN");
- m_eventThread->wait();
-
+ exitEventThread();
if (wifi_stop_supplicant(0) < 0)
qWarning("QWifiManager: failed to stop supplicant");
wifi_close_supplicant_connection(m_interface.constData());
@@ -261,9 +481,18 @@ void QWifiManager::disconnectFromBackend()
emit backendReadyChanged();
}
+void QWifiManager::exitEventThread()
+{
+ if (m_eventThread->isRunning()) {
+ m_exitingEventThread = true;
+ call("SCAN");
+ m_eventThread->wait();
+ }
+}
+
void QWifiManager::setScanning(bool scanning)
{
- if (m_scanning == scanning)
+ if (!m_backendReady || m_scanning == scanning)
return;
m_scanning = scanning;
@@ -299,15 +528,27 @@ bool QWifiManager::checkedCall(const char *command) const
return call(command).trimmed().toUpper() == "OK";
}
+void QWifiManager::updateNetworkState(NetworkState state)
+{
+ m_state = state;
+ if (m_network)
+ emit networkStateChanged(m_network);
+}
+
bool QWifiManager::event(QEvent *e)
{
switch ((int) e->type()) {
case WIFI_SCAN_RESULTS:
- m_networks.parseScanResults(call("SCAN_RESULTS"));
+ m_networkListModel.parseScanResults(call("SCAN_RESULTS"));
+ if (m_startingUp)
+ handleConnected();
return true;
case WIFI_CONNECTED:
handleConnected();
break;
+ case WIFI_HANDSHAKE_FAILED:
+ updateNetworkState(HandshakeFailed);
+ break;
case QEvent::Timer: {
int tid = static_cast<QTimerEvent *>(e)->timerId();
if (tid == m_scanTimer) {
@@ -323,10 +564,13 @@ bool QWifiManager::event(QEvent *e)
void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
{
+ m_network = network;
if (network->ssid() == m_connectedSSID) {
- if (QT_WIFI_DEBUG) qDebug("QWifiManager::connect(), already connected to %s", network->ssid().constData());
+ if (QT_WIFI_DEBUG)
+ qDebug("QWifiManager::connect(), already connected to %s", network->ssid().constData());
return;
}
+ updateNetworkState(Authenticating);
call("DISABLE_NETWORK all");
if (!m_connectedSSID.isEmpty()) {
@@ -334,16 +578,13 @@ void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
emit connectedSSIDChanged(m_connectedSSID);
}
- m_state = ObtainingIPAddress;
- emit networkStateChanged();
bool networkKnown = false;
QByteArray id;
QByteArray listResult = call("LIST_NETWORKS");
QList<QByteArray> lines = listResult.split('\n');
foreach (const QByteArray &line, lines) {
if (line.contains(network->ssid())) {
- int networkId = line.toInt();
- id = QByteArray::number(networkId);
+ id = line.split('\t').at(0);
networkKnown = true;
break;
}
@@ -351,7 +592,7 @@ void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
if (!networkKnown) {
bool ok;
- QByteArray id = call("ADD_NETWORK").trimmed();
+ id = call("ADD_NETWORK").trimmed();
id.toInt(&ok);
if (!ok) {
qWarning("QWifiManager::connect(), failed to add network");
@@ -394,9 +635,8 @@ void QWifiManager::disconnect()
call("DISCONNECT");
QByteArray req = m_interface;
sendDhcpRequest(req.append(" disconnect"));
- m_state = Disconnected;
m_connectedSSID.clear();
- emit networkStateChanged();
+ updateNetworkState(Disconnected);
emit connectedSSIDChanged(m_connectedSSID);
}
@@ -404,7 +644,7 @@ void QWifiManager::handleConnected()
{
QList<QByteArray> lists = call("LIST_NETWORKS").split('\n');
QByteArray connectedNetwork;
- for (int i=1; i<lists.size(); ++i) {
+ for (int i = 1; i < lists.size(); ++i) {
if (lists.at(i).toUpper().contains("[CURRENT]")) {
connectedNetwork = lists.at(i);
break;
@@ -413,8 +653,6 @@ void QWifiManager::handleConnected()
if (connectedNetwork.isEmpty()) {
if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: not connected to a network...");
- m_state = Disconnected;
- emit networkStateChanged();
return;
}
@@ -423,6 +661,15 @@ void QWifiManager::handleConnected()
QList<QByteArray> info = connectedNetwork.split('\t');
m_connectedSSID = info.at(1);
+ if (m_startingUp) {
+ m_startingUp = false;
+ if (!m_network) {
+ int pos = 0; // unused
+ m_network = m_networkListModel.networkForSSID(info.at(1), &pos);
+ }
+ }
+
+ updateNetworkState(ObtainingIPAddress);
QByteArray req = m_interface;
sendDhcpRequest(req.append(" connect"));
}
diff --git a/src/imports/wifi/qwifimanager.h b/src/imports/wifi/qwifimanager.h
index 432f411..162190e 100644
--- a/src/imports/wifi/qwifimanager.h
+++ b/src/imports/wifi/qwifimanager.h
@@ -25,7 +25,7 @@
#include <cutils/properties.h>
-#include "qwifinetworklist.h"
+#include "qwifinetworklistmodel.h"
class QWifiManagerEventThread;
@@ -37,11 +37,13 @@ class QWifiManager : public QObject
Q_PROPERTY(bool backendReady READ isbackendReady NOTIFY backendReadyChanged)
Q_PROPERTY(bool scanning READ scanning WRITE setScanning NOTIFY scanningChanged)
Q_PROPERTY(QString connectedSSID READ connectedSSID NOTIFY connectedSSIDChanged)
- Q_PROPERTY(QWifiNetworkList *networks READ networks CONSTANT)
+ Q_PROPERTY(QWifiNetworkListModel *networks READ networks CONSTANT)
public:
enum NetworkState {
Disconnected,
+ Authenticating,
+ HandshakeFailed,
ObtainingIPAddress,
DhcpRequestFailed,
Connected
@@ -50,7 +52,7 @@ public:
QWifiManager();
~QWifiManager();
- QWifiNetworkList *networks() { return &m_networks; }
+ QWifiNetworkListModel *networks() { return &m_networkListModel; }
QString connectedSSID() const { return m_connectedSSID; }
bool scanning() const { return m_scanning; }
void setScanning(bool scanning);
@@ -65,10 +67,10 @@ public slots:
void disconnect();
signals:
- void scanningChanged(bool arg);
- void networkStateChanged();
+ void scanningChanged(bool scanning);
+ void networkStateChanged(QWifiNetwork *network);
void backendReadyChanged();
- void connectedSSIDChanged(const QString &);
+ void connectedSSIDChanged(const QString &ssid);
protected:
bool event(QEvent *);
@@ -76,8 +78,10 @@ protected:
void handleConnected();
void connectToBackend();
void disconnectFromBackend();
+ void exitEventThread();
QByteArray call(const char *command) const;
bool checkedCall(const char *command) const;
+ void updateNetworkState(NetworkState state);
protected slots:
void connectedToDaemon();
@@ -87,7 +91,7 @@ private:
friend class QWifiManagerEventThread;
QString m_connectedSSID;
- QWifiNetworkList m_networks;
+ QWifiNetworkListModel m_networkListModel;
QWifiManagerEventThread *m_eventThread;
int m_scanTimer;
@@ -99,6 +103,8 @@ private:
QLocalSocket *m_daemonClientSocket;
QByteArray m_request;
bool m_exitingEventThread;
+ bool m_startingUp;
+ QWifiNetwork *m_network;
};
#endif // QWIFIMANAGER_H
diff --git a/src/imports/wifi/qwifinetwork.cpp b/src/imports/wifi/qwifinetwork.cpp
index a159e59..d4c20ef 100644
--- a/src/imports/wifi/qwifinetwork.cpp
+++ b/src/imports/wifi/qwifinetwork.cpp
@@ -18,7 +18,73 @@
****************************************************************************/
#include "qwifinetwork.h"
-QWifiNetwork::QWifiNetwork()
+/*!
+ \qmltype WifiNetwork
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief Represents a single WiFi network access point.
+
+ Instances of WifiNetwork cannot be created directly from the QML system, use
+ WifiManager::networks.
+*/
+
+/*!
+ \qmlproperty string WifiNetwork::bssid
+
+ This property holds basic service set identification of a network, used to uniquely
+ identify BSS.
+
+*/
+
+/*!
+ \qmlproperty string WifiNetwork::ssid
+
+ This property holds a network name. The SSID is the informal (human) name of BSS.
+*/
+
+/*!
+ \qmlproperty int WifiNetwork::signalStrength
+
+ This property holds the current strength of a WiFi signal, measured in dBm. New readings are
+ taken every 5 seconds.
+
+ \sa signalStrengthChanged
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPA
+
+ This property holds whether network access point supports WPA security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPA2
+
+ This property holds whether network access point supports WPA2 security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWEP
+
+ This property holds whether network access point supports WEP security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPS
+
+ This property holds whether network access point supports WPS security protocol.
+*/
+
+/*!
+ \qmlsignal void WifiNetwork::signalStrengthChanged(int strength)
+
+ This signal is emitted whenever signal strength has changed comparing the the
+ previous reading, the new signal's strength is \a strength.
+
+*/
+
+QWifiNetwork::QWifiNetwork() :
+ m_outOfRange(false)
{
}
@@ -29,3 +95,10 @@ void QWifiNetwork::setSignalStrength(int strength)
m_signalStrength = strength;
emit signalStrengthChanged(m_signalStrength);
}
+
+void QWifiNetwork::setOutOfRange(bool outOfRange)
+{
+ if (m_outOfRange == outOfRange)
+ return;
+ m_outOfRange = outOfRange;
+}
diff --git a/src/imports/wifi/qwifinetwork.h b/src/imports/wifi/qwifinetwork.h
index 780fc87..5ecc6a3 100644
--- a/src/imports/wifi/qwifinetwork.h
+++ b/src/imports/wifi/qwifinetwork.h
@@ -22,8 +22,6 @@
#include <QtCore/QByteArray>
#include <QtCore/QObject>
-class QWifiManager;
-
class QWifiNetwork : public QObject
{
Q_OBJECT
@@ -48,6 +46,9 @@ public:
int signalStrength() const { return m_signalStrength; }
void setSignalStrength(int strength);
+ void setOutOfRange(bool outOfRange);
+ bool outOfRange() { return m_outOfRange; }
+
QByteArray flags() const { return m_flags; }
void setFlags(const QByteArray &f) { m_flags = f; }
bool supportsWPA2() const { return m_flags.contains("WPA2"); }
@@ -56,7 +57,7 @@ public:
bool supportsWPS() const { return m_flags.contains("WPS"); }
signals:
- void signalStrengthChanged(int arg);
+ void signalStrengthChanged(int strength);
private:
QByteArray m_bssid;
@@ -64,6 +65,7 @@ private:
int m_signalStrength;
QByteArray m_flags;
+ bool m_outOfRange;
};
#endif // QWIFINETWORK_H
diff --git a/src/imports/wifi/qwifinetworklist.cpp b/src/imports/wifi/qwifinetworklistmodel.cpp
index 60fdc53..4fbf25f 100644
--- a/src/imports/wifi/qwifinetworklist.cpp
+++ b/src/imports/wifi/qwifinetworklistmodel.cpp
@@ -16,55 +16,47 @@
** the contact form at http://qt.digia.com/
**
****************************************************************************/
-#include "qwifinetworklist.h"
+#include "qwifinetworklistmodel.h"
#include <QtCore>
-const int ID_BSSID = (Qt::ItemDataRole) (Qt::UserRole + 1);
-const int ID_SSID = (Qt::ItemDataRole) (Qt::UserRole + 2);
-const int ID_SIGNAL = (Qt::ItemDataRole) (Qt::UserRole + 3);
-const int ID_WPA2 = (Qt::ItemDataRole) (Qt::UserRole + 4);
-const int ID_WPA = (Qt::ItemDataRole) (Qt::UserRole + 5);
-const int ID_NETWORK = (Qt::ItemDataRole) (Qt::UserRole + 6);
+const int ID_NETWORK = (Qt::ItemDataRole) (Qt::UserRole + 1);
-QWifiNetworkList::QWifiNetworkList(QWifiManager *manager)
+QWifiNetworkListModel::QWifiNetworkListModel(QWifiManager *manager)
: m_manager(manager)
{
}
-QHash<int, QByteArray> QWifiNetworkList::roleNames() const
+QWifiNetworkListModel::~QWifiNetworkListModel()
+{
+ qDeleteAll(m_networks);
+ qDeleteAll(m_outOfRangeNetworks);
+ m_networks.clear();
+ m_outOfRangeNetworks.clear();
+}
+
+QHash<int, QByteArray> QWifiNetworkListModel::roleNames() const
{
QHash<int, QByteArray> names;
- names.insert(ID_BSSID, "bssid");
- names.insert(ID_SSID, "ssid");
- names.insert(ID_SIGNAL, "strength");
- names.insert(ID_WPA2, "wpa2");
- names.insert(ID_WPA, "wpa");
names.insert(ID_NETWORK, "network");
return names;
}
-QVariant QWifiNetworkList::data(const QModelIndex &index, int role) const
+QVariant QWifiNetworkListModel::data(const QModelIndex &index, int role) const
{
QWifiNetwork *n = m_networks.at(index.row());
-
switch (role) {
- case ID_BSSID: return n->bssid();
- case ID_SSID: return n->ssid();
- case ID_SIGNAL: return n->signalStrength();
- case ID_WPA2: return n->supportsWPA2();
- case ID_WPA: return n->supportsWPA();
- case ID_NETWORK: return QVariant::fromValue((QObject *) n);
+ case ID_NETWORK: return QVariant::fromValue((QObject *) n);
}
- qWarning("QWifiNetworkList::data(), undefined role: %d\n", role);
+ qWarning("QWifiNetworkListModel::data(), undefined role: %d\n", role);
return QVariant();
}
-QWifiNetwork *QWifiNetworkList::networkForSSID(const QByteArray &ssid, int *pos)
+QWifiNetwork *QWifiNetworkListModel::networkForSSID(const QByteArray &ssid, int *pos)
{
- for (int i=0; i<m_networks.size(); ++i) {
+ for (int i = 0; i < m_networks.size(); ++i) {
if (m_networks.at(i)->ssid() == ssid) {
if (pos)
*pos = i;
@@ -74,21 +66,32 @@ QWifiNetwork *QWifiNetworkList::networkForSSID(const QByteArray &ssid, int *pos)
return 0;
}
-void QWifiNetworkList::parseScanResults(const QByteArray &results)
+QWifiNetwork *QWifiNetworkListModel::outOfRangeListContains(const QByteArray &ssid)
{
- QList<QByteArray> lines = results.split('\n');
+ for (int i = 0; i < m_outOfRangeNetworks.length(); ++i)
+ if (m_outOfRangeNetworks.at(i)->ssid() == ssid)
+ return m_outOfRangeNetworks.takeAt(i);
+ return 0;
+}
+void QWifiNetworkListModel::parseScanResults(const QByteArray &results)
+{
+ QList<QByteArray> lines = results.split('\n');
QSet<QByteArray> sensibleNetworks;
- for (int i=1; i<lines.size(); ++i) {
+
+ for (int i = 1; i < lines.size(); ++i) {
QList<QByteArray> info = lines.at(i).split('\t');
if (info.size() < 5 || info.at(4).isEmpty() || info.at(0).isEmpty())
continue;
int pos = 0;
- if (!sensibleNetworks.contains(info.at(4)))
- sensibleNetworks.insert(info.at(4));
- QWifiNetwork *existingNetwork = networkForSSID(info.at(4), &pos);
- if (!existingNetwork) {
+ sensibleNetworks.insert(info.at(4));
+ QWifiNetwork *knownNetwork = networkForSSID(info.at(4), &pos);
+ if (!knownNetwork)
+ knownNetwork = outOfRangeListContains(info.at(4));
+
+ if (!knownNetwork) {
QWifiNetwork *network = new QWifiNetwork();
+ network->setOutOfRange(false);
network->setBssid(info.at(0));
network->setFlags(info.at(3));
// signal strength is in dBm
@@ -98,13 +101,23 @@ void QWifiNetworkList::parseScanResults(const QByteArray &results)
m_networks << network;
endInsertRows();
} else {
+ if (knownNetwork->outOfRange()) {
+ // known network has come back into a range
+ knownNetwork->setOutOfRange(false);
+ beginInsertRows(QModelIndex(), m_networks.size(), m_networks.size());
+ m_networks << knownNetwork;
+ endInsertRows();
+ pos = m_networks.length() - 1;
+ }
// ssids are the same, compare bssids..
- if (existingNetwork->bssid() == info.at(0)) {
+ if (knownNetwork->bssid() == info.at(0)) {
// same access point, simply update the signal strength
- existingNetwork->setSignalStrength(info.at(2).toInt());
+ knownNetwork->setSignalStrength(info.at(2).toInt());
+ knownNetwork->setOutOfRange(false);
dataChanged(createIndex(pos, 0), createIndex(pos, 0));
- } else if (existingNetwork->signalStrength() < info.at(2).toInt()) {
+ } else if (knownNetwork->signalStrength() < info.at(2).toInt()) {
// replace with a stronger access point within the same network
+ m_networks.at(pos)->setOutOfRange(false);
m_networks.at(pos)->setBssid(info.at(0));
m_networks.at(pos)->setFlags(info.at(3));
m_networks.at(pos)->setSignalStrength(info.at(2).toInt());
@@ -113,16 +126,16 @@ void QWifiNetworkList::parseScanResults(const QByteArray &results)
}
}
}
- // remove networks that have gone out of range
- for (int i = 0; i < m_networks.size(); ++i) {
+ // remove out-of-range networks from the data model
+ for (int i = 0; i < m_networks.size();) {
if (!sensibleNetworks.contains(m_networks.at(i)->ssid())) {
beginRemoveRows(QModelIndex(), i, i);
- delete m_networks.takeAt(i);
+ QWifiNetwork *n = m_networks.takeAt(i);
+ n->setOutOfRange(true);
+ m_outOfRangeNetworks.append(n);
endRemoveRows();
} else {
++i;
}
}
}
-
-
diff --git a/src/imports/wifi/qwifinetworklist.h b/src/imports/wifi/qwifinetworklistmodel.h
index 84e78fc..91ca231 100644
--- a/src/imports/wifi/qwifinetworklist.h
+++ b/src/imports/wifi/qwifinetworklistmodel.h
@@ -16,8 +16,8 @@
** the contact form at http://qt.digia.com/
**
****************************************************************************/
-#ifndef QWIFINETWORKLIST_H
-#define QWIFINETWORKLIST_H
+#ifndef QWIFINETWORKLISTMODEL_H
+#define QWIFINETWORKLISTMODEL_H
#include <QtCore/QAbstractListModel>
#include <QtCore/QList>
@@ -26,17 +26,19 @@
class QWifiManager;
-class QWifiNetworkList : public QAbstractListModel
+class QWifiNetworkListModel : public QAbstractListModel
{
Q_OBJECT
public:
- QWifiNetworkList(QWifiManager *manager);
+ QWifiNetworkListModel(QWifiManager *manager);
+ ~QWifiNetworkListModel();
void parseScanResults(const QByteArray &data);
QWifiNetwork *networkForSSID(const QByteArray &ssid, int *pos);
+ QWifiNetwork *outOfRangeListContains(const QByteArray &ssid);
int rowCount(const QModelIndex &) const { return m_networks.size(); }
QVariant data(const QModelIndex &index, int role) const;
@@ -46,6 +48,7 @@ public:
private:
QWifiManager *m_manager;
QList<QWifiNetwork *> m_networks;
+ QList<QWifiNetwork *> m_outOfRangeNetworks;
};
-#endif // QWIFINETWORKLIST_H
+#endif // QWIFINETWORKLISTMODEL_H
diff --git a/src/imports/wifi/wifi.pro b/src/imports/wifi/wifi.pro
index 0231479..b920978 100644
--- a/src/imports/wifi/wifi.pro
+++ b/src/imports/wifi/wifi.pro
@@ -8,12 +8,12 @@ SOURCES += \
pluginmain.cpp \
qwifimanager.cpp \
qwifinetwork.cpp \
- qwifinetworklist.cpp
+ qwifinetworklistmodel.cpp
HEADERS += \
qwifimanager.h \
qwifinetwork.h \
- qwifinetworklist.h
+ qwifinetworklistmodel.h
LIBS += -lhardware_legacy -lcutils