A cute tiny piece of code implementing an IoT NAND device, demonstrating how to setup and advertise a cute GATT (NAND) service. The code has been tested on a Nordic nRF51822-DK.

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_HeartRate_IDB0XA1 by ST

Committer:
hux
Date:
Sun Jan 08 23:15:53 2017 +0000
Revision:
23:2e73c391bb12
A cute tiny piece of code implementing an Iot NAND device, demonstrating how to setup and advertise a cute GATT (NAND) service.

Who changed what in which revision?

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