High level Bluetooth Low Energy API and radio abstraction layer

Dependencies:   nRF51822

Dependents:   LinkNode_LIS3DH

Fork of BLE_API by Bluetooth Low Energy

Revision:
807:d119f9333581
Parent:
732:916f36dd93f8
Child:
808:f902b7ca06a6
diff -r 50c121156a71 -r d119f9333581 source/BLE.cpp
--- a/source/BLE.cpp	Tue Sep 29 09:47:51 2015 +0100
+++ b/source/BLE.cpp	Tue Sep 29 09:47:52 2015 +0100
@@ -35,4 +35,77 @@
 #endif // TARGET_OTA_ENABLED
 
     return BLE_ERROR_NONE;
+}
+
+/**
+ * BLE::Instance() and BLE constructor rely upon a static array of initializers
+ * to create actual BLE transport instances. A description of these instances
+ * and initializers is supposed to be put in some .json file contributing to
+ * yotta's configuration (typically the target.json). Here's a sample:
+ *
+ *  "config": {
+ *    ...
+ *    "ble_instances": {
+ *      "count": 1,
+ *      "0" : {
+ *        "initializer" : "createBLEInstance"
+ *      }
+ *    }
+ *  }
+ *
+ * The following macros result in translating the above config into a static
+ * array: instanceConstructors.
+ */
+#ifdef YOTTA_CFG_BLE_INSTANCES_COUNT
+#define CONCATENATE(A, B) A ## B
+#define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */
+
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER
+/* ... add more of the above if ever needed */
+
+#define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N))
+#endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */
+
+typedef BLEInstanceBase *(*InstanceConstructor_t)(void);
+static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = {
+#ifndef YOTTA_CFG_BLE_INSTANCES_COUNT
+    createBLEInstance
+#else
+    INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT)
+#endif
+};
+
+BLE::BLE &
+BLE::Instance(InstanceID_t id)
+{
+    static BLE *singletons[NUM_INSTANCES];
+    if (id < NUM_INSTANCES) {
+        if (singletons[id] == NULL) {
+            singletons[id] = new BLE(id); /* This object will never be freed. */
+        }
+
+        return *singletons[id];
+    }
+
+    /* we come here only in the case of a bad interfaceID. */
+    static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */);
+    return badSingleton;
+}
+
+BLE::BLE(InstanceID_t instanceID) : transport()
+{
+    static BLEInstanceBase *transportInstances[NUM_INSTANCES];
+
+    if (instanceID < NUM_INSTANCES) {
+        if (!transportInstances[instanceID]) {
+            transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */
+        }
+        transport = transportInstances[instanceID];
+    } else {
+        transport = NULL;
+    }
 }
\ No newline at end of file