A blue button is always a nice toy ...

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers characteristic.h Source File

characteristic.h

00001 // characteristic.h - an easy to use overloaded characteristic class
00002 //
00003 // Synopsis:
00004 //
00005 //    Characteristic<type>   myCharacteristic(col,uuid,mode);
00006 //    Characteristic<type>   myCharacteristic(col,uuid,mode,name);
00007 //    Characteristic<type>   myCharacteristic(col,uuid,mode,name,inidata);
00008 //    Characteristic<type>   myCharacteristic(col,uuid,mode,inidata);
00009 //
00010 // Declaration of a characteristic, specifying value type, UUID and access mode,
00011 // optionally providing a name (user descriptor) and initial data.
00012 //
00013 //    col:     Collection, to which the constructed characteristic is automati-
00014 //             cally added. After construction and adding all characteristics to 
00015 //             a collection this collection is passed to a service constructor,
00016 //             which gets thus knowledge about all characteristics which have to
00017 //             be involved in the service
00018 //
00019 //    uuid:    A unique universal ID which identifies the characteristic
00020 //
00021 //    mode:    A string comprising zero or more mode characters which 
00022 //             define possible properties of the characteristic.  
00023 //
00024 //                ""       no properties
00025 //                "b"      broadcast
00026 //                "r"      read access
00027 //                "s"      send & pray (write without response)
00028 //                "w"      write access (with feedback)
00029 //                "n"      notification (no client confirmation)
00030 //                "i"      indication (with client confirmation)
00031 //                "a"      authentication signed write
00032 //                "x"      extended access
00033 //
00034 //    name:    An optional name provided in terms of a user descriptor. If this
00035 //             argument is omitted the user descriptor is not created.
00036 //
00037 //    inidata: A pointer to a variable containing initializing data for the
00038 //             characteristic. If the inidata argument is not provided, an
00039 //             implicit initialization is performed which clears the characte-
00040 //             ristic (all bytes set to 0). As a concluding remark it needs to
00041 //             be noted that the implicite initialozation works only for 
00042 //             sizeof(Type) <= SIZE_INIBUFFER (defined in "bricks/types.h")
00043 //
00044 //
00045 // Example 1: A protocol might be declared as a class as follows
00046 //
00047 //    Collection col;                            // collection used during setup
00048 //
00049 //    Characteristic<ObjectId>   id(col,0x2AC3,"rw","ID");
00050 //    Characteristic<ObjectName> name(col,0x2ABE,"rw","Name");
00051 //    Characteristic<Digital>    presence(col,0x2A56,"r","Presence");
00052 //
00053 //    Service presenceDetection(col,0xA001);     // instantiate service
00054 //
00055 //    onSetup(Blob &blue)
00056 //    {
00057 //       blue.service(presenceDetection);        // add service    
00058 //    }
00059 //
00060 // Example 2: service definition by means of a service definition class
00061 //
00062 //   class PresenceDetector
00063 //   {
00064 //      public:
00065 //         Collection col;                       // collection used during setup 
00066 //
00067 //         Characteristic<ObjectId> id;          // ID of presence detector
00068 //         Characteristic<ObjectName> name;      // name of presence detector
00069 //         Characteristic<Digital> presence;     // digital presence value
00070 //         Characteristic<DateTime> timestamp;   // last detection change's time
00071 //         Characteristic<ObjectName> layout;    // name of model railway layout
00072 //
00073 //         Service presenceDetection;            // the service
00074 //
00075 //      public:
00076 //         PresenceDetector(Blob &blue, cost UUID uuid) :
00077 //            list;                              // init service list
00078 //            id(list,0x2AC3,"rw","ID"),         // instantiate characteristic
00079 //            name(list,0x2ABE,"rw","Name"),     // instantiate characteristic
00080 //            presence(list,0x2A56,"r","Presence"),// instantiate characteristic
00081 //            timestamp(list,0x2A08,"r","Timestamp"),// instantiate characteristic
00082 //            layout(list,0x2ABE,"rw","Layout"), // instantiate characteristic
00083 //            presenceDetection(list,uuid)       // instantiate service
00084 //         {
00085 //            blue.service(presenceDetection);   // add service    
00086 //         }
00087 //   };       
00088 //
00089 #ifndef _CHARACTERISTIC_H_
00090 #define _CHARACTERISTIC_H_
00091 
00092 #include "ble/BLE.h"
00093 #include "ble/Gap.h"
00094 #include "bricks/types.h"
00095 #include "bricks/collection.h"
00096 #include "bricks/descriptor.h"
00097 
00098       // the following #define is helpful if characteristics are defined on base
00099       // of the BLE API (the tedious way)
00100    
00101 #define UserDescriptor(name,attribute,descriptor,text) \
00102    static char *name = text; \
00103    static GattAttribute attribute(0x2901,(uint8_t*)name,strlen(name),strlen(name)); \
00104    static GattAttribute *descriptor[] = {&attribute}; 
00105 
00106       // the declaration of Characteristics needs the availability of an 
00107       // initializing buffer in the default case
00108       
00109    extern IniBuffer characteristicInidata;   // to initialize a characteristic
00110 
00111       // class definition of a characteristic initializer
00112       
00113    class CharacteristicInitializer     // provides pointers to initialized data
00114    {
00115       private:
00116          IniBuffer inibuf;             // initialized data
00117          
00118       public:
00119          ObjectId *pObjectId() { return (ObjectId*) &inibuf; } 
00120          ObjectName *pObjectName() { return (ObjectName*) &inibuf; } 
00121          Bool *pBool() { return (Bool*) &inibuf; } 
00122          Digital *pDigital() { return (Digital*) &inibuf; } 
00123          DateTime *pDateTime() { return (DateTime*) &inibuf; } 
00124          Buffer *pBuffer() { return (Buffer*) &inibuf; } 
00125 
00126       public:
00127          CharacteristicInitializer()   // constructor
00128          {
00129             memset(inibuf,0,sizeof(IniBuffer));
00130             
00131                // besides of the local inibuf also initialize the global
00132                // init buffer characteristicInidata;
00133                
00134             memset(characteristicInidata,0,sizeof(IniBuffer));   
00135          }
00136    }; 
00137 
00138       // definition of class Characteristic
00139       
00140    class Service;
00141 
00142    template <typename Type>
00143    class Characteristic : public GattCharacteristic
00144    {
00145       private:
00146          void init()                     // initialize inibuffer
00147          {
00148             static int initialized = 0;
00149       
00150             if (!initialized)                  // clear init data buffer
00151             {  initialized = 1;
00152                memset(characteristicInidata,0,sizeof(IniBuffer));
00153             }
00154          }
00155          
00156       private:
00157          UserDescriptor descriptor;      // characteristic's user descriptor
00158          
00159          uint8_t getmask(const char *pmask)
00160          {
00161             uint8_t mask = 0;
00162             
00163             for(;*pmask;pmask++)
00164             {  switch (*pmask)
00165                {
00166                   case 'b':  // broad cast
00167                      mask = mask | BLE_GATT_CHAR_PROPERTIES_BROADCAST;
00168                      break;
00169                   case 'r':  // read
00170                      mask = mask | BLE_GATT_CHAR_PROPERTIES_READ;
00171                      break; 
00172                   case 's':  // send (& pray)
00173                      mask = mask | BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE;
00174                      break; 
00175                   case 'w':  // write
00176                      mask = mask | BLE_GATT_CHAR_PROPERTIES_WRITE;
00177                      break; 
00178                   case 'n':  // notify
00179                      mask = mask | BLE_GATT_CHAR_PROPERTIES_NOTIFY;
00180                      break; 
00181                   case 'i':  // indicate
00182                      mask = mask | BLE_GATT_CHAR_PROPERTIES_INDICATE;
00183                      break; 
00184                   case 'a':  // authenticated signed write
00185                      mask = mask | BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES;
00186                      break; 
00187                   case 'x':  // extended properties
00188                      mask = mask | BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES;
00189                      break;
00190                } 
00191             }
00192             return mask;
00193          }
00194 /*         
00195       public:
00196          Characteristic<Type> (Service &service, UUID uuid, const char *mode,
00197                Type *valuePtr = (Type*)&characteristicInidata) : 
00198             GattCharacteristic(uuid, 
00199                                reinterpret_cast<uint8_t*> (valuePtr),
00200                                sizeof(Type),
00201                                sizeof(Type),
00202                                getmask(mode),
00203                                NULL,             // descriptor list
00204                                0,                // number of descriptors
00205                                false),
00206             descriptor("")                       // construct descriptor
00207          {
00208             init();                              // assure initializing
00209             
00210                // there is a potential danger that we use implicite initializing
00211                // with sizeof(Type) > sizeof(inibuffer). This must be prevented!
00212                
00213             int feasible = (sizeof(Type) <= sizeof(IniBuffer)); 
00214             if (feasible || valuePtr != (Type*)&characteristicInidata)
00215             {
00216                service.add(this);                // add to service
00217             }                                    // otherwise just ignore!
00218          }
00219 */
00220       public:
00221          Characteristic<Type> (Service &service, UUID uuid, const char *mode,
00222                 const char *name, Type *valuePtr = (Type*)&characteristicInidata) : 
00223             GattCharacteristic(uuid, 
00224                                reinterpret_cast<uint8_t*> (valuePtr),
00225                                sizeof(Type),
00226                                sizeof(Type),
00227                                getmask(mode),
00228                                descriptor.plist, // descriptor list
00229                                1,                // number of descriptors
00230                                false),
00231             descriptor(name)                     // construct descriptor
00232          {
00233             init();                              // assure initializing
00234             
00235                // there is a potential danger that we use implicite initializing
00236                // with sizeof(Type) > sizeof(inibuffer). This must be prevented!
00237                
00238             int feasible = (sizeof(Type) <= sizeof(IniBuffer)); 
00239             if (feasible || valuePtr != (Type*)&characteristicInidata)
00240             {
00241                service.add(this);                // add to service
00242             }                                    // otherwise just ignore!
00243          }
00244    };
00245 
00246 
00247 #endif // _CHARACTERISTIC_H_