Advanced Computer Systems - Bluetooth Clicker Project
Adel Zoabi - 305141418
Karim Mahamed - 302383682
What We Did
At first we did research about the HID over GATT Profile according to Bluetooth Docs.
This in order to list down all profiles that we needed to include into the project before putting down the design.
Our project was based on the ProjectZero template that we imported from SimpleLinkAcademy repos. We had to add the following profile dependencies:
- HID Device Profile
- Generic Attribute Profile (GATT)
- Battery Service Profile
- Device Information Profile
- Scan Parameters Profile
Having added the above-mentioned profiles it was necessary to implement the HID Keyboard Service by registering and linking GATT attributes to the GATT server (in this case, the CC2650 chip)
The implementation of the HID Keyboard Service is composed of:
- The HID Keyboard Input Report (Read, Notify)
- [Since our CC2650 behaves like a keyboard then we added the notify characteristic to notify the client upon keypress event]
- The HID Keyboard Output Report (Read, Write, Write&NoResponse)
- [LED Output e.g. CAPS Lock button click feedback]
- HID Information Characteristics - Keyboard Descriptors
The HID Keyboard Service works with a specific message type and these specs we found in this link
The message structure is defined in a struct object defined in the GATT Profile, which we included in our project.
For a short summary of the Keyboard Service implementation:
- Initiation of GAP Role parameters
- Starting the HID Keyboad Service
- Registeration of the HID callback function (to listen for incoming events)
- Initiate the HID
Additionally, we had to initiate the board key handlers. The KeyPress handler sends HID reports containing the following:
- TYPE: HID_REPORT_TYPE_INPUT
- VALUE: as illustrated in the USB Keyboard HID Protocol: [modifier, reserved, Key1, Key2, Key3, Key4, Key6, Key7]
- Key1: the main key that has been entered\pressed
- modifier: the key that modifies the meaning of a report key press, e.g. when a keyboard registers an event of Shift+a, the HID Keyboard Service will report [2, 0, 4, 0, 0, 0, 0, 0]
- *The exact form of the protocol we found in the following link
We have used the App Event Struct as defined in the util common function declarations. The use of this struct is to enqueue incoming press events in a message queue to keep track of all events.
Then, we created a Task with an infinite loop that operates as message queue processor to handle each KeyPress event. This handler knows how to translate press events to keyboard recognized characters.
As an initial proof of concept, we have registered the two existing buttons on the CC2650 to be translated into the characters 'A' and 'B' when clicking the Left and Right buttons accordingly.
EXTRA: We designed an extension to overcome the limitation of existing physical buttons on the board. To do so, we added the PIN_DIO22 to the board events handlers, and we handled the PIN pullup as a key press. From this point, we can enqueue the event to the message queue. The design of the handler is abstract, meaning that the rest of the translation fits in the above-mentioned procedure. (Regardless of how the event was registered).
We went even further by connecting a physical button to a breadboard that closes a circuit between the DIO22 PIN and the 5 volts PIN. This recreated a physical button, and equivalently could add more buttons (up to the amount of available pins).
This setup (3 physical buttons) motivated us to implement a simple binary keyboard. The two buttons on the CC2650 will be utilized as the 0 and 1 binary inputs. The third button will be the RETURN. The app will receive a binary input from the Chip and evaluate the ASCI value of an octet of bits, and append them to some output.
Demonstration on live.
Problems & Solutions
- We noticed in the debugging sessions that when fixing a breakpoint throughout an active Bluetooth connection, if the breakpoint has been idle for a prolonged amount of time, the connection between the devices would be lost.
- How we solved this: It turned out that according to the BLE protocol of communication, there's a connection interval between two subsequent packets of data. When a gap is produced and no two packets are received within this window of time the 'Master' will assume that the connection was lost abruptly, and thus terminating the connection. So in debug sessions, we tried to avoid settings breakpoints around Bluetooth send/receive commands. (unless it was crucial)
- Unable to receive visible KeyPress feedback from the Smartphone even after establishing Bluetooth connection.
- How we solved this: Turned out that we did not fill the protocol struct exactly as instructed in the relevant documentations which more than likely caused unexpected behviours on the receiving peer. We were able to solve the problem by filling the struct (padding when needed) EXACTLY as illustrated.
- We found out about the missing parameters by sniffing using WireShark, and patching the struct till we eventually reached a healthy state communication.
- Laggy reception of key presses where we noticed that some button presses responded slowly or did not register at all, meaning that the press button did not print the relevant character on the Smartphone's console. Apparently this was due to a faulty scheduling system that discarded some press events, which led to inaccurate feedback.
- How we solved this: Turned out that our Semaphore design was not enough to store all the clicks. We overcame this by implementing a queue in order to store all KeyPress events. These events were fairly easy to be captured using the enqueue function at a 100% accuracy rate. Then the event handler processor was to later process the top of the queue, if not empty and not busy.
- CC2650 is not discoverable by any Bluetooth ready device
- How we solved this: This was not exactly a blocking issue, however, it was very interesting because we noticed that this issue would only occur when the compiling laptop was on Battery mode. Apparently, when the laptop is on Battery mode the power delivered to the USB ports is limited. This power is surprisingly not enough to power on a Bluetooth broadcasting program.
The project was of fairly moderate difficulty and definitely put to use all theoretical and practical material that we learned in class. In addition, We learned many other project related things on the individual aspect from difficulties that we faced while developing.