Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DiscoveredCharacteristic.h Source File

DiscoveredCharacteristic.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef MBED_DISCOVERED_CHARACTERISTIC_H__
00018 #define MBED_DISCOVERED_CHARACTERISTIC_H__
00019 
00020 #include "UUID.h "
00021 #include "Gap.h"
00022 #include "GattAttribute.h"
00023 #include "GattClient.h"
00024 #include "CharacteristicDescriptorDiscovery.h"
00025 #include "DiscoveredCharacteristicDescriptor.h"
00026 
00027 /**
00028  * @addtogroup ble
00029  * @{
00030  * @addtogroup gatt
00031  * @{
00032  * @addtogroup client
00033  * @{
00034  */
00035 
00036 /**
00037  * Representation of a characteristic discovered.
00038  *
00039  * The GattClient discovery procedure initiated with
00040  * GattClient::launchServiceDiscovery() generates instances of this class.
00041  *
00042  * It exposes the main attributes of the discovered characteristic:
00043  *   - The UUID of the characteristic, it can be retrieved by a call to the
00044  *     function getUUID(). This UUID is the type of the characteristic.
00045  *   - Attribute Handles of the characteristic are present as the triplet
00046  *     declaration handle, value handle and last handle. The value handle is
00047  *     used to read or write the content of the characteristic.
00048  *   - The properties contain the set of operations the characteristic can
00049  *     handle, for instance being read or written.
00050  *
00051  * It important to note that the value of the characteristic - if it is
00052  * accessible - is not fetched at discovery time.
00053  *
00054  * The main operations the class offers are reading, writing and discovering
00055  * the descriptors of the characteristic discovered.
00056  *
00057  * Reading a discovered characteristic can be accomplished in two different
00058  * fashions:
00059  *
00060  * If the user has a callback registered for the data read operation in the
00061  * GattClient, then a call to the read(uint16_t) function will initiate a read of
00062  * the characteristic. Results of the operation will be pass on the callback
00063  * registered by GattClient::onDataRead(), which processes all the responses to
00064  * read requests. The read request for a given characteristic can be identified
00065  * by the connection handle and the attribute handle, which are present in
00066  * GattReadCallbackParams.
00067  *
00068  * Another overload (read(uint16_t, const GattClient::ReadCallback_t&)) of the
00069  * read function accepts a completion callback as a last parameter. That
00070  * completion callback will be invoked automatically once the response to the
00071  * read request for that given characteristic has been received. However,
00072  * convenience came at the expense of dynamic memory usage for the time of the
00073  * transaction.
00074  *
00075  * Similarly, two versions of the write() API are exposed. One where the user
00076  * has to register a callback handling write response through the function
00077  * GattClient::onDataWritten() and another one that accepts a completion
00078  * callback in input.
00079  *
00080  * It is also possible to send a write command, which is not acknowledged by the
00081  * peer server by using the function writeWoResponse().
00082  *
00083  * Finally, descriptors of the characteristic can be discovered by invoking the
00084  * function discoverDescriptors, which is shorthand for calling
00085  * GattClient::discoverCharacteristicDescriptors. That discovery is necessary to
00086  * enable or disable characteristic notification or indication that is achieved
00087  * by writing on the Client Characteristic Configuration Descriptor (CCCD).
00088  */
00089 class DiscoveredCharacteristic {
00090 public:
00091     /**
00092      * Properties of a discovered characteristic.
00093      */
00094     struct Properties_t {
00095         /**
00096          * Permits broadcasts of the characteristic value using the character
00097          * the Server Characteristic Configuration Descriptor.
00098          *
00099          * @note If set, descriptors of the characteristic contain a Server
00100          * Characteristic Configuration Descriptor.
00101          */
00102         uint8_t _broadcast :1;
00103 
00104         /**
00105          * If set, the value of the characteristic can be read.
00106          */
00107         uint8_t _read :1;
00108 
00109         /**
00110          * If set, a write command can write the characteristic value
00111          * (write without response).
00112          */
00113         uint8_t _writeWoResp :1;
00114 
00115         /**
00116          * If set, clients can issue requests to write the characteristic.
00117          */
00118         uint8_t _write :1;
00119 
00120         /**
00121          * If set, the server can emit notifications of the Characteristic Value
00122          * (without client acknowledgment).
00123          *
00124          * @note If set, descriptors of the characteristic contain a Client
00125          * Characteristic Configuration Descriptor.
00126          */
00127         uint8_t _notify :1;
00128 
00129         /**
00130          * If set, the server can emit indication of the Characteristic Value
00131          * (with client acknowledgement).
00132          *
00133          * @note If set, descriptors of the characteristic contain a Client
00134          * Characteristic Configuration Descriptor.
00135          */
00136         uint8_t _indicate :1;
00137 
00138         /**
00139          * If set, signed write of the Characteristic Value is supported.
00140          */
00141         uint8_t _authSignedWrite :1;
00142 
00143     public:
00144         /**
00145          * Return the value of the broadcast propertie.
00146          *
00147          * @return true if the Server Characteristic Configuration Descriptor
00148          * of the characteristic can be configured to broadcast the
00149          * characteristic value during broadcast procedure.
00150          *
00151          * @see _broadcast
00152          */
00153         bool broadcast(void) const
00154         {
00155             return _broadcast;
00156         }
00157 
00158         /**
00159          * Return the value of the read property
00160          *
00161          * @return true if the characteristic value can be read and false
00162          * otherwise.
00163          *
00164          * @see _read
00165          */
00166         bool read(void) const
00167         {
00168             return _read;
00169         }
00170 
00171         /**
00172          * Return the value of the write without response property.
00173          *
00174          * @return true if the characteristic accepts write without response
00175          * commands and false otherwise.
00176          *
00177          * @see _writeWoResp
00178          */
00179         bool writeWoResp(void) const
00180         {
00181             return _writeWoResp;
00182         }
00183 
00184         /**
00185          * Return the value of the write property.
00186          *
00187          * @return true if writing the characteristic accepts write requests and
00188          * false otherwise.
00189          *
00190          * @see _write
00191          */
00192         bool write(void) const
00193         {
00194             return _write;
00195         }
00196 
00197         /**
00198          * Return the value of the notification property.
00199          *
00200          * @return true if the Client Characteristic Configuration Descriptor
00201          * can be configured to notify the characteristic value to a given
00202          * client and false otherwise.
00203          *
00204          * @note unlike indication, the notification procedure does not require
00205          * acknowledgement from the client.
00206          *
00207          * @see _notify
00208          */
00209         bool notify(void) const
00210         {
00211             return _notify;
00212         }
00213 
00214         /**
00215          * Return the value of the indicate property.
00216          *
00217          * @return true if the Client Characteristic Configuration Descriptor
00218          * can be configured to indicate the characteristic value to a given
00219          * client and false otherwise.
00220          *
00221          * @note unlike notification the indication procedure does require
00222          * acknowledgment from the client.
00223          *
00224          * @see _indicate
00225          */
00226         bool indicate(void) const
00227         {
00228             return _indicate;
00229         }
00230 
00231         /**
00232          * Return the value of the authenticated signed writes property.
00233          *
00234          * @return true if the characteristic accepts authenticated signed write
00235          * and false otherwise.
00236          */
00237         bool authSignedWrite(void) const
00238         {
00239             return _authSignedWrite;
00240         }
00241 
00242         /**
00243          * Equal to operator for DiscoveredCharacteristic::Properties_t.
00244          *
00245          * @param[in] lhs The left hand side of the equality expression.
00246          * @param[in] rhs The right hand side of the equality expression.
00247          *
00248          * @return true if operands are equals and false otherwise.
00249          */
00250         friend bool operator==(Properties_t lhs, Properties_t rhs)
00251         {
00252             return lhs._broadcast == rhs._broadcast &&
00253                    lhs._read == rhs._read &&
00254                    lhs._writeWoResp == rhs._writeWoResp &&
00255                    lhs._write == rhs._write &&
00256                    lhs._notify == rhs._notify &&
00257                    lhs._indicate == rhs._indicate &&
00258                    lhs._authSignedWrite == rhs._authSignedWrite;
00259         }
00260 
00261         /**
00262          * Not equal to operator for DiscoveredCharacteristic::Properties_t.
00263          *
00264          * @param lhs The left hand side of the expression.
00265          * @param rhs The right hand side of the expression.
00266          *
00267          * @return true if operands are not equals, false otherwise.
00268          */
00269         friend bool operator!=(Properties_t lhs, Properties_t rhs)
00270         {
00271             return !(lhs == rhs);
00272         }
00273 
00274     private:
00275         /* Disallow implicit conversion to integer types. */
00276         operator uint8_t() const;
00277         operator unsigned() const;
00278     };
00279 
00280     /**
00281      * Initiate a read of the characteristic value.
00282      *
00283      * The characteristic value is read in its entirety from the value attribute
00284      * of the characteristic.
00285      *
00286      * Read responses will be passed to the callback registered in
00287      * GattClient::onDataRead(). Read responses to read requests that this function
00288      * call initiates will have their GattReadCallbackParams::connHandle
00289      * field equal to the value returned by getConnectionHandle() and their
00290      * GattReadCallbackParams::handle field equal to the value returned by
00291      * getValueHandle().
00292      *
00293      * @param[in] offset The position - in the characteristic value bytes stream
00294      * - where the read operation begin. This parameter is optional.
00295      *
00296      * @return BLE_ERROR_NONE if a read has been initiated.
00297      * @return BLE_ERROR_INVALID_STATE if some internal state about the
00298      * connection is invalid.
00299      * @return BLE_STACK_BUSY if some client procedure is already in progress.
00300      * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
00301      * properties.
00302      */
00303     ble_error_t read(uint16_t offset = 0) const;
00304 
00305     /**
00306      * Initiate a read of the characteristic value and pass the response to its
00307      * completion callback.
00308      *
00309      * @param[in] offset The position - in the characteristic value bytes stream
00310      * - where the read operation begin.
00311      *
00312      * @param[in] onRead Completion callback which will accept the response of
00313      * the read request. The callback is copied; it is unnecessary to keep it
00314      * in memory after the call.
00315      *
00316      * @return BLE_ERROR_NONE if a read has been initiated.
00317      * @return BLE_ERROR_INVALID_STATE if some internal state about the
00318      * connection is invalid.
00319      * @return BLE_STACK_BUSY if some client procedure is already in progress.
00320      * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
00321      * properties.
00322      *
00323      * @note This function is similar to read(uint16_t) const; however, it uses
00324      * dynamic memory to store the use completion callback.
00325      */
00326     ble_error_t read(
00327         uint16_t offset,
00328         const GattClient::ReadCallback_t  &onRead
00329     ) const;
00330 
00331     /**
00332      * Perform a write without response procedure.
00333      *
00334      * @note The server does not acknowledge write without responses.
00335      * Therefore, they won't generate any event on the client side.
00336      *
00337      * @param[in] length The amount of data being written.
00338      * @param[in] value The bytes being written.
00339      *
00340      * @return BLE_ERROR_NONE Successfully started the Write procedure.
00341      * @return BLE_ERROR_INVALID_STATE if some internal state about the
00342      * connection is invalid.
00343      * @return BLE_STACK_BUSY if some client procedure is already in progress.
00344      * @return BLE_ERROR_NO_MEM if there are no available buffers left to
00345      * process the request.
00346      * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
00347      * properties.
00348      */
00349     ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const;
00350 
00351     /**
00352      * Initiate a discovery of the characteristic descriptors.
00353      *
00354      * When a descriptor is discovered, the callback onDescriptorDiscovered is
00355      * invoked with the descriptor discovered as parameter. When the process
00356      * ends, the callback onTermination is invoked.
00357      *
00358      * @param[in] onDescriptorDiscovered Callback is invoked when a descriptor is
00359      * discovered.
00360      *
00361      * @param[in] onTermination Callback is invoked when the discovery process ends.
00362      *
00363      * @return BLE_ERROR_NONE if descriptor discovery is launched successfully;
00364      * else an appropriate error.
00365      *
00366      * @note This function is shorthand for
00367      * GattClient::discoverCharacteristicDescriptors; therefore,
00368      * GattClient::isCharacteristicDescriptorDiscoveryActive can be used to
00369      * determine the descriptor discovery and
00370      * GattClient::terminateCharacteristicDescriptorDiscovery can be used to
00371      * end the discovery process.
00372      */
00373     ble_error_t discoverDescriptors(
00374         const CharacteristicDescriptorDiscovery::DiscoveryCallback_t  &onDescriptorDiscovered,
00375         const CharacteristicDescriptorDiscovery::TerminationCallback_t  &onTermination
00376     ) const;
00377 
00378     /**
00379      * Initiate a write procedure of the characteristic value.
00380      *
00381      * Unlike write without responses (see writeWoResponse()), an acknowledgment
00382      * is expected for this procedure. The response of the peer GATT server to
00383      * the write request is passed to callbacks registered in
00384      * GattClient::onDataWritten().
00385      *
00386      * Similarly to read responses, responses to write request of this
00387      * characteristic can be identified by their connection handle (
00388      * GattWriteCallbackParams::connHandle), which is equal to the value
00389      * returned by getConnectionHandle() and their attribute handle (
00390      * GattWriteCallbackParams::handle), which is equal to the value
00391      * returned by getValueHandle().
00392      *
00393      * @param[in] length The amount of data being written.
00394      * @param[in] value The bytes being written.
00395      *
00396      * @return BLE_ERROR_NONE Successfully started the Write procedure.
00397      * @return BLE_ERROR_INVALID_STATE If some internal state about the
00398      * connection is invalid.
00399      * @return BLE_STACK_BUSY If some client procedure is already in progress.
00400      * @return BLE_ERROR_NO_MEM If there are no available buffers left to
00401      * process the request.
00402      * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
00403      * properties.
00404      *
00405      * @note Internally, the API uses the write or long write procedure, depending
00406      * on the number of bytes to write and the MTU size.
00407      */
00408     ble_error_t write(uint16_t length, const uint8_t *value) const;
00409 
00410     /**
00411      * Initiate a write procedure of the characteristic value.
00412      *
00413      * Same as write(uint16_t, const uint8_t *) const but accepts a completion
00414      * callback, which is invoked when the server response is received.
00415      *
00416      * @param[in] length The amount of bytes to write.
00417      * @param[in] value The bytes to write.
00418      * @param[in] onWrite Continuation callback of the write procedure.
00419      *
00420      * @return BLE_ERROR_NONE Successfully started the Write procedure.
00421      * @return BLE_ERROR_INVALID_STATE if some internal state about the
00422      * connection is invalid.
00423      * @return BLE_STACK_BUSY if some client procedure is already in progress.
00424      * @return BLE_ERROR_NO_MEM if there are no available buffers left to
00425      * process the request.
00426      * @return BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's
00427      * properties.
00428      */
00429     ble_error_t write(
00430         uint16_t length,
00431         const uint8_t *value,
00432         const GattClient::WriteCallback_t  &onWrite
00433     ) const;
00434 
00435     void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) {
00436         uuid.setupLong(longUUID, order);
00437     }
00438 
00439 public:
00440     /**
00441      * Get the UUID of the discovered characteristic.
00442      *
00443      * @return The UUID of this characteristic.
00444      */
00445     const UUID &getUUID(void) const
00446     {
00447         return uuid;
00448     }
00449 
00450     /**
00451      * Get the properties of this characteristic.
00452      *
00453      * @return The set of properties of this characteristic.
00454      */
00455     const Properties_t &getProperties(void) const
00456     {
00457         return props;
00458     }
00459 
00460     /**
00461      * Get the declaration handle of this characteristic.
00462      *
00463      * The declaration handle is the first handle of a characteristic
00464      * definition. The value accessible at this handle contains the following
00465      * informations:
00466      *    - The characteristics properties (see Properties_t). This value can
00467      *      be accessed by using #getProperties .
00468      *    - The characteristic value attribute handle. This field can be accessed
00469      *      by using #getValueHandle .
00470      *    - The characteristic UUID, this value can be accessed by using the
00471      *      function #getUUID .
00472      *
00473      * @return the declaration handle of this characteristic.
00474      */
00475     GattAttribute::Handle_t getDeclHandle(void) const
00476     {
00477         return declHandle;
00478     }
00479 
00480     /**
00481      * Get the attribute handle of the characteristic value.
00482      *
00483      * This handle is used to read or write the value of the characteristic.
00484      *
00485      * @return The handle to access the value of this characteristic.
00486      */
00487     GattAttribute::Handle_t getValueHandle(void) const
00488     {
00489         return valueHandle;
00490     }
00491 
00492     /**
00493      * Return the last attribute handle of the characteristic definition.
00494      *
00495      * The attribute layout of a characteristic definition is:
00496      *   - Declaration attribute (see #getDeclHandle).
00497      *   - Value attribute (see #getValueHandle).
00498      *   - Zero or more characteristic descriptors attribute.
00499      *
00500      * The last attribute handle is used internally to discover characteristic
00501      * descriptors. The discovery operates on the range [ValueHandle + 1 :
00502      * LastHandle].
00503      *
00504      * @return The last handle of this characteristic definition.
00505      *
00506      * @note This function is public for informative purposes.
00507      */
00508     GattAttribute::Handle_t getLastHandle(void) const
00509     {
00510         return lastHandle;
00511     }
00512 
00513     /**
00514      * Get the GattClient, which can operate on this characteristic.
00515      *
00516      * @return The GattClient, which can operate on this characteristic.
00517      */
00518     GattClient* getGattClient()
00519     {
00520         return gattc;
00521     }
00522 
00523     /**
00524      * Get the GattClient, which can operate on this characteristic.
00525      *
00526      * @return The GattClient, which can operate on this characteristic.
00527      */
00528     const GattClient* getGattClient() const
00529     {
00530         return gattc;
00531     }
00532 
00533     /**
00534      * @brief Get the connection handle to the GattServer containing this
00535      * characteristic.
00536      *
00537      * @return Connection handle to the GattServer, which contains this
00538      * characteristic.
00539      */
00540     Gap::Handle_t getConnectionHandle() const
00541     {
00542         return connHandle;
00543     }
00544 
00545     /**
00546      * "Equal to" operator for DiscoveredCharacteristic.
00547      *
00548      * @param[in] lhs The left hand side of the equality expression.
00549      * @param[in] rhs The right hand side of the equality expression.
00550      *
00551      * @return true if operands are equals and false otherwise.
00552      */
00553     friend bool operator==(
00554         const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs
00555     ) {
00556         return lhs.gattc == rhs.gattc &&
00557                lhs.uuid == rhs.uuid &&
00558                lhs.props == rhs.props &&
00559                lhs.declHandle == rhs.declHandle &&
00560                lhs.valueHandle == rhs.valueHandle &&
00561                lhs.lastHandle == rhs.lastHandle &&
00562                lhs.connHandle == rhs.connHandle;
00563     }
00564 
00565     /**
00566      * "Not equal to" operator for DiscoveredCharacteristic.
00567      *
00568      * @param[in] lhs The right hand side of the expression.
00569      * @param[in] rhs The left hand side of the expression.
00570      *
00571      * @return true if operands are not equal and false otherwise.
00572      */
00573     friend bool operator !=(
00574         const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs
00575     ) {
00576         return !(lhs == rhs);
00577     }
00578 
00579 public:
00580     DiscoveredCharacteristic() :
00581         gattc(NULL),
00582         uuid(UUID::ShortUUIDBytes_t(0)),
00583         props(),
00584         declHandle(GattAttribute::INVALID_HANDLE),
00585         valueHandle(GattAttribute::INVALID_HANDLE),
00586         lastHandle(GattAttribute::INVALID_HANDLE),
00587         connHandle() {
00588     }
00589 
00590 protected:
00591     /**
00592      * Pointer to the underlying GattClient for this DiscoveredCharacteristic
00593      * object.
00594      */
00595     GattClient *gattc;
00596 
00597 protected:
00598     /**
00599      * Discovered characteristic's UUID.
00600      */
00601     UUID uuid;
00602 
00603     /**
00604      * Hold the configured properties of the discovered characteristic.
00605      *
00606      * @see Properties_t.
00607      */
00608     Properties_t props;
00609 
00610     /**
00611      * Value handle of the discovered characteristic's declaration attribute.
00612      */
00613     GattAttribute::Handle_t declHandle;
00614 
00615     /**
00616      * Value handle of the discovered characteristic's value attribute.
00617      */
00618     GattAttribute::Handle_t valueHandle;
00619 
00620     /**
00621      * Value handle of the discovered characteristic's last attribute.
00622      */
00623     GattAttribute::Handle_t lastHandle;
00624 
00625     /**
00626      * Handle of the connection where the characteristic was discovered.
00627      */
00628     Gap::Handle_t connHandle;
00629 };
00630 
00631 /**
00632  * @}
00633  * @}
00634  * @}
00635  */
00636 
00637 #endif /*MBED_DISCOVERED_CHARACTERISTIC_H__*/