A blue button is always a nice toy ...

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_HeartRate_IDB0XA1 by ST

Committer:
hux
Date:
Sun Oct 01 12:49:25 2017 +0000
Revision:
29:a6b74dfdd5f2
A blue button is always a nice toy ...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hux 29:a6b74dfdd5f2 1 // characteristic.h - an easy to use overloaded characteristic class
hux 29:a6b74dfdd5f2 2 //
hux 29:a6b74dfdd5f2 3 // Synopsis:
hux 29:a6b74dfdd5f2 4 //
hux 29:a6b74dfdd5f2 5 // Characteristic<type> myCharacteristic(col,uuid,mode);
hux 29:a6b74dfdd5f2 6 // Characteristic<type> myCharacteristic(col,uuid,mode,name);
hux 29:a6b74dfdd5f2 7 // Characteristic<type> myCharacteristic(col,uuid,mode,name,inidata);
hux 29:a6b74dfdd5f2 8 // Characteristic<type> myCharacteristic(col,uuid,mode,inidata);
hux 29:a6b74dfdd5f2 9 //
hux 29:a6b74dfdd5f2 10 // Declaration of a characteristic, specifying value type, UUID and access mode,
hux 29:a6b74dfdd5f2 11 // optionally providing a name (user descriptor) and initial data.
hux 29:a6b74dfdd5f2 12 //
hux 29:a6b74dfdd5f2 13 // col: Collection, to which the constructed characteristic is automati-
hux 29:a6b74dfdd5f2 14 // cally added. After construction and adding all characteristics to
hux 29:a6b74dfdd5f2 15 // a collection this collection is passed to a service constructor,
hux 29:a6b74dfdd5f2 16 // which gets thus knowledge about all characteristics which have to
hux 29:a6b74dfdd5f2 17 // be involved in the service
hux 29:a6b74dfdd5f2 18 //
hux 29:a6b74dfdd5f2 19 // uuid: A unique universal ID which identifies the characteristic
hux 29:a6b74dfdd5f2 20 //
hux 29:a6b74dfdd5f2 21 // mode: A string comprising zero or more mode characters which
hux 29:a6b74dfdd5f2 22 // define possible properties of the characteristic.
hux 29:a6b74dfdd5f2 23 //
hux 29:a6b74dfdd5f2 24 // "" no properties
hux 29:a6b74dfdd5f2 25 // "b" broadcast
hux 29:a6b74dfdd5f2 26 // "r" read access
hux 29:a6b74dfdd5f2 27 // "s" send & pray (write without response)
hux 29:a6b74dfdd5f2 28 // "w" write access (with feedback)
hux 29:a6b74dfdd5f2 29 // "n" notification (no client confirmation)
hux 29:a6b74dfdd5f2 30 // "i" indication (with client confirmation)
hux 29:a6b74dfdd5f2 31 // "a" authentication signed write
hux 29:a6b74dfdd5f2 32 // "x" extended access
hux 29:a6b74dfdd5f2 33 //
hux 29:a6b74dfdd5f2 34 // name: An optional name provided in terms of a user descriptor. If this
hux 29:a6b74dfdd5f2 35 // argument is omitted the user descriptor is not created.
hux 29:a6b74dfdd5f2 36 //
hux 29:a6b74dfdd5f2 37 // inidata: A pointer to a variable containing initializing data for the
hux 29:a6b74dfdd5f2 38 // characteristic. If the inidata argument is not provided, an
hux 29:a6b74dfdd5f2 39 // implicit initialization is performed which clears the characte-
hux 29:a6b74dfdd5f2 40 // ristic (all bytes set to 0). As a concluding remark it needs to
hux 29:a6b74dfdd5f2 41 // be noted that the implicite initialozation works only for
hux 29:a6b74dfdd5f2 42 // sizeof(Type) <= SIZE_INIBUFFER (defined in "bricks/types.h")
hux 29:a6b74dfdd5f2 43 //
hux 29:a6b74dfdd5f2 44 //
hux 29:a6b74dfdd5f2 45 // Example 1: A protocol might be declared as a class as follows
hux 29:a6b74dfdd5f2 46 //
hux 29:a6b74dfdd5f2 47 // Collection col; // collection used during setup
hux 29:a6b74dfdd5f2 48 //
hux 29:a6b74dfdd5f2 49 // Characteristic<ObjectId> id(col,0x2AC3,"rw","ID");
hux 29:a6b74dfdd5f2 50 // Characteristic<ObjectName> name(col,0x2ABE,"rw","Name");
hux 29:a6b74dfdd5f2 51 // Characteristic<Digital> presence(col,0x2A56,"r","Presence");
hux 29:a6b74dfdd5f2 52 //
hux 29:a6b74dfdd5f2 53 // Service presenceDetection(col,0xA001); // instantiate service
hux 29:a6b74dfdd5f2 54 //
hux 29:a6b74dfdd5f2 55 // onSetup(Blob &blue)
hux 29:a6b74dfdd5f2 56 // {
hux 29:a6b74dfdd5f2 57 // blue.service(presenceDetection); // add service
hux 29:a6b74dfdd5f2 58 // }
hux 29:a6b74dfdd5f2 59 //
hux 29:a6b74dfdd5f2 60 // Example 2: service definition by means of a service definition class
hux 29:a6b74dfdd5f2 61 //
hux 29:a6b74dfdd5f2 62 // class PresenceDetector
hux 29:a6b74dfdd5f2 63 // {
hux 29:a6b74dfdd5f2 64 // public:
hux 29:a6b74dfdd5f2 65 // Collection col; // collection used during setup
hux 29:a6b74dfdd5f2 66 //
hux 29:a6b74dfdd5f2 67 // Characteristic<ObjectId> id; // ID of presence detector
hux 29:a6b74dfdd5f2 68 // Characteristic<ObjectName> name; // name of presence detector
hux 29:a6b74dfdd5f2 69 // Characteristic<Digital> presence; // digital presence value
hux 29:a6b74dfdd5f2 70 // Characteristic<DateTime> timestamp; // last detection change's time
hux 29:a6b74dfdd5f2 71 // Characteristic<ObjectName> layout; // name of model railway layout
hux 29:a6b74dfdd5f2 72 //
hux 29:a6b74dfdd5f2 73 // Service presenceDetection; // the service
hux 29:a6b74dfdd5f2 74 //
hux 29:a6b74dfdd5f2 75 // public:
hux 29:a6b74dfdd5f2 76 // PresenceDetector(Blob &blue, cost UUID uuid) :
hux 29:a6b74dfdd5f2 77 // list; // init service list
hux 29:a6b74dfdd5f2 78 // id(list,0x2AC3,"rw","ID"), // instantiate characteristic
hux 29:a6b74dfdd5f2 79 // name(list,0x2ABE,"rw","Name"), // instantiate characteristic
hux 29:a6b74dfdd5f2 80 // presence(list,0x2A56,"r","Presence"),// instantiate characteristic
hux 29:a6b74dfdd5f2 81 // timestamp(list,0x2A08,"r","Timestamp"),// instantiate characteristic
hux 29:a6b74dfdd5f2 82 // layout(list,0x2ABE,"rw","Layout"), // instantiate characteristic
hux 29:a6b74dfdd5f2 83 // presenceDetection(list,uuid) // instantiate service
hux 29:a6b74dfdd5f2 84 // {
hux 29:a6b74dfdd5f2 85 // blue.service(presenceDetection); // add service
hux 29:a6b74dfdd5f2 86 // }
hux 29:a6b74dfdd5f2 87 // };
hux 29:a6b74dfdd5f2 88 //
hux 29:a6b74dfdd5f2 89 #ifndef _CHARACTERISTIC_H_
hux 29:a6b74dfdd5f2 90 #define _CHARACTERISTIC_H_
hux 29:a6b74dfdd5f2 91
hux 29:a6b74dfdd5f2 92 #include "ble/BLE.h"
hux 29:a6b74dfdd5f2 93 #include "ble/Gap.h"
hux 29:a6b74dfdd5f2 94 #include "bricks/types.h"
hux 29:a6b74dfdd5f2 95 #include "bricks/collection.h"
hux 29:a6b74dfdd5f2 96 #include "bricks/descriptor.h"
hux 29:a6b74dfdd5f2 97
hux 29:a6b74dfdd5f2 98 // the following #define is helpful if characteristics are defined on base
hux 29:a6b74dfdd5f2 99 // of the BLE API (the tedious way)
hux 29:a6b74dfdd5f2 100
hux 29:a6b74dfdd5f2 101 #define UserDescriptor(name,attribute,descriptor,text) \
hux 29:a6b74dfdd5f2 102 static char *name = text; \
hux 29:a6b74dfdd5f2 103 static GattAttribute attribute(0x2901,(uint8_t*)name,strlen(name),strlen(name)); \
hux 29:a6b74dfdd5f2 104 static GattAttribute *descriptor[] = {&attribute};
hux 29:a6b74dfdd5f2 105
hux 29:a6b74dfdd5f2 106 // the declaration of Characteristics needs the availability of an
hux 29:a6b74dfdd5f2 107 // initializing buffer in the default case
hux 29:a6b74dfdd5f2 108
hux 29:a6b74dfdd5f2 109 extern IniBuffer characteristicInidata; // to initialize a characteristic
hux 29:a6b74dfdd5f2 110
hux 29:a6b74dfdd5f2 111 // class definition of a characteristic initializer
hux 29:a6b74dfdd5f2 112
hux 29:a6b74dfdd5f2 113 class CharacteristicInitializer // provides pointers to initialized data
hux 29:a6b74dfdd5f2 114 {
hux 29:a6b74dfdd5f2 115 private:
hux 29:a6b74dfdd5f2 116 IniBuffer inibuf; // initialized data
hux 29:a6b74dfdd5f2 117
hux 29:a6b74dfdd5f2 118 public:
hux 29:a6b74dfdd5f2 119 ObjectId *pObjectId() { return (ObjectId*) &inibuf; }
hux 29:a6b74dfdd5f2 120 ObjectName *pObjectName() { return (ObjectName*) &inibuf; }
hux 29:a6b74dfdd5f2 121 Bool *pBool() { return (Bool*) &inibuf; }
hux 29:a6b74dfdd5f2 122 Digital *pDigital() { return (Digital*) &inibuf; }
hux 29:a6b74dfdd5f2 123 DateTime *pDateTime() { return (DateTime*) &inibuf; }
hux 29:a6b74dfdd5f2 124 Buffer *pBuffer() { return (Buffer*) &inibuf; }
hux 29:a6b74dfdd5f2 125
hux 29:a6b74dfdd5f2 126 public:
hux 29:a6b74dfdd5f2 127 CharacteristicInitializer() // constructor
hux 29:a6b74dfdd5f2 128 {
hux 29:a6b74dfdd5f2 129 memset(inibuf,0,sizeof(IniBuffer));
hux 29:a6b74dfdd5f2 130
hux 29:a6b74dfdd5f2 131 // besides of the local inibuf also initialize the global
hux 29:a6b74dfdd5f2 132 // init buffer characteristicInidata;
hux 29:a6b74dfdd5f2 133
hux 29:a6b74dfdd5f2 134 memset(characteristicInidata,0,sizeof(IniBuffer));
hux 29:a6b74dfdd5f2 135 }
hux 29:a6b74dfdd5f2 136 };
hux 29:a6b74dfdd5f2 137
hux 29:a6b74dfdd5f2 138 // definition of class Characteristic
hux 29:a6b74dfdd5f2 139
hux 29:a6b74dfdd5f2 140 class Service;
hux 29:a6b74dfdd5f2 141
hux 29:a6b74dfdd5f2 142 template <typename Type>
hux 29:a6b74dfdd5f2 143 class Characteristic : public GattCharacteristic
hux 29:a6b74dfdd5f2 144 {
hux 29:a6b74dfdd5f2 145 private:
hux 29:a6b74dfdd5f2 146 void init() // initialize inibuffer
hux 29:a6b74dfdd5f2 147 {
hux 29:a6b74dfdd5f2 148 static int initialized = 0;
hux 29:a6b74dfdd5f2 149
hux 29:a6b74dfdd5f2 150 if (!initialized) // clear init data buffer
hux 29:a6b74dfdd5f2 151 { initialized = 1;
hux 29:a6b74dfdd5f2 152 memset(characteristicInidata,0,sizeof(IniBuffer));
hux 29:a6b74dfdd5f2 153 }
hux 29:a6b74dfdd5f2 154 }
hux 29:a6b74dfdd5f2 155
hux 29:a6b74dfdd5f2 156 private:
hux 29:a6b74dfdd5f2 157 UserDescriptor descriptor; // characteristic's user descriptor
hux 29:a6b74dfdd5f2 158
hux 29:a6b74dfdd5f2 159 uint8_t getmask(const char *pmask)
hux 29:a6b74dfdd5f2 160 {
hux 29:a6b74dfdd5f2 161 uint8_t mask = 0;
hux 29:a6b74dfdd5f2 162
hux 29:a6b74dfdd5f2 163 for(;*pmask;pmask++)
hux 29:a6b74dfdd5f2 164 { switch (*pmask)
hux 29:a6b74dfdd5f2 165 {
hux 29:a6b74dfdd5f2 166 case 'b': // broad cast
hux 29:a6b74dfdd5f2 167 mask = mask | BLE_GATT_CHAR_PROPERTIES_BROADCAST;
hux 29:a6b74dfdd5f2 168 break;
hux 29:a6b74dfdd5f2 169 case 'r': // read
hux 29:a6b74dfdd5f2 170 mask = mask | BLE_GATT_CHAR_PROPERTIES_READ;
hux 29:a6b74dfdd5f2 171 break;
hux 29:a6b74dfdd5f2 172 case 's': // send (& pray)
hux 29:a6b74dfdd5f2 173 mask = mask | BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE;
hux 29:a6b74dfdd5f2 174 break;
hux 29:a6b74dfdd5f2 175 case 'w': // write
hux 29:a6b74dfdd5f2 176 mask = mask | BLE_GATT_CHAR_PROPERTIES_WRITE;
hux 29:a6b74dfdd5f2 177 break;
hux 29:a6b74dfdd5f2 178 case 'n': // notify
hux 29:a6b74dfdd5f2 179 mask = mask | BLE_GATT_CHAR_PROPERTIES_NOTIFY;
hux 29:a6b74dfdd5f2 180 break;
hux 29:a6b74dfdd5f2 181 case 'i': // indicate
hux 29:a6b74dfdd5f2 182 mask = mask | BLE_GATT_CHAR_PROPERTIES_INDICATE;
hux 29:a6b74dfdd5f2 183 break;
hux 29:a6b74dfdd5f2 184 case 'a': // authenticated signed write
hux 29:a6b74dfdd5f2 185 mask = mask | BLE_GATT_CHAR_PROPERTIES_AUTHENTICATED_SIGNED_WRITES;
hux 29:a6b74dfdd5f2 186 break;
hux 29:a6b74dfdd5f2 187 case 'x': // extended properties
hux 29:a6b74dfdd5f2 188 mask = mask | BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES;
hux 29:a6b74dfdd5f2 189 break;
hux 29:a6b74dfdd5f2 190 }
hux 29:a6b74dfdd5f2 191 }
hux 29:a6b74dfdd5f2 192 return mask;
hux 29:a6b74dfdd5f2 193 }
hux 29:a6b74dfdd5f2 194 /*
hux 29:a6b74dfdd5f2 195 public:
hux 29:a6b74dfdd5f2 196 Characteristic<Type> (Service &service, UUID uuid, const char *mode,
hux 29:a6b74dfdd5f2 197 Type *valuePtr = (Type*)&characteristicInidata) :
hux 29:a6b74dfdd5f2 198 GattCharacteristic(uuid,
hux 29:a6b74dfdd5f2 199 reinterpret_cast<uint8_t*> (valuePtr),
hux 29:a6b74dfdd5f2 200 sizeof(Type),
hux 29:a6b74dfdd5f2 201 sizeof(Type),
hux 29:a6b74dfdd5f2 202 getmask(mode),
hux 29:a6b74dfdd5f2 203 NULL, // descriptor list
hux 29:a6b74dfdd5f2 204 0, // number of descriptors
hux 29:a6b74dfdd5f2 205 false),
hux 29:a6b74dfdd5f2 206 descriptor("") // construct descriptor
hux 29:a6b74dfdd5f2 207 {
hux 29:a6b74dfdd5f2 208 init(); // assure initializing
hux 29:a6b74dfdd5f2 209
hux 29:a6b74dfdd5f2 210 // there is a potential danger that we use implicite initializing
hux 29:a6b74dfdd5f2 211 // with sizeof(Type) > sizeof(inibuffer). This must be prevented!
hux 29:a6b74dfdd5f2 212
hux 29:a6b74dfdd5f2 213 int feasible = (sizeof(Type) <= sizeof(IniBuffer));
hux 29:a6b74dfdd5f2 214 if (feasible || valuePtr != (Type*)&characteristicInidata)
hux 29:a6b74dfdd5f2 215 {
hux 29:a6b74dfdd5f2 216 service.add(this); // add to service
hux 29:a6b74dfdd5f2 217 } // otherwise just ignore!
hux 29:a6b74dfdd5f2 218 }
hux 29:a6b74dfdd5f2 219 */
hux 29:a6b74dfdd5f2 220 public:
hux 29:a6b74dfdd5f2 221 Characteristic<Type> (Service &service, UUID uuid, const char *mode,
hux 29:a6b74dfdd5f2 222 const char *name, Type *valuePtr = (Type*)&characteristicInidata) :
hux 29:a6b74dfdd5f2 223 GattCharacteristic(uuid,
hux 29:a6b74dfdd5f2 224 reinterpret_cast<uint8_t*> (valuePtr),
hux 29:a6b74dfdd5f2 225 sizeof(Type),
hux 29:a6b74dfdd5f2 226 sizeof(Type),
hux 29:a6b74dfdd5f2 227 getmask(mode),
hux 29:a6b74dfdd5f2 228 descriptor.plist, // descriptor list
hux 29:a6b74dfdd5f2 229 1, // number of descriptors
hux 29:a6b74dfdd5f2 230 false),
hux 29:a6b74dfdd5f2 231 descriptor(name) // construct descriptor
hux 29:a6b74dfdd5f2 232 {
hux 29:a6b74dfdd5f2 233 init(); // assure initializing
hux 29:a6b74dfdd5f2 234
hux 29:a6b74dfdd5f2 235 // there is a potential danger that we use implicite initializing
hux 29:a6b74dfdd5f2 236 // with sizeof(Type) > sizeof(inibuffer). This must be prevented!
hux 29:a6b74dfdd5f2 237
hux 29:a6b74dfdd5f2 238 int feasible = (sizeof(Type) <= sizeof(IniBuffer));
hux 29:a6b74dfdd5f2 239 if (feasible || valuePtr != (Type*)&characteristicInidata)
hux 29:a6b74dfdd5f2 240 {
hux 29:a6b74dfdd5f2 241 service.add(this); // add to service
hux 29:a6b74dfdd5f2 242 } // otherwise just ignore!
hux 29:a6b74dfdd5f2 243 }
hux 29:a6b74dfdd5f2 244 };
hux 29:a6b74dfdd5f2 245
hux 29:a6b74dfdd5f2 246
hux 29:a6b74dfdd5f2 247 #endif // _CHARACTERISTIC_H_