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
main.cpp@0:be89b5fdea09, 2016-07-17 (annotated)
- Committer:
- cho45
- Date:
- Sun Jul 17 23:08:32 2016 +0000
- Revision:
- 0:be89b5fdea09
- Child:
- 2:c2e3f240640c
work for osx;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| cho45 | 0:be89b5fdea09 | 1 | /* mbed Microcontroller Library |
| cho45 | 0:be89b5fdea09 | 2 | * Copyright (c) 2015 ARM Limited |
| cho45 | 0:be89b5fdea09 | 3 | * |
| cho45 | 0:be89b5fdea09 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| cho45 | 0:be89b5fdea09 | 5 | * you may not use this file except in compliance with the License. |
| cho45 | 0:be89b5fdea09 | 6 | * You may obtain a copy of the License at |
| cho45 | 0:be89b5fdea09 | 7 | * |
| cho45 | 0:be89b5fdea09 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| cho45 | 0:be89b5fdea09 | 9 | * |
| cho45 | 0:be89b5fdea09 | 10 | * Unless required by applicable law or agreed to in writing, software |
| cho45 | 0:be89b5fdea09 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| cho45 | 0:be89b5fdea09 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| cho45 | 0:be89b5fdea09 | 13 | * See the License for the specific language governing permissions and |
| cho45 | 0:be89b5fdea09 | 14 | * limitations under the License. |
| cho45 | 0:be89b5fdea09 | 15 | */ |
| cho45 | 0:be89b5fdea09 | 16 | |
| cho45 | 0:be89b5fdea09 | 17 | #include "mbed.h" |
| cho45 | 0:be89b5fdea09 | 18 | #include "BLE.h" |
| cho45 | 0:be89b5fdea09 | 19 | #include "KeyboardService.h" |
| cho45 | 0:be89b5fdea09 | 20 | #include "BatteryService.h" |
| cho45 | 0:be89b5fdea09 | 21 | #include "DeviceInformationService.h" |
| cho45 | 0:be89b5fdea09 | 22 | |
| cho45 | 0:be89b5fdea09 | 23 | static const char MODEL_NAME[] = "keyboard"; |
| cho45 | 0:be89b5fdea09 | 24 | static const char SERIAL_NUMBER[] = "X00000"; |
| cho45 | 0:be89b5fdea09 | 25 | static const char HARDWARE_REVISION[] = "0.1"; |
| cho45 | 0:be89b5fdea09 | 26 | static const char FIRMWARE_REVISION[] = "0.1"; |
| cho45 | 0:be89b5fdea09 | 27 | static const char SOFTWARE_REVISION[] = "0.0"; |
| cho45 | 0:be89b5fdea09 | 28 | |
| cho45 | 0:be89b5fdea09 | 29 | static const uint8_t DEVICE_NAME[] = "my keyboard"; |
| cho45 | 0:be89b5fdea09 | 30 | static const uint8_t SHORT_DEVICE_NAME[] = "kbd1"; |
| cho45 | 0:be89b5fdea09 | 31 | |
| cho45 | 0:be89b5fdea09 | 32 | InterruptIn button1(D2); |
| cho45 | 0:be89b5fdea09 | 33 | |
| cho45 | 0:be89b5fdea09 | 34 | |
| cho45 | 0:be89b5fdea09 | 35 | static const uint16_t uuid16_list[] = { |
| cho45 | 0:be89b5fdea09 | 36 | GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, |
| cho45 | 0:be89b5fdea09 | 37 | GattService::UUID_DEVICE_INFORMATION_SERVICE, |
| cho45 | 0:be89b5fdea09 | 38 | GattService::UUID_BATTERY_SERVICE |
| cho45 | 0:be89b5fdea09 | 39 | }; |
| cho45 | 0:be89b5fdea09 | 40 | |
| cho45 | 0:be89b5fdea09 | 41 | KeyboardService* keyboardService; |
| cho45 | 0:be89b5fdea09 | 42 | BatteryService* batteryService; |
| cho45 | 0:be89b5fdea09 | 43 | DeviceInformationService* deviceInformationService; |
| cho45 | 0:be89b5fdea09 | 44 | |
| cho45 | 0:be89b5fdea09 | 45 | // I2C i2c(D2, D3); |
| cho45 | 0:be89b5fdea09 | 46 | // AnalogIn batteryInput(A4); |
| cho45 | 0:be89b5fdea09 | 47 | |
| cho45 | 0:be89b5fdea09 | 48 | static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) { |
| cho45 | 0:be89b5fdea09 | 49 | printf("onDisconnect\r\n"); |
| cho45 | 0:be89b5fdea09 | 50 | BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); |
| cho45 | 0:be89b5fdea09 | 51 | } |
| cho45 | 0:be89b5fdea09 | 52 | |
| cho45 | 0:be89b5fdea09 | 53 | |
| cho45 | 0:be89b5fdea09 | 54 | static void onConnect(const Gap::ConnectionCallbackParams_t *params) { |
| cho45 | 0:be89b5fdea09 | 55 | printf("onConnect\r\n"); |
| cho45 | 0:be89b5fdea09 | 56 | } |
| cho45 | 0:be89b5fdea09 | 57 | |
| cho45 | 0:be89b5fdea09 | 58 | |
| cho45 | 0:be89b5fdea09 | 59 | static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) { |
| cho45 | 0:be89b5fdea09 | 60 | printf("Input passKey: "); |
| cho45 | 0:be89b5fdea09 | 61 | for (unsigned i = 0; i < Gap::ADDR_LEN; i++) { |
| cho45 | 0:be89b5fdea09 | 62 | printf("%c", passkey[i]); |
| cho45 | 0:be89b5fdea09 | 63 | } |
| cho45 | 0:be89b5fdea09 | 64 | printf("\r\n"); |
| cho45 | 0:be89b5fdea09 | 65 | } |
| cho45 | 0:be89b5fdea09 | 66 | |
| cho45 | 0:be89b5fdea09 | 67 | static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) |
| cho45 | 0:be89b5fdea09 | 68 | { |
| cho45 | 0:be89b5fdea09 | 69 | if (status == SecurityManager::SEC_STATUS_SUCCESS) { |
| cho45 | 0:be89b5fdea09 | 70 | printf("Security success %d\r\n", status); |
| cho45 | 0:be89b5fdea09 | 71 | } else { |
| cho45 | 0:be89b5fdea09 | 72 | printf("Security failed %d\r\n", status); |
| cho45 | 0:be89b5fdea09 | 73 | } |
| cho45 | 0:be89b5fdea09 | 74 | } |
| cho45 | 0:be89b5fdea09 | 75 | |
| cho45 | 0:be89b5fdea09 | 76 | static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) |
| cho45 | 0:be89b5fdea09 | 77 | { |
| cho45 | 0:be89b5fdea09 | 78 | printf("Security setup initiated\r\n"); |
| cho45 | 0:be89b5fdea09 | 79 | } |
| cho45 | 0:be89b5fdea09 | 80 | |
| cho45 | 0:be89b5fdea09 | 81 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { |
| cho45 | 0:be89b5fdea09 | 82 | BLE &ble = params->ble; |
| cho45 | 0:be89b5fdea09 | 83 | ble_error_t error = params->error; |
| cho45 | 0:be89b5fdea09 | 84 | |
| cho45 | 0:be89b5fdea09 | 85 | if (error != BLE_ERROR_NONE) { |
| cho45 | 0:be89b5fdea09 | 86 | printf("error on ble.init() \r\n"); |
| cho45 | 0:be89b5fdea09 | 87 | return; |
| cho45 | 0:be89b5fdea09 | 88 | } |
| cho45 | 0:be89b5fdea09 | 89 | |
| cho45 | 0:be89b5fdea09 | 90 | ble.gap().onDisconnection(onDisconnect); |
| cho45 | 0:be89b5fdea09 | 91 | ble.gap().onConnection(onConnect); |
| cho45 | 0:be89b5fdea09 | 92 | |
| cho45 | 0:be89b5fdea09 | 93 | |
| cho45 | 0:be89b5fdea09 | 94 | bool enableBonding = true; |
| cho45 | 0:be89b5fdea09 | 95 | bool requireMITM = true; |
| cho45 | 0:be89b5fdea09 | 96 | uint8_t passkey[] = "123456"; |
| cho45 | 0:be89b5fdea09 | 97 | |
| cho45 | 0:be89b5fdea09 | 98 | printf("setup ble security manager\r\n"); |
| cho45 | 0:be89b5fdea09 | 99 | ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback); |
| cho45 | 0:be89b5fdea09 | 100 | ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback); |
| cho45 | 0:be89b5fdea09 | 101 | ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback); |
| cho45 | 0:be89b5fdea09 | 102 | // TODO |
| cho45 | 0:be89b5fdea09 | 103 | // ble.securityManager().init(true, true, SecurityManager::IO_CAPS_DISPLAY_ONLY); |
| cho45 | 0:be89b5fdea09 | 104 | // ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_KEYBOARD_ONLY, passkey); |
| cho45 | 0:be89b5fdea09 | 105 | // ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE); |
| cho45 | 0:be89b5fdea09 | 106 | ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, passkey); |
| cho45 | 0:be89b5fdea09 | 107 | |
| cho45 | 0:be89b5fdea09 | 108 | keyboardService = new KeyboardService(ble); |
| cho45 | 0:be89b5fdea09 | 109 | deviceInformationService = new DeviceInformationService(ble, "lowreal.net", MODEL_NAME, SERIAL_NUMBER, HARDWARE_REVISION, FIRMWARE_REVISION, SOFTWARE_REVISION); |
| cho45 | 0:be89b5fdea09 | 110 | batteryService = new BatteryService(ble, 10); |
| cho45 | 0:be89b5fdea09 | 111 | |
| cho45 | 0:be89b5fdea09 | 112 | printf("general setup\r\n"); |
| cho45 | 0:be89b5fdea09 | 113 | ble.gap().accumulateAdvertisingPayload( |
| cho45 | 0:be89b5fdea09 | 114 | GapAdvertisingData::BREDR_NOT_SUPPORTED | |
| cho45 | 0:be89b5fdea09 | 115 | GapAdvertisingData::LE_GENERAL_DISCOVERABLE |
| cho45 | 0:be89b5fdea09 | 116 | ); |
| cho45 | 0:be89b5fdea09 | 117 | ble.gap().accumulateAdvertisingPayload( |
| cho45 | 0:be89b5fdea09 | 118 | GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, |
| cho45 | 0:be89b5fdea09 | 119 | (uint8_t*)uuid16_list, sizeof(uuid16_list) |
| cho45 | 0:be89b5fdea09 | 120 | ); |
| cho45 | 0:be89b5fdea09 | 121 | |
| cho45 | 0:be89b5fdea09 | 122 | printf("set advertising\r\n"); |
| cho45 | 0:be89b5fdea09 | 123 | // see 5.1.2: HID over GATT Specification (pg. 25) |
| cho45 | 0:be89b5fdea09 | 124 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
| cho45 | 0:be89b5fdea09 | 125 | printf("set advertising interval\r\n"); |
| cho45 | 0:be89b5fdea09 | 126 | ble.gap().setAdvertisingInterval(50); |
| cho45 | 0:be89b5fdea09 | 127 | // XXX |
| cho45 | 0:be89b5fdea09 | 128 | ble.gap().setAdvertisingTimeout(0); |
| cho45 | 0:be89b5fdea09 | 129 | |
| cho45 | 0:be89b5fdea09 | 130 | printf("set key board\r\n"); |
| cho45 | 0:be89b5fdea09 | 131 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD); |
| cho45 | 0:be89b5fdea09 | 132 | ble.gap().accumulateAdvertisingPayload( |
| cho45 | 0:be89b5fdea09 | 133 | GapAdvertisingData::COMPLETE_LOCAL_NAME, |
| cho45 | 0:be89b5fdea09 | 134 | DEVICE_NAME, sizeof(DEVICE_NAME) |
| cho45 | 0:be89b5fdea09 | 135 | ); |
| cho45 | 0:be89b5fdea09 | 136 | ble.gap().accumulateAdvertisingPayload( |
| cho45 | 0:be89b5fdea09 | 137 | GapAdvertisingData::SHORTENED_LOCAL_NAME, |
| cho45 | 0:be89b5fdea09 | 138 | SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME) |
| cho45 | 0:be89b5fdea09 | 139 | ); |
| cho45 | 0:be89b5fdea09 | 140 | |
| cho45 | 0:be89b5fdea09 | 141 | printf("set device name\r\n"); |
| cho45 | 0:be89b5fdea09 | 142 | ble.gap().setDeviceName(DEVICE_NAME); |
| cho45 | 0:be89b5fdea09 | 143 | // ble.gap().setTxPower(-12); |
| cho45 | 0:be89b5fdea09 | 144 | |
| cho45 | 0:be89b5fdea09 | 145 | |
| cho45 | 0:be89b5fdea09 | 146 | printf("advertising\r\n"); |
| cho45 | 0:be89b5fdea09 | 147 | ble.gap().startAdvertising(); |
| cho45 | 0:be89b5fdea09 | 148 | } |
| cho45 | 0:be89b5fdea09 | 149 | |
| cho45 | 0:be89b5fdea09 | 150 | void send_string(const char * c) { |
| cho45 | 0:be89b5fdea09 | 151 | if (!keyboardService) |
| cho45 | 0:be89b5fdea09 | 152 | return; |
| cho45 | 0:be89b5fdea09 | 153 | |
| cho45 | 0:be89b5fdea09 | 154 | if (!keyboardService->isConnected()) { |
| cho45 | 0:be89b5fdea09 | 155 | printf("we haven't connected yet..."); |
| cho45 | 0:be89b5fdea09 | 156 | } else { |
| cho45 | 0:be89b5fdea09 | 157 | int len = strlen(c); |
| cho45 | 0:be89b5fdea09 | 158 | keyboardService->printf(c); |
| cho45 | 0:be89b5fdea09 | 159 | printf("sending %d chars\r\n", len); |
| cho45 | 0:be89b5fdea09 | 160 | } |
| cho45 | 0:be89b5fdea09 | 161 | } |
| cho45 | 0:be89b5fdea09 | 162 | |
| cho45 | 0:be89b5fdea09 | 163 | void send_stuff() { |
| cho45 | 0:be89b5fdea09 | 164 | send_string("hello world!\n"); |
| cho45 | 0:be89b5fdea09 | 165 | } |
| cho45 | 0:be89b5fdea09 | 166 | |
| cho45 | 0:be89b5fdea09 | 167 | int main(void) { |
| cho45 | 0:be89b5fdea09 | 168 | |
| cho45 | 0:be89b5fdea09 | 169 | // https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp |
| cho45 | 0:be89b5fdea09 | 170 | |
| cho45 | 0:be89b5fdea09 | 171 | printf("ble.init\r\n"); |
| cho45 | 0:be89b5fdea09 | 172 | BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); |
| cho45 | 0:be89b5fdea09 | 173 | ble.init(bleInitComplete); |
| cho45 | 0:be89b5fdea09 | 174 | |
| cho45 | 0:be89b5fdea09 | 175 | button1.rise(send_stuff); |
| cho45 | 0:be89b5fdea09 | 176 | |
| cho45 | 0:be89b5fdea09 | 177 | // TODO: Use internal 1.2V reference for batteryInput |
| cho45 | 0:be89b5fdea09 | 178 | while (!ble.hasInitialized()) { } |
| cho45 | 0:be89b5fdea09 | 179 | |
| cho45 | 0:be89b5fdea09 | 180 | printf("ble.hasIntialized\r\n"); |
| cho45 | 0:be89b5fdea09 | 181 | |
| cho45 | 0:be89b5fdea09 | 182 | while(1) { |
| cho45 | 0:be89b5fdea09 | 183 | ble.waitForEvent(); |
| cho45 | 0:be89b5fdea09 | 184 | } |
| cho45 | 0:be89b5fdea09 | 185 | } |
| cho45 | 0:be89b5fdea09 | 186 | |
| cho45 | 0:be89b5fdea09 | 187 | |
| cho45 | 0:be89b5fdea09 | 188 | |
| cho45 | 0:be89b5fdea09 | 189 | |
| cho45 | 0:be89b5fdea09 | 190 | |
| cho45 | 0:be89b5fdea09 | 191 | |
| cho45 | 0:be89b5fdea09 | 192 | |
| cho45 | 0:be89b5fdea09 | 193 | |
| cho45 | 0:be89b5fdea09 | 194 | |
| cho45 | 0:be89b5fdea09 | 195 | |
| cho45 | 0:be89b5fdea09 | 196 | |
| cho45 | 0:be89b5fdea09 | 197 | |
| cho45 | 0:be89b5fdea09 | 198 | |
| cho45 | 0:be89b5fdea09 | 199 | |
| cho45 | 0:be89b5fdea09 | 200 | |
| cho45 | 0:be89b5fdea09 | 201 | |
| cho45 | 0:be89b5fdea09 | 202 | |
| cho45 | 0:be89b5fdea09 | 203 | |
| cho45 | 0:be89b5fdea09 | 204 | |
| cho45 | 0:be89b5fdea09 | 205 |