ble nano hid over gatt

Dependencies:   BLE_API mbed-dev nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HIDServiceBase.cpp Source File

HIDServiceBase.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "config.h"
00019 #include "HIDServiceBase.h"
00020 
00021 static const report_reference_t inputReportReferenceData = { 1, INPUT_REPORT };
00022 static const GattAttribute inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&inputReportReferenceData, 2, 2, false);
00023 static const GattAttribute * inputReportDescriptors[] = {
00024     &inputReportReferenceDescriptor,
00025 };
00026 
00027 static const report_reference_t outputReportReferenceData = { 1, OUTPUT_REPORT };
00028 static const GattAttribute outputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&outputReportReferenceData, 2, 2, false);
00029 static const GattAttribute * outputReportDescriptors[] = {
00030     &outputReportReferenceDescriptor,
00031 };
00032 
00033 
00034 static const report_reference_t featureReportReferenceData = { 1, FEATURE_REPORT };
00035 static const GattAttribute featureReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, (uint8_t *)&featureReportReferenceData, 2, 2, false);
00036 static const GattAttribute * featureReportDescriptors[] = {
00037     &featureReportReferenceDescriptor,
00038 };
00039 
00040 // static const uint16_t reportMapExternalReportReferenceData = GattCharacteristic::UUID_BATTERY_LEVEL_CHAR;
00041 static const uint8_t reportMapExternalReportReferenceData[] = { 0x2A, 0x19 };
00042 static const GattAttribute reportMapExternalReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_EXTERNAL_REPORT_REFERENCE, (uint8_t *)&reportMapExternalReportReferenceData, 2, 2, false);
00043 static const GattAttribute * reportMapDescriptors[] = {
00044     &reportMapExternalReportReferenceDescriptor,
00045 };
00046 
00047 #define HID_REMOTE_WAKE_Pos 0
00048 #define HID_NORMALLY_CONNECTABLE_Pos 1
00049 static const HID_information_t HID_information = {
00050     HID_VERSION_1_11,
00051     0x00,
00052     (1<<HID_REMOTE_WAKE_Pos) |
00053     (0<<HID_NORMALLY_CONNECTABLE_Pos)
00054 };
00055 
00056 HIDServiceBase::HIDServiceBase(
00057     BLE          &_ble,
00058     report_map_t reportMap,
00059     uint8_t      reportMapSize,
00060     report_t     inputReport,
00061     report_t     outputReport,
00062     report_t     featureReport,
00063     uint8_t      inputReportLength,
00064     uint8_t      outputReportLength,
00065     uint8_t      featureReportLength
00066 ) :
00067 
00068     ble(_ble),
00069     connected (false),
00070     reportMapLength(reportMapSize),
00071 
00072     inputReport(inputReport),
00073     outputReport(outputReport),
00074     featureReport(featureReport),
00075 
00076     inputReportLength(inputReportLength),
00077     outputReportLength(outputReportLength),
00078     featureReportLength(featureReportLength),
00079 
00080     protocolMode(REPORT_PROTOCOL),
00081 
00082     protocolModeCharacteristic(
00083         GattCharacteristic::UUID_PROTOCOL_MODE_CHAR, &protocolMode, 1, 1,
00084         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ
00085         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE
00086     ),
00087 
00088     inputReportCharacteristic(
00089         GattCharacteristic::UUID_REPORT_CHAR,
00090         (uint8_t *)inputReport, inputReportLength, inputReportLength,
00091         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ
00092         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
00093         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE,
00094         const_cast<GattAttribute**>(inputReportDescriptors), 1
00095     ),
00096 
00097     outputReportCharacteristic(
00098         GattCharacteristic::UUID_REPORT_CHAR,
00099         (uint8_t *)outputReport, outputReportLength, outputReportLength,
00100         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ
00101         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE
00102         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE,
00103         const_cast<GattAttribute**>(outputReportDescriptors), 1
00104     ),
00105 
00106     featureReportCharacteristic(
00107         GattCharacteristic::UUID_REPORT_CHAR,
00108         (uint8_t *)featureReport, featureReportLength, featureReportLength,
00109         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ
00110         | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE,
00111         const_cast<GattAttribute**>(featureReportDescriptors), 1
00112     ),
00113 
00114     /*
00115      * We need to set reportMap content as const, in order to let the compiler put it into flash
00116      * instead of RAM. The characteristic is read-only so it won't be written, but
00117      * GattCharacteristic constructor takes non-const arguments only. Hence the cast.
00118      */
00119     reportMapCharacteristic(
00120         GattCharacteristic::UUID_REPORT_MAP_CHAR,
00121         const_cast<uint8_t*>(reportMap), reportMapLength, reportMapLength,
00122         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ,
00123         const_cast<GattAttribute**>(reportMapDescriptors), 1
00124     ),
00125 
00126     HIDInformationCharacteristic(
00127         GattCharacteristic::UUID_HID_INFORMATION_CHAR,
00128         const_cast<HID_information_t*>(&HID_information)
00129     ),
00130 
00131     HIDControlPointCharacteristic(
00132         GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR,
00133         &controlPointCommand, 1, 1,
00134         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE
00135     )
00136 {
00137 }
00138 
00139 void HIDServiceBase::init(void) {
00140     static GattCharacteristic *characteristics[] = {
00141         &reportMapCharacteristic,
00142         &protocolModeCharacteristic,
00143         &HIDControlPointCharacteristic,
00144         &HIDInformationCharacteristic,
00145         NULL,
00146         NULL,
00147         NULL,
00148         NULL,
00149         NULL
00150     };
00151 
00152     uint8_t charIndex = 4;
00153     /*
00154      * Report characteristics are optional, and depend on the reportMap descriptor
00155      * Note: at least one should be present, but we don't check that at the moment.
00156      */
00157     if (inputReportLength)
00158         characteristics[charIndex++] = &inputReportCharacteristic;
00159     if (outputReportLength)
00160         characteristics[charIndex++] = &outputReportCharacteristic;
00161     if (featureReportLength)
00162         characteristics[charIndex++] = &featureReportCharacteristic;
00163 
00164     addExtraCharacteristics(characteristics, charIndex);
00165 
00166     DEBUG_PRINTF_BLE("new GattService %d\r\n", charIndex);
00167     GattService service(GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, characteristics, charIndex);
00168 
00169     ble.gattServer().addService(service);
00170 
00171     ble.gap().onConnection(this, &HIDServiceBase::onConnection);
00172     ble.gap().onDisconnection(this, &HIDServiceBase::onDisconnection);
00173 
00174     ble.gattServer().onDataSent(this, &HIDServiceBase::onDataSent);
00175     ble.gattServer().onDataWritten(this, &HIDServiceBase::onDataWritten);
00176 
00177     SecurityManager::SecurityMode_t securityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
00178     protocolModeCharacteristic.requireSecurity(securityMode);
00179     reportMapCharacteristic.requireSecurity(securityMode);
00180     inputReportCharacteristic.requireSecurity(securityMode);
00181     outputReportCharacteristic.requireSecurity(securityMode);
00182     featureReportCharacteristic.requireSecurity(securityMode);
00183 }
00184 
00185 void HIDServiceBase::onDataSent(unsigned count) {
00186 }
00187 
00188 void HIDServiceBase::onDataWritten(const GattWriteCallbackParams *params) {
00189 }
00190 
00191 void HIDServiceBase::addExtraCharacteristics(GattCharacteristic** characteristics, uint8_t& charIndex) {
00192 }
00193 
00194 ble_error_t HIDServiceBase::send(const report_t report) {
00195     return ble.gattServer().write(
00196         inputReportCharacteristic.getValueHandle(),
00197         report,
00198         inputReportLength
00199     );
00200 }
00201 
00202 ble_error_t HIDServiceBase::read(report_t report) {
00203     // TODO. For the time being, we'll just have HID input reports...
00204     return BLE_ERROR_NOT_IMPLEMENTED;
00205 }
00206 
00207 void HIDServiceBase::onConnection(const Gap::ConnectionCallbackParams_t *params) {
00208     this->connected = true;
00209 }
00210 
00211 void HIDServiceBase::onDisconnection(const Gap::DisconnectionCallbackParams_t *params) {
00212     this->connected = false;
00213 }