back up of work during May 2019
Dependencies: microbit
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 "HIDServiceBase.h" 00019 00020 HIDServiceBase::HIDServiceBase(BLE &_ble, 00021 report_map_t reportMap, 00022 uint8_t reportMapSize, 00023 report_t inputReport, 00024 report_t outputReport, 00025 report_t featureReport, 00026 uint8_t inputReportLength, 00027 uint8_t outputReportLength, 00028 uint8_t featureReportLength, 00029 uint8_t inputReportTickerDelay) : 00030 ble(_ble), 00031 connected (false), 00032 reportMapLength(reportMapSize), 00033 00034 inputReport(inputReport), 00035 outputReport(outputReport), 00036 featureReport(featureReport), 00037 00038 inputReportLength(inputReportLength), 00039 outputReportLength(outputReportLength), 00040 featureReportLength(featureReportLength), 00041 00042 protocolMode(REPORT_PROTOCOL), 00043 00044 inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, 00045 (uint8_t *)&inputReportReferenceData, 2, 2), 00046 outputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, 00047 (uint8_t *)&outputReportReferenceData, 2, 2), 00048 featureReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE, 00049 (uint8_t *)&featureReportReferenceData, 2, 2), 00050 00051 protocolModeCharacteristic(GattCharacteristic::UUID_PROTOCOL_MODE_CHAR, &protocolMode, 1, 1, 00052 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ 00053 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 00054 00055 inputReportCharacteristic(GattCharacteristic::UUID_REPORT_CHAR, 00056 (uint8_t *)inputReport, inputReportLength, inputReportLength, 00057 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ 00058 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY 00059 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, 00060 inputReportDescriptors(), 1), 00061 00062 outputReportCharacteristic(GattCharacteristic::UUID_REPORT_CHAR, 00063 (uint8_t *)outputReport, outputReportLength, outputReportLength, 00064 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ 00065 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE 00066 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, 00067 outputReportDescriptors(), 1), 00068 00069 featureReportCharacteristic(GattCharacteristic::UUID_REPORT_CHAR, 00070 (uint8_t *)featureReport, featureReportLength, featureReportLength, 00071 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ 00072 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, 00073 featureReportDescriptors(), 1), 00074 00075 /* 00076 * We need to set reportMap content as const, in order to let the compiler put it into flash 00077 * instead of RAM. The characteristic is read-only so it won't be written, but 00078 * GattCharacteristic constructor takes non-const arguments only. Hence the cast. 00079 */ 00080 reportMapCharacteristic(GattCharacteristic::UUID_REPORT_MAP_CHAR, 00081 const_cast<uint8_t*>(reportMap), reportMapLength, reportMapLength, 00082 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 00083 00084 HIDInformationCharacteristic(GattCharacteristic::UUID_HID_INFORMATION_CHAR, HIDInformation()), 00085 HIDControlPointCharacteristic(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, 00086 &controlPointCommand, 1, 1, 00087 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 00088 00089 reportTickerDelay(inputReportTickerDelay), 00090 reportTickerIsActive(false) 00091 { 00092 static GattCharacteristic *characteristics[] = { 00093 &HIDInformationCharacteristic, 00094 &reportMapCharacteristic, 00095 &protocolModeCharacteristic, 00096 &HIDControlPointCharacteristic, 00097 NULL, 00098 NULL, 00099 NULL, 00100 NULL, 00101 NULL 00102 }; 00103 00104 unsigned int charIndex = 4; 00105 /* 00106 * Report characteristics are optional, and depend on the reportMap descriptor 00107 * Note: at least one should be present, but we don't check that at the moment. 00108 */ 00109 if (inputReportLength) 00110 characteristics[charIndex++] = &inputReportCharacteristic; 00111 if (outputReportLength) 00112 characteristics[charIndex++] = &outputReportCharacteristic; 00113 if (featureReportLength) 00114 characteristics[charIndex++] = &featureReportCharacteristic; 00115 00116 /* TODO: let children add some more characteristics, namely boot keyboard and mouse (They are 00117 * mandatory as per HIDS spec.) Ex: 00118 * 00119 * addExtraCharacteristics(characteristics, int& charIndex); 00120 */ 00121 00122 GattService service(GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, 00123 characteristics, charIndex); 00124 00125 ble.gattServer().addService(service); 00126 00127 ble.gap().onConnection(this, &HIDServiceBase::onConnection); 00128 ble.gap().onDisconnection(this, &HIDServiceBase::onDisconnection); 00129 00130 ble.gattServer().onDataSent(this, &HIDServiceBase::onDataSent); 00131 00132 /* 00133 * Change preferred connection params, in order to optimize the notification frequency. Most 00134 * OSes seem to respect this, even though they are not required to. 00135 * 00136 * Some OSes don't handle reconnection well, at the moment, so we set the maximum possible 00137 * timeout, 32 seconds 00138 */ 00139 uint16_t minInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(reportTickerDelay / 2); 00140 if (minInterval < 6) 00141 minInterval = 6; 00142 uint16_t maxInterval = minInterval * 2; 00143 Gap::ConnectionParams_t params = {minInterval, maxInterval, 0, 3200}; 00144 00145 ble.gap().setPreferredConnectionParams(¶ms); 00146 00147 SecurityManager::SecurityMode_t securityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM; 00148 protocolModeCharacteristic.requireSecurity(securityMode); 00149 reportMapCharacteristic.requireSecurity(securityMode); 00150 inputReportCharacteristic.requireSecurity(securityMode); 00151 outputReportCharacteristic.requireSecurity(securityMode); 00152 featureReportCharacteristic.requireSecurity(securityMode); 00153 } 00154 00155 void HIDServiceBase::startReportTicker(void) { 00156 if (reportTickerIsActive) 00157 return; 00158 reportTicker.attach_us(this, &HIDServiceBase::sendCallback, reportTickerDelay * 1000); 00159 reportTickerIsActive = true; 00160 } 00161 00162 void HIDServiceBase::stopReportTicker(void) { 00163 reportTicker.detach(); 00164 reportTickerIsActive = false; 00165 } 00166 00167 void HIDServiceBase::onDataSent(unsigned count) { 00168 startReportTicker(); 00169 } 00170 00171 GattAttribute** HIDServiceBase::inputReportDescriptors() { 00172 inputReportReferenceData.ID = 0; 00173 inputReportReferenceData.type = INPUT_REPORT; 00174 00175 static GattAttribute * descs[] = { 00176 &inputReportReferenceDescriptor, 00177 }; 00178 return descs; 00179 } 00180 00181 GattAttribute** HIDServiceBase::outputReportDescriptors() { 00182 outputReportReferenceData.ID = 0; 00183 outputReportReferenceData.type = OUTPUT_REPORT; 00184 00185 static GattAttribute * descs[] = { 00186 &outputReportReferenceDescriptor, 00187 }; 00188 return descs; 00189 } 00190 00191 GattAttribute** HIDServiceBase::featureReportDescriptors() { 00192 featureReportReferenceData.ID = 0; 00193 featureReportReferenceData.type = FEATURE_REPORT; 00194 00195 static GattAttribute * descs[] = { 00196 &featureReportReferenceDescriptor, 00197 }; 00198 return descs; 00199 } 00200 00201 00202 HID_information_t* HIDServiceBase::HIDInformation() { 00203 static HID_information_t info = {HID_VERSION_1_11, 0x00, 0x03}; 00204 printf("read hid information\n"); 00205 00206 return &info; 00207 } 00208 00209 ble_error_t HIDServiceBase::send(const report_t report) { 00210 return ble.gattServer().write(inputReportCharacteristic.getValueHandle(), 00211 report, 00212 inputReportLength); 00213 } 00214 00215 ble_error_t HIDServiceBase::read(report_t report) { 00216 // TODO. For the time being, we'll just have HID input reports... 00217 printf("read not implemented\n"); 00218 return BLE_ERROR_NOT_IMPLEMENTED; 00219 } 00220 00221 void HIDServiceBase::onConnection(const Gap::ConnectionCallbackParams_t *params) 00222 { 00223 this->connected = true; 00224 } 00225 00226 void HIDServiceBase::onDisconnection(const Gap::DisconnectionCallbackParams_t *params) 00227 { 00228 this->connected = false; 00229 } 00230
Generated on Mon Jul 18 2022 14:25:12 by 1.7.2