summaryrefslogtreecommitdiffstats
path: root/src/bluetooth
Commit message (Collapse)AuthorAgeFilesLines
* QBluetoothDeviceDiscoveryAgent - timeout on OS X/iOSTimur Pocheptsov2014-12-051-1/+1
| | | | | | | | On OS X we have to first make Classic device scan and then LE device scan. Shorten Classic discovery from 20s to 15s. Change-Id: I653b2d9f6c911bdf09c900735273bd6d1e95b078 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Provide user visible strings/translations for new BTLE uuidsAlex Blasche2014-12-051-1/+81
| | | | | | Change-Id: I02e4b3518c57e120d46fdcc427663a5910e01a97 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Add new environmental sensing descriptor typesAlex Blasche2014-12-052-2/+16
| | | | | | Change-Id: Id0ed9503da1cff66a04a83196cf61863289b98ab Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Add newly adopted BTLE service/characteristic type uuidsAlex Blasche2014-12-052-11/+191
| | | | | | Change-Id: I57eff858c2e5700ac814d24fb173c269ebff5fd3 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Client characteristic configuration (OS X and iOS)Timur Pocheptsov2014-12-052-2/+10
| | | | | | | | If client characteristic configuration descriptor has an indication/notification bit set - enable ("automatically" == no explicit user's request) notifications. Change-Id: I839aabd6f5513141f66c8e4467618b3edd523350 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Update supported platforms and feature in QtBluetoothAlex Blasche2014-12-052-17/+8
| | | | | | | | | The Low Energy API is final from Qt 5.5 onwards and OSX and iOS are platform additions. Change-Id: I73f18b3169c5e1438af4d90c6655eabb515e0d39 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* QLowEnergyCharacteristic - cached values (OS X and iOS)Timur Pocheptsov2014-12-041-2/+6
| | | | | | | | Cache a characteristic's value in update/write notification only if characteristic has a 'Read' property. Change-Id: Idc705e0c4f2ee704a80bf37b4e59e1dd09ca9e4f Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Low energy descriptor - value on iOSTimur Pocheptsov2014-12-042-0/+59
| | | | | | | | On OS X CBDescriptor's value is always NSData, on iOS it can be NSData, NSString, NSNumber. Change-Id: I6ffa4b813238ec26759508a012fa6e236db04c63 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Don't update cached char value when property is not readableAlex Blasche2014-12-043-5/+22
| | | | | | | | | In addition we update the documentation to reflect the slightly changed API behavior. Change-Id: Ieddee750aa35a32d3c01213dfbf678ee2a1d88d7 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Android: enable writing of characteristics without response modeAlex Blasche2014-12-041-4/+6
| | | | | | Change-Id: I9c26aaa11857db8dc33a99d42347a9b7f6281ad7 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* QLowEnergyController/Service - enable for iOSTimur Pocheptsov2014-12-032-3/+13
| | | | | | | Enable Core Bluetooth-based version for iOS. Change-Id: Ica13fdc6c01744713483771e7c8ad6153c9fccdf Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Bluez: Do not update char value() if char is non-readableAlex Blasche2014-12-031-3/+6
| | | | | | Change-Id: Ia075bfb4174c7a2b90376b215f3366076d9ae1c9 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* QBluetoothLocalDevice - isValid, tests (OS X and iOS)Timur Pocheptsov2014-12-031-5/+1
| | | | | | | | | | | Cancel the previous modification - even if BT is off, the device is valid unless we create it with some address (in the 'OFF' state I can not verify any address and the device is considered invalid). Enable (back) auto-test - if BT is off we just skip the test (as it's done in other test functions). Change-Id: I8b013af6a73eab9699a91834e197716836b00e78 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* Merge "Merge remote-tracking branch 'origin/5.4' into dev" into refs/staging/devAlex Blasche2014-12-036-2/+23
|\
| * Merge remote-tracking branch 'origin/5.4' into devFrederik Gladhorn2014-11-276-2/+23
| |\ | | | | | | | | | Change-Id: I6c1eabeea1b3397803e285d13cef147220ff5aa4
| | * Reset the controller's internal state when disconnectingAlex Blasche2014-11-233-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This caused problems when disconnecting from the remote device while an openrequest was pending and if the controller tried to reconnect immediately afterwards. The pending request queue was blocked forever. Change-Id: I444d5ac6763b65ec8baf687e0dccec4b28016a6c Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
| | * Merge remote-tracking branch 'origin/5.4.0' into 5.4Frederik Gladhorn2014-11-213-2/+9
| | |\ | | | | | | | | | | | | Change-Id: Ib79fe0b33b405cdf6fee87f97f6ebb86bb79d976
| | | * Add missing \since tags for new API introduced by Qt 5.4.Alex Blasche2014-11-133-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | Change-Id: Ie51d6e549d80baae57864d4e0d43a1c58897f149 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Topi Reiniƶ <topi.reinio@digia.com>
* | | | QLowEnergyService - ClientCharacteristicConfigurationTimur Pocheptsov2014-12-035-36/+238
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Core Bluetooth has a special method to enable/disable char update notifications and even more - Core Bluetooth does not allow to use writeValue:forDescriptor: with ClientCharacteristicConfiguration - that's why need this 'workaround'. Change-Id: I4a01690a76aabf62397321ca6ba22c4abb1c420c Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | QBluetoothLocalDevice - bug on OS X (isValid)Timur Pocheptsov2014-12-011-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If BT adapter is off local device is invalid on OS X: no way to access information like address/name, no way to turn the device on, all operations fail. Considering it's valid breaks the logic: you can pass any address to such a device (invalid non-null address) and device can not check if it's valid or not. Change-Id: I25f70723d566d4de8f993fc9c9a9e6867f936b7f Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | QLowEnergyController - service state (OS X/iOS)Timur Pocheptsov2014-12-011-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix a bug - call setState on a service instead of stateChanged (which is just a signal not actually chanding the service's state). Change-Id: I243f1f6c6775a5592357a443a2f180e4afcf8219 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | QLowEnergyController - concurrent characteristic writesTimur Pocheptsov2014-12-015-78/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Qt's API assumes that several write operations must be serialized (this is not guaranteed with Core Bluetooth AFAIK). I can enqueu only write with response operations, otherwise I never know when to do the next write. Change-Id: Iaa83514748358437e2c39335ab142d084ff197e3 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | QLowEnergyController - writeDescriptor (OS X/iOS)Timur Pocheptsov2014-12-016-29/+241
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Core Bluetooth - based implementation. Change-Id: Ie642a13ae9a4d75401dd10648fac6eeee4123a3b Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | Update QLEService::Type() documentation for Android specificsAlex Blasche2014-12-011-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Android doesn't expose the required API elements to set the correct service type. Therefore all services are by definition primary services too. Change-Id: Ifae4a1baa856382d481ab377b98f05b5b9974a85 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | Android: Implements QLEService::includedServices() and type()Alex Blasche2014-12-011-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Unfortunately it is not possible to say whether a service is primary or secondary on Android. The platform doesn't expose this information. Change-Id: I9b0aad191308120d2d1992a5e7736b985a375e30 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | | Bluetooth LE - handles/chars/descriptors/services (OS X and iOS)Timur Pocheptsov2014-12-014-108/+165
|/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In Qt we work with handles (real for Bluez, emulated for Android/iOS/OS X). Core Bluetooth has its own (quite primitive and inconvenient) data structures (arrays of objects, containing nested arrays). To make things not so ugly I'm adding several maps to be able to find a characteristic/descriptor/service using a handle from Qt's layer. Also modify writeCharacteristic to use this new 'addressing scheme'. Change-Id: Ic822c9aa82a4df1e9c4cf4c673451cac8006b9ba Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | Fix missing update of cached characteristic valueAlex Blasche2014-11-261-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we receive a characteristic update we have to update the cached value on the Qt side. This was accidentally missed during an earlier commit. Change-Id: I0f84e35ee44e38d1e46b7ddcd4e78b7e216e49d5 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | QLowEnergyService::writeCharacteristic - implementation for OS X and iOSTimur Pocheptsov2014-11-268-15/+468
| | | | | | | | | | | | | | | | | | | | | writeCharacteristic - implemented with Core Bluetooth for OS X and iOS. Change-Id: Ia228ff451e1e6d7b6fb7de6cad29198aa9257602 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | Document Android's caching of BTLE service data.Alex Blasche2014-11-261-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | It can be confusing. As more platforms are supported, this behavior needs to be verified too. The Bluez implementation does not exhibit this cache behavior. Change-Id: I42dd003f2ac2632c32e48b1b1784e4ca529950f3 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | QLowEnergyController - service details discovery (OS X and iOS)Timur Pocheptsov2014-11-256-15/+588
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implement details discovery: characteristics, their values (if any), descriptors. We have to emulate handles (QLowEnergyHandle) - while Core Bluetooth internally has the notion of handles, it never exposes them as a public API. Change-Id: I09158433ce6835dd34fe8ad47d047212dab59e8e Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | QLowEnergyService - primary/secondary (OS X and iOS)Timur Pocheptsov2014-11-251-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | It looks like isPrimary property is always 'NO' on CBService objects discovered making this property ... hmm, TOTALLY USELESS? Change-Id: Ia38323c204e6cf1c3def3bbb3deb08bb8cdf90e4 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | Android: characteristic changed notification supportAlex Blasche2014-11-245-0/+49
| | | | | | | | | | | | | | | | | | Change-Id: I4c50df7d758390989c2e2127f7646e5d2dc34712 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | QLowEnergyController - service discovery (OS X and iOS)Timur Pocheptsov2014-11-245-93/+330
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The initial version of service discovery failed to discover included services correctly, actually this discovery requires some kind of 'graph traversal' on the services tree. This patch re-implements the service discovery, discovering included services also and avoiding ... loops in services referencing each other (if it ever happens :) ) Change-Id: I60c6122fa5ddb922c21c99dd12024879cffad334 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | QLowEnergyController - connectTo/disconnectFromDevice (OS X, iOS)Timur Pocheptsov2014-11-242-8/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fix for disconnectFromDevice. It can happen that connect requesting is pending forever and not reporting any error: there is no timeout in Core Bluetooth (quite reasonable), a device (after it was found by LE scan) can be turned off or move out of range before connected. If a user calls disconnectFromDevice on a controller during this time: - we still have to call cancelPeripheralConnection to make sure the pending connection never succeeds - we have to set the controller's state to unconnected, since, unfortunately, delegate's callback is not guaranteed to work (descipe of Apple's docs promising this behavior). Fix for connectToDevice - small typo was breaking connectToDevice's logic. Change-Id: I4040c79a37ff31ecb5fb2296fa0d39b81d26393d Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | Workaround Android when connecting to non-existing/turned off deviceAlex Blasche2014-11-231-1/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In such cases a disconnect() call never receives a system callback that BluetoothGatt is disconnected. Similarly when the timeout hits the platform sends an unknown error code 133 and again doesn't send a disconnected status. This patch works around both issues by preempting the platform behavior. It seems that subsequent connect attempts are not harmed by this. Change-Id: I14326c9169f8c1cbbe8aa11de62ca807e79f4975 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | | Merge remote-tracking branch 'origin/5.4' into devFrederik Gladhorn2014-11-212-3/+4
|\| | | | | | | | | | | Change-Id: Ie8293c006bb74cdf324073044a0c622d44651324
| * | More clearly specify the Linux and Bluez version for BTLE supportAlex Blasche2014-11-131-2/+1
| | | | | | | | | | | | | | | | | | Change-Id: If62bce8794855b8865e02ed87ec3faac80bfc3bd Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
| * | Fix QLEController::connectToDevice() documentationAlex Blasche2014-11-111-1/+3
| |/ | | | | | | | | | | | | | | A logical condition was inverted. Change-Id: Ia7b54fe75a8cea4275e3c92c6283bc12f3423b64 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Document and test concurrent write requestsAlex Blasche2014-11-141-1/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | BTLE communication is serialised. However the Qt API provides the ability to issue multiple write requests while the first is still pending. The backend must enqueue the requests for later on. This behavior was already indirectly tests by a unit test but this patch adds an explicit test section for it and documents the behavior. Change-Id: I089b52940820bf0ba9c3ec872a6f1d5d6bd78a0e Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Fix wrong error signal emision on writeCharacteristic() on AndroidAlex Blasche2014-11-141-2/+1
| | | | | | | | | | | | | | | | | | | | | | There is no need to go around the event loop. Furthermore there is no signal "void error(QLEHandle)" in QLEService. The signal is void error(QLEService::ServiceError) Change-Id: I53e9eb9b82cff38b15edab524329fa98206ab27b Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Support for QLEService::writeDescriptor() on AndroidAlex Blasche2014-11-145-6/+91
| | | | | | | | | | | | Change-Id: I1c7f0491506c6f0512d097a419660c5f5e7fb144 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | QLowEnergyController - service discovery (OS X, iOS)Timur Pocheptsov2014-11-134-12/+114
| | | | | | | | | | | | | | | | | | | | | | Implement discoverServices and delegate's methods to work with a service discovery on a peripheral. - CBUUID (it's internal data) can be only 2 bytes long (16-bit shortened UUID) despite of the docs saying 'CBUUID is a 16-bit UUID'. - property 'isPrimary' did not exist prior to 10.9 SDK (OS X). Change-Id: If692d147c0479ed69a331514617e3ef2a986cdf4 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Fix intermittent failure when mapping handles to servicesAlex Blasche2014-11-122-1/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | startHandle and endHandle were randomly initialized and thus QLowEnergyControllerPrivate::serviceForHandle(..) failed at the same rate. In addition this adds a few debug logs which turned out useful when debugging the above issue. Change-Id: I41b65274213a66fa100d8c69bba02be0bb876b65 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Support for QLEService::writeCharacteristic() on AndroidAlex Blasche2014-11-125-3/+93
| | | | | | | | | | | | | | | | Currently only the WriteWithResponse mode works and has been tested. Change-Id: I7947b67f737f5878a01704c09d3a9a532a41b820 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | QLowEnergyController - connectTo/disconnectFrom/Device (OS X, iOS)Timur Pocheptsov2014-11-125-8/+780
| | | | | | | | | | | | | | | | | | | | | | | | | | Implement connect to device/disconnect from device methods, add CentralManager class dealing with CBCentralManager (with additional external logic). - Improve error handling while in 'connecting' state. - Use the proper error (ConnectionError) instead of UnknownError + make the error handling more uniform while isConnecting == true. - Use isNull on QBluetoothUuid, no need in ugly 'hasUuid'. Change-Id: I84a704a746b4677ccb870b9c132db5f7359030c6 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | QLowEnergyController - version for OS X and iOSTimur Pocheptsov2014-11-125-2/+452
| | | | | | | | | | | | | | | | | | | | | | QLowEnergyController/Private for OS X and iOS. This patch contains dummy empty classes required. While LE controller is not fully implemented, I have to disable (marking as insignificant) auto test on this class, otherwise changing the (empty) class to pass the test adds more problem. Change-Id: I54f764f7f6468b1acf58e80555ae454922de9f3b Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Improve reliability of QLEController connect()/disconnect()/connect()Alex Blasche2014-11-121-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Quick disconnecting and reconnecting caused some bugs and revealed some unreliabe API behavior on Android. The internal data structures were never cleaned up when disconnecting from the remote device. If multiple QLEService objects of the same QLEController instance requested a service discovery, every request but the first failed. This was fixed by queueing up the service discovery requests. Last but not least, reusing the same BluetoothGatt instance for the reconnect is very error prone. It may well be caused by Android API bugs. The reconnect would sometimes fail or toggle the connect/disconnect flag a couple of times which is not a problem for the Qt API itself but the stability of the related unit test (see tst_QLowEnergyController::tst_concurrentDiscovery()). Therefore we won't reuse the same BluetoothGatt instance but rather request a new one. Change-Id: I314f2a30960284b9bcd4926f4944c415a6d75788 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Fixes for QLowEnergyController unit test on AndroidAlex Blasche2014-11-111-4/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | It turns out mutliple connections to the sam remote device are possible. The limitations on Linux are implementation specific. We lift the general API limitation and document the insufficient behavior on Linux. A bug has been filed to track this limitation. On Android, unit tests require widgets support to run as we need a QGuiApplication. Change-Id: I37c487246ea6115d3441ca91a920279adbdf726e Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | Avoid one large memory allocation per read descriptor/characteristicAlex Blasche2014-11-111-16/+6
| | | | | | | | | | | | | | | | | | We directly allocate into the QByteArray which continues to manage the memory for us. Change-Id: I39cd314a3cc9fcfd6bcf28836e0222d6d9a4f04f Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
* | The service->characteristic->descriptor tree becomes available in QtAlex Blasche2014-11-115-23/+121
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | At the same time this fixes bugs the following bugs: 1.) Non-readable characteristics were not visible 2.) Crashes when descriptor/characteristic values were empty 3.) QLEService::discoverServiceDetails always finished with an UnknownError Missing/incorrect are still service details such as included services and the service type (which currently always defaults to primary service). Change-Id: Id73013a3784cd3c3f632102f13f5459ab37e95a6 Reviewed-by: Timur Pocheptsov <Timur.Pocheptsov@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>