Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed-dev nRF51822
Revision 86:e0fab77e669d, committed 2016-09-15
- Comitter:
 - cho45 
 - Date:
 - Thu Sep 15 09:31:05 2016 +0900
 - Parent:
 - 85:e526a89a0674
 - Commit message:
 - support consumer keys
 
Changed in this revision
--- a/HIDController_BLE.cpp	Thu Sep 15 08:48:57 2016 +0900
+++ b/HIDController_BLE.cpp	Thu Sep 15 09:31:05 2016 +0900
@@ -350,6 +350,18 @@
 	}
 }
 
+void HIDController::pressConsumerKey(const uint16_t key) {
+	if (keyboardService) {
+		keyboardService->pressConsumerKey(key);
+	}
+}
+
+void HIDController::releaseConsumerKey() {
+	if (keyboardService) {
+		keyboardService->releaseConsumerKey();
+	}
+}
+
 void HIDController::queueCurrentReportData() {
 	if (!connected()) return;
 	if (keyboardService) {
--- a/HIDController_BLE.h Thu Sep 15 08:48:57 2016 +0900 +++ b/HIDController_BLE.h Thu Sep 15 09:31:05 2016 +0900 @@ -20,6 +20,8 @@ static void appendReportData(const uint8_t key); static void deleteReportData(const uint8_t key); + static void pressConsumerKey(const uint16_t key); + static void releaseConsumerKey(); static void queueCurrentReportData(); static void updateBatteryLevel(const uint8_t percentage, const uint16_t voltage); static void initializeConnection(const bool ignoreWhiteList);
--- a/HIDServiceBase.cpp	Thu Sep 15 08:48:57 2016 +0900
+++ b/HIDServiceBase.cpp	Thu Sep 15 09:31:05 2016 +0900
@@ -18,20 +18,20 @@
 #include "config.h"
 #include "HIDServiceBase.h"
 
-static const report_reference_t inputReportReferenceData = { 0, INPUT_REPORT };
+static const report_reference_t inputReportReferenceData = { 1, INPUT_REPORT };
 static const GattAttribute inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&inputReportReferenceData, 2, 2, false);
 static const GattAttribute * inputReportDescriptors[] = {
 	&inputReportReferenceDescriptor,
 };
 
-static const report_reference_t outputReportReferenceData = { 0, OUTPUT_REPORT };
+static const report_reference_t outputReportReferenceData = { 1, OUTPUT_REPORT };
 static const GattAttribute outputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&outputReportReferenceData, 2, 2, false);
 static const GattAttribute * outputReportDescriptors[] = {
 	&outputReportReferenceDescriptor,
 };
 
 
-static const report_reference_t featureReportReferenceData = { 0, FEATURE_REPORT };
+static const report_reference_t featureReportReferenceData = { 1, FEATURE_REPORT };
 static const GattAttribute featureReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&featureReportReferenceData, 2, 2, false);
 static const GattAttribute * featureReportDescriptors[] = {
 	&featureReportReferenceDescriptor,
--- a/KeyboardService.h	Thu Sep 15 08:48:57 2016 +0900
+++ b/KeyboardService.h	Thu Sep 15 09:31:05 2016 +0900
@@ -28,6 +28,7 @@
 	USAGE_PAGE(1),      0x01,       // Generic Desktop Ctrls
 	USAGE(1),           0x06,       // Keyboard
 	COLLECTION(1),      0x01,       // Application
+		REPORT_ID(1),       0x01,
 		USAGE_PAGE(1),      0x07,       //   Kbrd/Keypad
 		USAGE_MINIMUM(1),   0xE0,
 		USAGE_MAXIMUM(1),   0xE7,
@@ -61,13 +62,36 @@
 		USAGE_MAXIMUM(1),   0x65,
 		INPUT(1),           0x00,       //   Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position
 
-		USAGE_PAGE(1),      0x00,       //   Undefined
-		USAGE_MINIMUM(1),   0x00,
-		USAGE_MAXIMUM(1),   0xFF,
-		REPORT_COUNT(1),    0x01,       //   1 byte 
-		REPORT_SIZE(1),     0x08,
-		FEATURE(1),         0x02,       //   Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile
+		USAGE_PAGE(1),      0x0C,       //   Consumer
+		USAGE(1),           0x00,
+		COLLECTION(1),      0x02,       // Logical
+			REPORT_ID(1),       0x01,
+			USAGE_MINIMUM(1),   0x00,
+			USAGE_MAXIMUM(1),   0xFF,
+			REPORT_COUNT(1),    0x01,       //   1 byte 
+			REPORT_SIZE(1),     0x08,
+			FEATURE(1),         0x02,       //   Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile
+		END_COLLECTION(0),
 	END_COLLECTION(0),
+
+	USAGE_PAGE(1),      0x0C,
+	USAGE(1),           0x01,
+	COLLECTION(1),      0x01,
+		REPORT_ID(1),       0x03,
+		REPORT_SIZE(1), 0x10,
+		REPORT_COUNT(1), 0x01,
+		LOGICAL_MINIMUM(1), 1,
+		LOGICAL_MAXIMUM(2), 0xFF, 0x03,
+		USAGE_MINIMUM(1), 1,
+		USAGE_MAXIMUM(2), 0xFF, 0x03,
+		INPUT(1), 0x60,
+	END_COLLECTION(0),
+};
+
+static const report_reference_t consumerInputReportReferenceData = { 3, INPUT_REPORT };
+static const GattAttribute consumerInputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&consumerInputReportReferenceData, 2, 2, false);
+static const GattAttribute * consumerInputReportDescriptors[] = {
+	&consumerInputReportReferenceDescriptor,
 };
 
 class KeyboardService : public HIDServiceBase {
@@ -89,12 +113,18 @@
 		uint8_t raw[1];
 	};
 
