Diff: BLE_HID/MouseService.h
- Revision:
- 1:032b96b05e51
diff -r 0041f35b0c4c -r 032b96b05e51 BLE_HID/MouseService.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/BLE_HID/MouseService.h Wed Jun 12 15:21:01 2019 +0000
@@ -0,0 +1,220 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+
+#include "HIDServiceBase.h"
+
+enum ButtonState
+{
+ BUTTON_UP,
+ BUTTON_DOWN
+};
+
+enum MouseButton
+{
+ MOUSE_BUTTON_LEFT = 0x1,
+ MOUSE_BUTTON_RIGHT = 0x2,
+ MOUSE_BUTTON_MIDDLE = 0x4,
+};
+
+/**
+ * Report descriptor for a standard 3 buttons + wheel mouse with relative X/Y
+ * moves
+ */
+report_map_t MOUSE_REPORT_MAP = {
+ USAGE_PAGE(1), 0x01, // Generic Desktop
+ USAGE(1), 0x02, // Mouse
+ COLLECTION(1), 0x01, // Application
+ USAGE(1), 0x01, // Pointer
+ COLLECTION(1), 0x00, // Physical
+ USAGE_PAGE(1), 0x09, // Buttons
+ USAGE_MINIMUM(1), 0x01,
+ USAGE_MAXIMUM(1), 0x03,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x01,
+ REPORT_COUNT(1), 0x03, // 3 bits (Buttons)
+ REPORT_SIZE(1), 0x01,
+ INPUT(1), 0x02, // Data, Variable, Absolute
+ REPORT_COUNT(1), 0x01, // 5 bits (Padding)
+ REPORT_SIZE(1), 0x05,
+ INPUT(1), 0x01, // Constant
+ USAGE_PAGE(1), 0x01, // Generic Desktop
+ USAGE(1), 0x30, // X
+ USAGE(1), 0x31, // Y
+ USAGE(1), 0x38, // Wheel
+ LOGICAL_MINIMUM(1), 0x81, // -127
+ LOGICAL_MAXIMUM(1), 0x7f, // 127
+ REPORT_SIZE(1), 0x08, // Three bytes
+ REPORT_COUNT(1), 0x03,
+ INPUT(1), 0x06, // Data, Variable, Relative
+ END_COLLECTION(0),
+ END_COLLECTION(0),
+};
+
+uint8_t report[] = { 0, 0, 0, 0 };
+
+/**
+ * @class MouseService
+ * @brief HID-over-Gatt mouse service.
+ *
+ * Send mouse moves and button informations over BLE.
+ *
+ * @code
+ * BLE ble;
+ * MouseService mouse(ble);
+ *
+ * Timeout timeout;
+ *
+ * void stop_mouse_move(void)
+ * {
+ * // Set mouse state to immobile
+ * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_UP);
+ * mouse.setSpeed(0, 0, 0);
+ * }
+ *
+ * void start_mouse_move(void)
+ * {
+ * // Move left with a left button down. If the focus is on a drawing
+ * // software, for instance, this should draw a line.
+ * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_DOWN);
+ * mouse.setSpeed(1, 0, 0);
+ *
+ * timeout.attach(stop_mouse_move, 0.2);
+ * }
+ * @endcode
+ */
+class MouseService: public HIDServiceBase
+{
+public:
+ MouseService(BLE &_ble) :
+ HIDServiceBase(_ble,
+ MOUSE_REPORT_MAP, sizeof(MOUSE_REPORT_MAP),
+ inputReport = report,
+ outputReport = NULL,
+ featureReport = NULL,
+ inputReportLength = sizeof(inputReport),
+ outputReportLength = 0,
+ featureReportLength = 0,
+ reportTickerDelay = 20),
+ buttonsState (0),
+ failedReports (0)
+ {
+ speed[0] = 0;
+ speed[1] = 0;
+ speed[2] = 0;
+
+ startReportTicker();
+ }
+
+ void onConnection(const Gap::ConnectionCallbackParams_t *params)
+ {
+ HIDServiceBase::onConnection(params);
+ startReportTicker();
+ }
+
+ void onDisconnection(const Gap::DisconnectionCallbackParams_t *params)
+ {
+ stopReportTicker();
+ HIDServiceBase::onDisconnection(params);
+ }
+
+ /**
+ * Set X, Y, Z speed of the mouse. Parameters are sticky and will be
+ * transmitted on every tick. Users should therefore reset them to 0 when
+ * the device is immobile.
+ *
+ * @param x Speed on hoizontal axis
+ * @param y Speed on vertical axis
+ * @param wheel Scroll speed
+ *
+ * @returns A status code
+ *
+ * @note Directions depend on the operating system's configuration. It is
+ * customary to increase values on the X axis from left to right, and on the
+ * Y axis from top to bottom.
+ * Wheel is less standard, although positive values will usually scroll up.
+ */
+ int setSpeed(int8_t x, int8_t y, int8_t wheel)
+ {
+ speed[0] = x;
+ speed[1] = y;
+ speed[2] = wheel;
+
+ startReportTicker();
+
+ return 0;
+ }
+
+ /**
+ * Toggle the state of one button
+ *
+ * @returns A status code
+ */
+ int setButton(MouseButton button, ButtonState state)
+ {
+ if (state == BUTTON_UP)
+ buttonsState &= ~(button);
+ else
+ buttonsState |= button;
+
+ startReportTicker();
+
+ return 0;
+ }
+
+ /**
+ * Called by the report ticker
+ */
+ virtual void sendCallback(void) {
+ uint8_t buttons = buttonsState & 0x7;
+
+ if (!connected)
+ return;
+
+ bool can_sleep = (report[0] == 0
+ && report[1] == 0
+ && report[2] == 0
+ && report[3] == 0
+ && report[0] == buttons
+ && report[1] == speed[0]
+ && report[2] == speed[1]
+ && report[3] == speed[2]);
+
+ if (can_sleep) {
+ /* TODO: find out why there always is two more calls to sendCallback after this
+ * stopReportTicker(). */
+ stopReportTicker();
+ return;
+ }
+
+ report[0] = buttons;
+ report[1] = speed[0];
+ report[2] = speed[1];
+ report[3] = speed[2];
+
+ if (send(report))
+ failedReports++;
+ }
+
+protected:
+ uint8_t buttonsState;
+ uint8_t speed[3];
+
+public:
+ uint32_t failedReports;
+};
+