+	union ConsumerInputReportData {
+		uint8_t raw[2];
+		uint16_t key;
+	};
+
 	/**
 	 * Boot Protocol
 	 * Share input/output report with Report Protocol for memmory saving
 	 */
 	GattCharacteristic bootKeyboardInputReportCharacteristic;
 	GattCharacteristic bootKeyboardOutputReportCharacteristic;
+	GattCharacteristic consumerInputReportCharacteristic;
 
 	InputReportData inputReportDataPublished;
 	InputReportData inputReportData;
@@ -110,6 +140,9 @@
 	FeatureReportData featureReportData;
 	bool isSending;
 
+	ConsumerInputReportData consumerInputReportData;
+	bool hasPendingConsumerInputReport;
+
 	static const uint8_t MODIFIER_LEFT_CONTROL = 1<<0;
 	static const uint8_t MODIFIER_LEFT_SHIFT = 1<<1;
 	static const uint8_t MODIFIER_LEFT_ALT = 1<<2;
@@ -149,7 +182,16 @@
 			| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE
 			| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE
 		),
+		consumerInputReportCharacteristic(
+			GattCharacteristic::UUID_REPORT_CHAR,
+			(uint8_t *)&consumerInputReportData, sizeof(consumerInputReportData), sizeof(consumerInputReportData),
+			GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ
+			| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
+			| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE,
+			const_cast<GattAttribute**>(consumerInputReportDescriptors), 1
+		),
 		isSending(false),
+		hasPendingConsumerInputReport(false),
 		sendAvailable(false),
 		bufferCount(0)
 	{
@@ -165,6 +207,7 @@
 		DEBUG_PRINTF_BLE("addExtraCharacteristics %d\r\n", charIndex);
 		characteristics[charIndex++] = &bootKeyboardInputReportCharacteristic;
 		characteristics[charIndex++] = &bootKeyboardOutputReportCharacteristic;
+		characteristics[charIndex++] = &consumerInputReportCharacteristic;
 	}
 
 	virtual ble_error_t send(const report_t report) {
@@ -216,6 +259,18 @@
 		}
 	}
 
+	void pressConsumerKey(const uint16_t key) {
+		consumerInputReportData.key = key;
+		hasPendingConsumerInputReport = true;
+		sendAvailable = true;
+	}
+
+	void releaseConsumerKey() {
+		consumerInputReportData.key = 0;
+		hasPendingConsumerInputReport = true;
+		sendAvailable = true;
+	}
+
 	void queueCurrentReportData() {
 		DEBUG_PRINTF_BLE("Q %d\r\n", bufferCount);
 		bufferCount++;
@@ -251,6 +306,15 @@
 			return;
 		}
 		sendAvailable = false;
+
+		if (hasPendingConsumerInputReport) {
+			ble.gattServer().write(
+				consumerInputReportCharacteristic.getValueHandle(),
+				(uint8_t*)&consumerInputReportData,
+				sizeof(consumerInputReportData)
+			);
+			hasPendingConsumerInputReport = false;
+		}
 		
 		// isSending の場合現在送信中の report があり、再送中である可能性がある
 		// そうではない場合のみ queue から pop して新しく send する
--- a/keymap.h	Thu Sep 15 08:48:57 2016 +0900
+++ b/keymap.h	Thu Sep 15 09:31:05 2016 +0900
@@ -38,6 +38,14 @@
 		DEBUG_PRINTF_KEYEVENT("LAYER->%d\r\n", keymap.layer);
 	}
 
+	static void consumer_play_pause(Keymap& keymap, const bool pressed) {
+		if (pressed) {
+			HIDController::pressConsumerKey(0x00cd);
+		} else {
+			HIDController::releaseConsumerKey();
+		}
+	}
+
 	void execute(const int row, const int col, const bool pressed) {
 		for (int i = 0; ; i++) {
 			const keyfunc_t& keyfunc = KEYMAP_FUNCTIONS[i];
@@ -100,6 +108,7 @@
 
 const keyfunc_t Keymap::KEYMAP_FUNCTIONS[] = {
 	{ 5, 14, &Keymap::switch_layer },
+	{ 5, 5, &Keymap::consumer_play_pause },
 	{ -1, -1, 0 } /* for iteration */
 };