├── .gitignore ├── DEVICES.pdf ├── README.md └── examples ├── nrf8001 ├── led_and_button_services │ ├── lighting │ │ ├── lighting.ino │ │ └── services.h │ ├── lighting_and_button.fzz │ ├── lighting_and_button.png │ ├── lighting_and_button.xml │ ├── lighting_with_state │ │ ├── lighting_with_state.ino │ │ └── services.h │ ├── nRF8001.m4v │ └── nrf8001.zip ├── led_service │ ├── lighting.fzz │ ├── lighting.png │ ├── lighting.xml │ ├── lighting │ │ ├── lighting.ino │ │ └── services.h │ └── nrf8001.zip └── wiring_the_adafruit_board.png └── redbearlab └── blemini └── led_serial ├── Blink for Mac ├── Blink.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── aa.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── aa.xcuserdatad │ │ └── xcschemes │ │ ├── Blink.xcscheme │ │ └── xcschememanagement.plist └── Blink │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── BLE.h │ ├── BLE.m │ ├── BLEDefines.h │ ├── Base.lproj │ └── MainMenu.xib │ ├── Blink-Info.plist │ ├── Blink-Prefix.pch │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── en.lproj │ ├── Credits.rtf │ └── InfoPlist.strings │ └── main.m ├── Blink └── Blink.ino ├── README.md ├── circuit.fzz ├── circuit.png └── library ├── BLE.h ├── BLE.m └── BLEDefines.h /.gitignore: -------------------------------------------------------------------------------- 1 | # git config --global core.excludesfile ./.gitignore 2 | 3 | node_modules 4 | *.json 5 | 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | Icon 10 | ._* 11 | .Spotlight-V100 12 | .Trashes 13 | 14 | lib-cov 15 | *.seed 16 | *.log 17 | *.csv 18 | *.dat 19 | *.out 20 | *.pid 21 | *.gz 22 | 23 | pids 24 | logs 25 | results 26 | 27 | npm-debug.log 28 | 29 | build/ 30 | Debug 31 | Release 32 | 33 | zwscene.xml 34 | zwcfg_*.xml 35 | 36 | .node-xmlhttprequest-* 37 | -------------------------------------------------------------------------------- /DEVICES.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/DEVICES.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BLEDocs 2 | ======= 3 | 4 | This repository contains notes and code samples from a Bluetooth LE doc-a-thon held at ITP in June 2014. 5 | 6 | Over the course of the last few months, we had all been working with or developing a variety of Bluetooth LE devices and libraries. We found that while there are several good tools out there, they weren't always that well documented. We decided to work together for two days and try to document what we knew of the various tools we'd been using. Our hope is that this repository may provide pointers for others to get started. 7 | 8 | The doc-a-thon will take place on June 9 and 10, 2014. Here are some of the goals: 9 | 10 | 1) For a given hardware device, can we: 11 | 12 | * describe it and what services/sensors it offers 13 | * set the advertised name 14 | * set the advertising packet data (raw hex is fine) 15 | * set the scan response packet 16 | 17 | 2) There are a variety of Bluetooth LE APIs for these devices, and so far, not a lot of common standards to those APIs. Can we: 18 | 19 | * describe the clearest and most understandable APIs 20 | * suggest how they might be implemented for other devices 21 | * come up with a set of "best practices" for Bluetooth LE APIs 22 | 23 | Check the [Wiki](https://github.com/tigoe/BLEDocs/wiki) for introductions to the various devices and libraries we've investigated, and the code repo for actual code samples. 24 | 25 | The participants (not complete): 26 | Tom Igoe, Don Coleman, Alasdair Allan, Sandeep Mistry, Kevin Townsend (remotely), Yihui Xiong (remotely), Shawn Van Every, JB Kim, Guan Yang, 27 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting/lighting.ino: -------------------------------------------------------------------------------- 1 | // Set Serial Monitor to 115200 2 | // Currently this will output large amounts of debugging data 3 | 4 | #include "services.h" 5 | 6 | #define NRF_DEBUG 1 7 | #include 8 | #include 9 | 10 | #define LED_SWITCH_PIPE 1 11 | #define BUTTON_TX_PIPE 3 12 | #define BUTTON_STATE_PIPE 4 13 | 14 | // change nRF8001 reset pin to -1 if it's not connected 15 | // Redbear BLE Shield users: to my knowledge reset pin is not connected so use -1! 16 | // NOTE: if you choose -1, youll need to manually reset your device after powerup!! 17 | #define RESET_PIN 9 18 | #define REQN_PIN 10 19 | #define RDYN_PIN 2 20 | 21 | hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT; 22 | nRF8001 *nrf; 23 | 24 | int val; 25 | int buttonState; // variable to hold the last button state 26 | 27 | uint8_t pipeStatusReceived, dataSent; 28 | unsigned long lastSent; 29 | 30 | // Generic event handler, here it's just for debugging all received events 31 | void eventHandler(nRFEvent *event) 32 | { 33 | Serial.println("event handler"); 34 | // nrf->debugEvent(event); 35 | Serial.print("event = "); 36 | Serial.println( event->event ); 37 | 38 | // Data Received 39 | if ( event->event == NRF_DATARECEIVEDEVENT ) { 40 | Serial.println( "We have data" ); 41 | Serial.print( "pipe = " ); 42 | Serial.println( event->msg.dataReceived.servicePipeNo ); 43 | 44 | Serial.print( "length = " ); 45 | Serial.println( event->length ); 46 | 47 | Serial.print( "data = " ); 48 | for ( int i = 0; i < event->length - 2; i++ ) { 49 | Serial.print( event->msg.dataReceived.data[i] ); 50 | } 51 | Serial.println(""); 52 | if ( event->msg.dataReceived.data[0] > 0 ) { 53 | digitalWrite( 3, HIGH ); 54 | } else { 55 | digitalWrite( 3, LOW ); 56 | } 57 | } 58 | 59 | // Credit Received 60 | if ( event->event == NRF_DATACREDITEVENT ) { 61 | Serial.println( "We have a credit" ); 62 | 63 | } 64 | 65 | } 66 | 67 | void setup() { 68 | pipeStatusReceived = 0; 69 | lastSent = 0; 70 | 71 | pinMode( 3, OUTPUT ); 72 | pinMode( 4, OUTPUT ); 73 | 74 | Serial.begin(115200); 75 | Serial.println("Hello"); 76 | 77 | // nRF8001 class initialized with pin numbers 78 | nrf = new nRF8001(RESET_PIN, REQN_PIN, RDYN_PIN); 79 | 80 | // Register event handles 81 | nrf->setEventHandler(&eventHandler); 82 | if ((nrf->setup( setup_msgs, NB_SETUP_MESSAGES)) == cmdSuccess) { 83 | Serial.println("SUCCESS"); 84 | } else { 85 | Serial.println("FAIL"); 86 | while (1); 87 | } 88 | 89 | // These functions merely request device address and temperature, 90 | // actual responses are asynchronous. They'll return error codes 91 | // if somehow the request itself failed, for example because 92 | // the device is not ready for these commands. 93 | nrf->getDeviceAddress(); 94 | nrf->poll(); 95 | 96 | nrf->connect(0, 32); 97 | } 98 | 99 | void loop() { 100 | //Serial.println("polling"); 101 | 102 | // Polling will block - times out after 50 milliseconds 103 | nrf->poll(50); 104 | 105 | if (nrf->getConnectionStatus() == Disconnected) { 106 | Serial.println("Reconnecting"); 107 | dataSent = 0; 108 | nrf->connect(0, 32); 109 | } 110 | 111 | val = digitalRead(4); // read input value and store it in val 112 | if (val != buttonState) { // the button state has changed! 113 | uint8_t foo = -1; 114 | uint8_t bar = -1; 115 | Serial.print("credits available "); 116 | Serial.println( nrf->creditsAvailable() ); 117 | 118 | if (val == LOW) { // check if the button is pressed 119 | Serial.println("Button just released"); 120 | digitalWrite( 3, LOW ); 121 | bar = 0; 122 | nrf->setLocalData(LED_SWITCH_PIPE, 1, &bar); 123 | 124 | // STATE 125 | if (nrf->isPipeOpen(BUTTON_STATE_PIPE) && nrf->creditsAvailable()) { 126 | Serial.println("Setting 0"); 127 | foo = 0; 128 | nrf->setLocalData(BUTTON_STATE_PIPE, 1, &foo); 129 | 130 | } 131 | 132 | // TX 133 | if ( nrf->isPipeOpen(BUTTON_TX_PIPE) ) { 134 | Serial.println("Sending 0"); 135 | foo = 0; 136 | nrf->sendData(BUTTON_TX_PIPE, 1, &foo); 137 | } 138 | 139 | } else { // the button is -not- pressed... 140 | Serial.println("Button just pressed"); 141 | digitalWrite( 3, HIGH ); 142 | bar = 1; 143 | nrf->setLocalData(LED_SWITCH_PIPE, 1, &bar); 144 | 145 | // STATE 146 | if (nrf->isPipeOpen(BUTTON_STATE_PIPE) && nrf->creditsAvailable()) { 147 | Serial.println("Setting 1"); 148 | foo = 1; 149 | nrf->setLocalData(BUTTON_STATE_PIPE, 1, &foo); 150 | } 151 | 152 | // TX 153 | if ( nrf->isPipeOpen(BUTTON_TX_PIPE) ) { 154 | Serial.println("Sending 1"); 155 | foo = 1; 156 | nrf->sendData(BUTTON_TX_PIPE, 1, &foo); 157 | } 158 | } 159 | 160 | } 161 | 162 | buttonState = val; // save the new state in our variable 163 | 164 | } 165 | 166 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting/services.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * - Redistributions in binary form must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * - The name of Nordic Semiconductor ASA may not be used to endorse or promote 16 | * products derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * This file is autogenerated by nRFgo Studio 1.16.1.3119 32 | */ 33 | 34 | #ifndef SETUP_MESSAGES_H__ 35 | #define SETUP_MESSAGES_H__ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | #define SETUP_ID 0 43 | #define SETUP_FORMAT 3 /** nRF8001 D */ 44 | #define ACI_DYNAMIC_DATA_SIZE 119 45 | 46 | /* Service: LED - Characteristic: Switch - Pipe: SET */ 47 | #define PIPE_LED_SWITCH_SET 1 48 | #define PIPE_LED_SWITCH_SET_MAX_SIZE 1 49 | 50 | /* Service: LED - Characteristic: Switch - Pipe: RX_ACK_AUTO */ 51 | #define PIPE_LED_SWITCH_RX_ACK_AUTO 2 52 | #define PIPE_LED_SWITCH_RX_ACK_AUTO_MAX_SIZE 1 53 | 54 | /* Service: Button - Characteristic: State - Pipe: TX */ 55 | #define PIPE_BUTTON_STATE_TX 3 56 | #define PIPE_BUTTON_STATE_TX_MAX_SIZE 1 57 | 58 | /* Service: Button - Characteristic: State - Pipe: SET */ 59 | #define PIPE_BUTTON_STATE_SET 4 60 | #define PIPE_BUTTON_STATE_SET_MAX_SIZE 1 61 | 62 | 63 | #define NUMBER_OF_PIPES 4 64 | 65 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\ 66 | {ACI_STORE_LOCAL, ACI_SET}, \ 67 | {ACI_STORE_LOCAL, ACI_RX_ACK_AUTO}, \ 68 | {ACI_STORE_LOCAL, ACI_TX}, \ 69 | {ACI_STORE_LOCAL, ACI_SET}, \ 70 | } 71 | 72 | #define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 73 | #define GAP_PPCP_MIN_CONN_INT 0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 74 | #define GAP_PPCP_SLAVE_LATENCY 0 75 | #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */ 76 | 77 | #define NB_SETUP_MESSAGES 20 78 | #define SETUP_MESSAGES_CONTENT {\ 79 | {0x00,\ 80 | {\ 81 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\ 82 | },\ 83 | },\ 84 | {0x00,\ 85 | {\ 86 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ 87 | 0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 88 | },\ 89 | },\ 90 | {0x00,\ 91 | {\ 92 | 0x1f,0x06,0x10,0x1c,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 93 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x03,0x90,0x02,0xff,\ 94 | },\ 95 | },\ 96 | {0x00,\ 97 | {\ 98 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,\ 99 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 100 | },\ 101 | },\ 102 | {0x00,\ 103 | {\ 104 | 0x05,0x06,0x10,0x54,0x00,0x00,\ 105 | },\ 106 | },\ 107 | {0x00,\ 108 | {\ 109 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\ 110 | 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14,\ 111 | },\ 112 | },\ 113 | {0x00,\ 114 | {\ 115 | 0x1f,0x06,0x20,0x1c,0x05,0x00,0x03,0x2a,0x00,0x01,0x4c,0x69,0x67,0x68,0x74,0x63,0x73,0x65,0x6d,0x69,\ 116 | 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,\ 117 | },\ 118 | },\ 119 | {0x00,\ 120 | {\ 121 | 0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,\ 122 | 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,\ 123 | },\ 124 | },\ 125 | {0x00,\ 126 | {\ 127 | 0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,\ 128 | 0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04,\ 129 | },\ 130 | },\ 131 | {0x00,\ 132 | {\ 133 | 0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,\ 134 | 0x00,0x01,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 135 | },\ 136 | },\ 137 | {0x00,\ 138 | {\ 139 | 0x1f,0x06,0x20,0x8c,0xf2,0xe8,0x01,0x00,0xb1,0x19,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x0a,\ 140 | 0x0b,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 141 | },\ 142 | },\ 143 | {0x00,\ 144 | {\ 145 | 0x1f,0x06,0x20,0xa8,0xf2,0xe8,0x02,0x00,0xb1,0x19,0x46,0x14,0x02,0x01,0x00,0x0b,0x00,0x02,0x02,0x00,\ 146 | 0x04,0x04,0x10,0x10,0x00,0x0c,0x28,0x00,0x01,0x3a,0xa4,0x69,\ 147 | },\ 148 | },\ 149 | {0x00,\ 150 | {\ 151 | 0x1f,0x06,0x20,0xc4,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,0x01,0x00,0xe7,0x29,0x04,0x04,0x13,\ 152 | 0x13,0x00,0x0d,0x28,0x03,0x01,0x12,0x0e,0x00,0x3a,0xa4,0x69,\ 153 | },\ 154 | },\ 155 | {0x00,\ 156 | {\ 157 | 0x1f,0x06,0x20,0xe0,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,0x02,0x00,0xe7,0x29,0x16,0x04,0x02,\ 158 | 0x01,0x00,0x0e,0x00,0x02,0x03,0x00,0x46,0x14,0x03,0x02,0x00,\ 159 | },\ 160 | },\ 161 | {0x00,\ 162 | {\ 163 | 0x0a,0x06,0x20,0xfc,0x0f,0x29,0x02,0x01,0x00,0x00,0x00,\ 164 | },\ 165 | },\ 166 | {0x00,\ 167 | {\ 168 | 0x17,0x06,0x40,0x00,0x00,0x02,0x02,0x04,0x80,0x04,0x00,0x0b,0x00,0x00,0x00,0x02,0x03,0x00,0x82,0x04,\ 169 | 0x00,0x0e,0x00,0x0f,\ 170 | },\ 171 | },\ 172 | {0x00,\ 173 | {\ 174 | 0x1f,0x06,0x50,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,0xf2,0xe8,0x00,0x00,0xb1,0x19,\ 175 | 0x3a,0xa4,0x69,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,\ 176 | },\ 177 | },\ 178 | {0x00,\ 179 | {\ 180 | 0x07,0x06,0x50,0x1c,0x00,0x00,0xe7,0x29,\ 181 | },\ 182 | },\ 183 | {0x00,\ 184 | {\ 185 | 0x09,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 186 | },\ 187 | },\ 188 | {0x00,\ 189 | {\ 190 | 0x06,0x06,0xf0,0x00,0x03,0x8f,0x93,\ 191 | },\ 192 | },\ 193 | } 194 | 195 | #endif 196 | 197 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting_and_button.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_and_button_services/lighting_and_button.fzz -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting_and_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_and_button_services/lighting_and_button.png -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting_and_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | nRF8001_Dx 6 | 7 | LED 8 | 0001 9 | 10 | Switch 11 | 0002 12 | 0 13 | 0 14 | 1 15 | 1 16 | false 17 | 18 | false 19 | true 20 | false 21 | false 22 | false 23 | 24 | true 25 | true 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | Button 33 | 0001 34 | 35 | State 36 | 0002 37 | 0 38 | 0 39 | 1 40 | 1 41 | false 42 | 43 | false 44 | false 45 | true 46 | false 47 | false 48 | 49 | true 50 | false 51 | 52 | 0 53 | 54 | 55 | 56 | 57 | Light 58 | 0 59 | false 60 | 1 61 | 0000 62 | 0 63 | 0 64 | 0 65 | 600 66 | 10 67 | 7 68 | 16 69 | 0 70 | a 71 | 0 72 | 0 73 | 10 74 | 0 75 | 0 76 | 0 77 | 0 78 | 0 79 | 0 80 | 0 81 | 0 82 | 65535 83 | 65535 84 | 0 85 | 65535 86 | false 87 | false 88 | 89 | 0001 90 | 91 | 92 | 93 | 19 94 | 0000 95 | 96 | 97 | 18 98 | 99 | 100 | 101 | 102 | 103 | 1 104 | 1 105 | 3 106 | 0 107 | 0 108 | 0 109 | 0 110 | false 111 | 112 | 113 | 220 114 | 10 115 | 1000 116 | 0 117 | 0 118 | 1280 119 | 120 | 121 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting_with_state/lighting_with_state.ino: -------------------------------------------------------------------------------- 1 | // Set Serial Monitor to 115200 2 | // Currently this will output large amounts of debugging data 3 | 4 | // This version of the code acts more like a light switch. The LED doesn't go off when you 5 | // release the button. Notifications are made on button press and release as before however. 6 | 7 | #include "services.h" 8 | 9 | #define NRF_DEBUG 1 10 | #include 11 | #include 12 | 13 | #define LED_SWITCH_PIPE 1 14 | #define BUTTON_TX_PIPE 3 15 | #define BUTTON_STATE_PIPE 4 16 | 17 | // change nRF8001 reset pin to -1 if it's not connected 18 | // Redbear BLE Shield users: to my knowledge reset pin is not connected so use -1! 19 | // NOTE: if you choose -1, youll need to manually reset your device after powerup!! 20 | #define RESET_PIN 9 21 | #define REQN_PIN 10 22 | #define RDYN_PIN 2 23 | 24 | hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT; 25 | nRF8001 *nrf; 26 | 27 | int val; 28 | int buttonState; // variable to hold the last button state 29 | int ledState; 30 | 31 | uint8_t pipeStatusReceived, dataSent; 32 | unsigned long lastSent; 33 | 34 | // Generic event handler, here it's just for debugging all received events 35 | void eventHandler(nRFEvent *event) 36 | { 37 | Serial.println("event handler"); 38 | // nrf->debugEvent(event); 39 | Serial.print("event = "); 40 | Serial.println( event->event ); 41 | 42 | // Data Received 43 | if ( event->event == NRF_DATARECEIVEDEVENT ) { 44 | Serial.println( "We have data" ); 45 | Serial.print( "pipe = " ); 46 | Serial.println( event->msg.dataReceived.servicePipeNo ); 47 | 48 | Serial.print( "length = " ); 49 | Serial.println( event->length ); 50 | 51 | Serial.print( "data = " ); 52 | for ( int i = 0; i < event->length - 2; i++ ) { 53 | Serial.print( event->msg.dataReceived.data[i] ); 54 | } 55 | Serial.println(""); 56 | if ( event->msg.dataReceived.data[0] > 0 ) { 57 | // Turn the LED on 58 | digitalWrite( 3, HIGH ); 59 | ledState = 1; 60 | } else { 61 | // or off 62 | digitalWrite( 3, LOW ); 63 | ledState = 0; 64 | } 65 | } 66 | 67 | // Credit Received 68 | if ( event->event == NRF_DATACREDITEVENT ) { 69 | Serial.println( "We have a credit" ); 70 | 71 | } 72 | 73 | } 74 | 75 | void setup() { 76 | pipeStatusReceived = 0; 77 | lastSent = 0; 78 | 79 | pinMode( 3, OUTPUT ); 80 | pinMode( 4, OUTPUT ); 81 | ledState = 0; 82 | digitalWrite( 3, LOW ); // Turn the LED off on boot 83 | 84 | Serial.begin(115200); 85 | Serial.println("Hello"); 86 | 87 | // nRF8001 class initialized with pin numbers 88 | nrf = new nRF8001(RESET_PIN, REQN_PIN, RDYN_PIN); 89 | 90 | // Register event handles 91 | nrf->setEventHandler(&eventHandler); 92 | if ((nrf->setup( setup_msgs, NB_SETUP_MESSAGES)) == cmdSuccess) { 93 | Serial.println("SUCCESS"); 94 | } else { 95 | Serial.println("FAIL"); 96 | while (1); 97 | } 98 | 99 | // These functions merely request device address and temperature, 100 | // actual responses are asynchronous. They'll return error codes 101 | // if somehow the request itself failed, for example because 102 | // the device is not ready for these commands. 103 | nrf->getDeviceAddress(); 104 | nrf->poll(); 105 | 106 | nrf->connect(0, 32); 107 | } 108 | 109 | void loop() { 110 | //Serial.println("polling"); 111 | 112 | // Polling will block - times out after 50 milliseconds 113 | nrf->poll(50); 114 | 115 | if (nrf->getConnectionStatus() == Disconnected) { 116 | Serial.println("Reconnecting"); 117 | dataSent = 0; 118 | nrf->connect(0, 32); 119 | } 120 | 121 | val = digitalRead(4); // read input value and store it in val 122 | if (val != buttonState) { // the button state has changed! 123 | uint8_t foo = -1; 124 | uint8_t bar = -1; 125 | Serial.print("credits available "); 126 | Serial.println( nrf->creditsAvailable() ); 127 | 128 | if (val == LOW) { // check if the button is pressed 129 | Serial.println("Button just released"); 130 | 131 | // STATE 132 | if (nrf->isPipeOpen(BUTTON_STATE_PIPE) && nrf->creditsAvailable()) { 133 | Serial.println("Setting 0"); 134 | foo = 0; 135 | nrf->setLocalData(BUTTON_STATE_PIPE, 1, &foo); 136 | 137 | } 138 | 139 | // TX 140 | if ( nrf->isPipeOpen(BUTTON_TX_PIPE) ) { 141 | Serial.println("Sending 0"); 142 | foo = 0; 143 | nrf->sendData(BUTTON_TX_PIPE, 1, &foo); 144 | } 145 | 146 | } else { // the button is -not- pressed... 147 | Serial.println("Button just pressed"); 148 | if ( ledState == 1 ) { 149 | // turn the LED off 150 | digitalWrite(3, LOW ); 151 | ledState = 0; 152 | bar = 0; 153 | nrf->setLocalData(LED_SWITCH_PIPE, 1, &bar); 154 | } else { 155 | // turn it on 156 | digitalWrite( 3, HIGH ); 157 | ledState = 1; 158 | bar = 1; 159 | nrf->setLocalData(LED_SWITCH_PIPE, 1, &bar); 160 | } 161 | 162 | 163 | 164 | // STATE 165 | if (nrf->isPipeOpen(BUTTON_STATE_PIPE) && nrf->creditsAvailable()) { 166 | Serial.println("Setting 1"); 167 | foo = 1; 168 | nrf->setLocalData(BUTTON_STATE_PIPE, 1, &foo); 169 | } 170 | 171 | // TX 172 | if ( nrf->isPipeOpen(BUTTON_TX_PIPE) ) { 173 | Serial.println("Sending 1"); 174 | foo = 1; 175 | nrf->sendData(BUTTON_TX_PIPE, 1, &foo); 176 | } 177 | } 178 | 179 | } 180 | 181 | buttonState = val; // save the new state in our variable 182 | 183 | } 184 | 185 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/lighting_with_state/services.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * - Redistributions in binary form must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * - The name of Nordic Semiconductor ASA may not be used to endorse or promote 16 | * products derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * This file is autogenerated by nRFgo Studio 1.16.1.3119 32 | */ 33 | 34 | #ifndef SETUP_MESSAGES_H__ 35 | #define SETUP_MESSAGES_H__ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | #define SETUP_ID 0 43 | #define SETUP_FORMAT 3 /** nRF8001 D */ 44 | #define ACI_DYNAMIC_DATA_SIZE 119 45 | 46 | /* Service: LED - Characteristic: Switch - Pipe: SET */ 47 | #define PIPE_LED_SWITCH_SET 1 48 | #define PIPE_LED_SWITCH_SET_MAX_SIZE 1 49 | 50 | /* Service: LED - Characteristic: Switch - Pipe: RX_ACK_AUTO */ 51 | #define PIPE_LED_SWITCH_RX_ACK_AUTO 2 52 | #define PIPE_LED_SWITCH_RX_ACK_AUTO_MAX_SIZE 1 53 | 54 | /* Service: Button - Characteristic: State - Pipe: TX */ 55 | #define PIPE_BUTTON_STATE_TX 3 56 | #define PIPE_BUTTON_STATE_TX_MAX_SIZE 1 57 | 58 | /* Service: Button - Characteristic: State - Pipe: SET */ 59 | #define PIPE_BUTTON_STATE_SET 4 60 | #define PIPE_BUTTON_STATE_SET_MAX_SIZE 1 61 | 62 | 63 | #define NUMBER_OF_PIPES 4 64 | 65 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\ 66 | {ACI_STORE_LOCAL, ACI_SET}, \ 67 | {ACI_STORE_LOCAL, ACI_RX_ACK_AUTO}, \ 68 | {ACI_STORE_LOCAL, ACI_TX}, \ 69 | {ACI_STORE_LOCAL, ACI_SET}, \ 70 | } 71 | 72 | #define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 73 | #define GAP_PPCP_MIN_CONN_INT 0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 74 | #define GAP_PPCP_SLAVE_LATENCY 0 75 | #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */ 76 | 77 | #define NB_SETUP_MESSAGES 20 78 | #define SETUP_MESSAGES_CONTENT {\ 79 | {0x00,\ 80 | {\ 81 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\ 82 | },\ 83 | },\ 84 | {0x00,\ 85 | {\ 86 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ 87 | 0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 88 | },\ 89 | },\ 90 | {0x00,\ 91 | {\ 92 | 0x1f,0x06,0x10,0x1c,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 93 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x03,0x90,0x02,0xff,\ 94 | },\ 95 | },\ 96 | {0x00,\ 97 | {\ 98 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,\ 99 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 100 | },\ 101 | },\ 102 | {0x00,\ 103 | {\ 104 | 0x05,0x06,0x10,0x54,0x00,0x00,\ 105 | },\ 106 | },\ 107 | {0x00,\ 108 | {\ 109 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\ 110 | 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14,\ 111 | },\ 112 | },\ 113 | {0x00,\ 114 | {\ 115 | 0x1f,0x06,0x20,0x1c,0x05,0x00,0x03,0x2a,0x00,0x01,0x4c,0x69,0x67,0x68,0x74,0x63,0x73,0x65,0x6d,0x69,\ 116 | 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,\ 117 | },\ 118 | },\ 119 | {0x00,\ 120 | {\ 121 | 0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,\ 122 | 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,\ 123 | },\ 124 | },\ 125 | {0x00,\ 126 | {\ 127 | 0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,\ 128 | 0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04,\ 129 | },\ 130 | },\ 131 | {0x00,\ 132 | {\ 133 | 0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,\ 134 | 0x00,0x01,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 135 | },\ 136 | },\ 137 | {0x00,\ 138 | {\ 139 | 0x1f,0x06,0x20,0x8c,0xf2,0xe8,0x01,0x00,0xb1,0x19,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x0a,\ 140 | 0x0b,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 141 | },\ 142 | },\ 143 | {0x00,\ 144 | {\ 145 | 0x1f,0x06,0x20,0xa8,0xf2,0xe8,0x02,0x00,0xb1,0x19,0x46,0x14,0x02,0x01,0x00,0x0b,0x00,0x02,0x02,0x00,\ 146 | 0x04,0x04,0x10,0x10,0x00,0x0c,0x28,0x00,0x01,0x3a,0xa4,0x69,\ 147 | },\ 148 | },\ 149 | {0x00,\ 150 | {\ 151 | 0x1f,0x06,0x20,0xc4,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,0x01,0x00,0xe7,0x29,0x04,0x04,0x13,\ 152 | 0x13,0x00,0x0d,0x28,0x03,0x01,0x12,0x0e,0x00,0x3a,0xa4,0x69,\ 153 | },\ 154 | },\ 155 | {0x00,\ 156 | {\ 157 | 0x1f,0x06,0x20,0xe0,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,0x02,0x00,0xe7,0x29,0x16,0x04,0x02,\ 158 | 0x01,0x00,0x0e,0x00,0x02,0x03,0x00,0x46,0x14,0x03,0x02,0x00,\ 159 | },\ 160 | },\ 161 | {0x00,\ 162 | {\ 163 | 0x0a,0x06,0x20,0xfc,0x0f,0x29,0x02,0x01,0x00,0x00,0x00,\ 164 | },\ 165 | },\ 166 | {0x00,\ 167 | {\ 168 | 0x17,0x06,0x40,0x00,0x00,0x02,0x02,0x04,0x80,0x04,0x00,0x0b,0x00,0x00,0x00,0x02,0x03,0x00,0x82,0x04,\ 169 | 0x00,0x0e,0x00,0x0f,\ 170 | },\ 171 | },\ 172 | {0x00,\ 173 | {\ 174 | 0x1f,0x06,0x50,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,0xf2,0xe8,0x00,0x00,0xb1,0x19,\ 175 | 0x3a,0xa4,0x69,0xcc,0xa5,0x09,0x73,0x34,0x97,0xe0,0x27,0x92,\ 176 | },\ 177 | },\ 178 | {0x00,\ 179 | {\ 180 | 0x07,0x06,0x50,0x1c,0x00,0x00,0xe7,0x29,\ 181 | },\ 182 | },\ 183 | {0x00,\ 184 | {\ 185 | 0x09,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 186 | },\ 187 | },\ 188 | {0x00,\ 189 | {\ 190 | 0x06,0x06,0xf0,0x00,0x03,0x8f,0x93,\ 191 | },\ 192 | },\ 193 | } 194 | 195 | #endif 196 | 197 | -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/nRF8001.m4v: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_and_button_services/nRF8001.m4v -------------------------------------------------------------------------------- /examples/nrf8001/led_and_button_services/nrf8001.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_and_button_services/nrf8001.zip -------------------------------------------------------------------------------- /examples/nrf8001/led_service/lighting.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_service/lighting.fzz -------------------------------------------------------------------------------- /examples/nrf8001/led_service/lighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_service/lighting.png -------------------------------------------------------------------------------- /examples/nrf8001/led_service/lighting.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | nRF8001_Dx 6 | 7 | LED 8 | 0001 9 | 10 | Switch 11 | 0002 12 | 0 13 | 0 14 | 1 15 | 1 16 | false 17 | 18 | false 19 | true 20 | false 21 | false 22 | false 23 | 24 | true 25 | true 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | Lighting 33 | 0 34 | false 35 | 1 36 | 0000 37 | 0 38 | 0 39 | 0 40 | 600 41 | 10 42 | 7 43 | 16 44 | 0 45 | a 46 | 0 47 | 0 48 | 10 49 | 0 50 | 0 51 | 0 52 | 0 53 | 0 54 | 0 55 | 0 56 | 0 57 | 65535 58 | 65535 59 | 0 60 | 65535 61 | false 62 | false 63 | 64 | 0001 65 | 66 | 67 | 68 | 19 69 | 0000 70 | 71 | 72 | 18 73 | 74 | 75 | 76 | 77 | 78 | 1 79 | 1 80 | 3 81 | 0 82 | 0 83 | 0 84 | 0 85 | false 86 | 87 | 88 | 220 89 | 10 90 | 1000 91 | 0 92 | 0 93 | 1280 94 | 95 | 96 | -------------------------------------------------------------------------------- /examples/nrf8001/led_service/lighting/lighting.ino: -------------------------------------------------------------------------------- 1 | // Set Serial Monitor to 115200 2 | // Currently this will output large amounts of debugging data 3 | 4 | #include "services.h" 5 | 6 | #define NRF_DEBUG 1 7 | #include 8 | #include 9 | 10 | #define LED_SWITCH_PIPE 1 11 | 12 | // change nRF8001 reset pin to -1 if it's not connected 13 | // Redbear BLE Shield users: to my knowledge reset pin is not connected so use -1! 14 | // NOTE: if you choose -1, youll need to manually reset your device after powerup!! 15 | #define RESET_PIN 9 16 | #define REQN_PIN 10 17 | #define RDYN_PIN 2 18 | 19 | hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT; 20 | nRF8001 *nrf; 21 | 22 | uint8_t pipeStatusReceived, dataSent; 23 | unsigned long lastSent; 24 | 25 | // Generic event handler, here it's just for debugging all received events 26 | void eventHandler(nRFEvent *event) 27 | { 28 | Serial.println("event handler"); 29 | // nrf->debugEvent(event); 30 | Serial.print("event = "); 31 | Serial.println( event->event ); 32 | if ( event->event == NRF_DATARECEIVEDEVENT ) { 33 | Serial.println( "We have data" ); 34 | Serial.print( "pipe = " ); 35 | Serial.println( event->msg.dataReceived.servicePipeNo ); 36 | 37 | Serial.print( "length = " ); 38 | Serial.println( event->length ); 39 | 40 | Serial.print( "data = " ); 41 | for ( int i = 0; i < event->length - 2; i++ ) { 42 | Serial.print( event->msg.dataReceived.data[i] ); 43 | } 44 | Serial.println(""); 45 | if ( event->msg.dataReceived.data[0] > 0 ) { 46 | digitalWrite( 3, HIGH ); 47 | } else { 48 | digitalWrite( 3, LOW ); 49 | } 50 | } 51 | } 52 | 53 | void setup() { 54 | pipeStatusReceived = 0; 55 | lastSent = 0; 56 | 57 | pinMode( 3, OUTPUT ); 58 | 59 | Serial.begin(115200); 60 | Serial.println("Hello"); 61 | 62 | // nRF8001 class initialized with pin numbers 63 | nrf = new nRF8001(RESET_PIN, REQN_PIN, RDYN_PIN); 64 | 65 | // Register event handles 66 | nrf->setEventHandler(&eventHandler); 67 | if ((nrf->setup( setup_msgs, NB_SETUP_MESSAGES)) == cmdSuccess) { 68 | Serial.println("SUCCESS"); 69 | } else { 70 | Serial.println("FAIL"); 71 | while (1); 72 | } 73 | 74 | // These functions merely request device address and temperature, 75 | // actual responses are asynchronous. They'll return error codes 76 | // if somehow the request itself failed, for example because 77 | // the device is not ready for these commands. 78 | nrf->getDeviceAddress(); 79 | nrf->poll(); 80 | 81 | nrf->connect(0, 32); 82 | } 83 | 84 | void loop() { 85 | Serial.println("polling"); 86 | 87 | // Polling will block - times out after 2 seconds 88 | nrf->poll(2000); 89 | 90 | if (nrf->getConnectionStatus() == Disconnected) { 91 | Serial.println("Reconnecting"); 92 | dataSent = 0; 93 | nrf->connect(0, 32); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /examples/nrf8001/led_service/lighting/services.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Nordic Semiconductor ASA 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * - Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * - Redistributions in binary form must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * - The name of Nordic Semiconductor ASA may not be used to endorse or promote 16 | * products derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * This file is autogenerated by nRFgo Studio 1.16.1.3119 32 | */ 33 | 34 | #ifndef SETUP_MESSAGES_H__ 35 | #define SETUP_MESSAGES_H__ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | 42 | #define SETUP_ID 0 43 | #define SETUP_FORMAT 3 /** nRF8001 D */ 44 | #define ACI_DYNAMIC_DATA_SIZE 110 45 | 46 | /* Service: LED - Characteristic: Switch - Pipe: SET */ 47 | #define PIPE_LED_SWITCH_SET 1 48 | #define PIPE_LED_SWITCH_SET_MAX_SIZE 1 49 | 50 | /* Service: LED - Characteristic: Switch - Pipe: RX_ACK_AUTO */ 51 | #define PIPE_LED_SWITCH_RX_ACK_AUTO 2 52 | #define PIPE_LED_SWITCH_RX_ACK_AUTO_MAX_SIZE 1 53 | 54 | 55 | #define NUMBER_OF_PIPES 2 56 | 57 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\ 58 | {ACI_STORE_LOCAL, ACI_SET}, \ 59 | {ACI_STORE_LOCAL, ACI_RX_ACK_AUTO}, \ 60 | } 61 | 62 | #define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 63 | #define GAP_PPCP_MIN_CONN_INT 0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */ 64 | #define GAP_PPCP_SLAVE_LATENCY 0 65 | #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */ 66 | 67 | #define NB_SETUP_MESSAGES 16 68 | #define SETUP_MESSAGES_CONTENT {\ 69 | {0x00,\ 70 | {\ 71 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\ 72 | },\ 73 | },\ 74 | {0x00,\ 75 | {\ 76 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\ 77 | 0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 78 | },\ 79 | },\ 80 | {0x00,\ 81 | {\ 82 | 0x1f,0x06,0x10,0x1c,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 83 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x03,0x90,0x01,0xff,\ 84 | },\ 85 | },\ 86 | {0x00,\ 87 | {\ 88 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,\ 89 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 90 | },\ 91 | },\ 92 | {0x00,\ 93 | {\ 94 | 0x05,0x06,0x10,0x54,0x00,0x00,\ 95 | },\ 96 | },\ 97 | {0x00,\ 98 | {\ 99 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\ 100 | 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14,\ 101 | },\ 102 | },\ 103 | {0x00,\ 104 | {\ 105 | 0x1f,0x06,0x20,0x1c,0x08,0x00,0x03,0x2a,0x00,0x01,0x4c,0x69,0x67,0x68,0x74,0x69,0x6e,0x67,0x6d,0x69,\ 106 | 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,\ 107 | },\ 108 | },\ 109 | {0x00,\ 110 | {\ 111 | 0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,\ 112 | 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,\ 113 | },\ 114 | },\ 115 | {0x00,\ 116 | {\ 117 | 0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,\ 118 | 0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x04,0x04,\ 119 | },\ 120 | },\ 121 | {0x00,\ 122 | {\ 123 | 0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,\ 124 | 0x00,0x01,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 125 | },\ 126 | },\ 127 | {0x00,\ 128 | {\ 129 | 0x1f,0x06,0x20,0x8c,0xf2,0xe8,0x01,0x00,0xb1,0x19,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x0a,\ 130 | 0x0b,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,\ 131 | },\ 132 | },\ 133 | {0x00,\ 134 | {\ 135 | 0x14,0x06,0x20,0xa8,0xf2,0xe8,0x02,0x00,0xb1,0x19,0x46,0x14,0x02,0x01,0x00,0x0b,0x00,0x02,0x02,0x00,\ 136 | 0x00,\ 137 | },\ 138 | },\ 139 | {0x00,\ 140 | {\ 141 | 0x0d,0x06,0x40,0x00,0x00,0x02,0x02,0x04,0x80,0x04,0x00,0x0b,0x00,0x00,\ 142 | },\ 143 | },\ 144 | {0x00,\ 145 | {\ 146 | 0x13,0x06,0x50,0x00,0x14,0x12,0x8a,0x76,0x04,0xd1,0x6c,0x4f,0x7e,0x53,0xf2,0xe8,0x00,0x00,0xb1,0x19,\ 147 | },\ 148 | },\ 149 | {0x00,\ 150 | {\ 151 | 0x06,0x06,0x60,0x00,0x00,0x00,0x00,\ 152 | },\ 153 | },\ 154 | {0x00,\ 155 | {\ 156 | 0x06,0x06,0xf0,0x00,0x03,0xb9,0x5c,\ 157 | },\ 158 | },\ 159 | } 160 | 161 | #endif 162 | 163 | -------------------------------------------------------------------------------- /examples/nrf8001/led_service/nrf8001.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/led_service/nrf8001.zip -------------------------------------------------------------------------------- /examples/nrf8001/wiring_the_adafruit_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/nrf8001/wiring_the_adafruit_board.png -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00FAC0DE193FEE5F004BB1DC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00FAC0DD193FEE5F004BB1DC /* Cocoa.framework */; }; 11 | 00FAC0E8193FEE5F004BB1DC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 00FAC0E6193FEE5F004BB1DC /* InfoPlist.strings */; }; 12 | 00FAC0EA193FEE5F004BB1DC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 00FAC0E9193FEE5F004BB1DC /* main.m */; }; 13 | 00FAC0EE193FEE5F004BB1DC /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 00FAC0EC193FEE5F004BB1DC /* Credits.rtf */; }; 14 | 00FAC0F1193FEE5F004BB1DC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 00FAC0F0193FEE5F004BB1DC /* AppDelegate.m */; }; 15 | 00FAC0F4193FEE5F004BB1DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 00FAC0F2193FEE5F004BB1DC /* MainMenu.xib */; }; 16 | 00FAC0F6193FEE5F004BB1DC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 00FAC0F5193FEE5F004BB1DC /* Images.xcassets */; }; 17 | 00FAC112193FF09D004BB1DC /* IOBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00FAC111193FF09D004BB1DC /* IOBluetooth.framework */; }; 18 | 00FAC116193FF1D8004BB1DC /* BLE.m in Sources */ = {isa = PBXBuildFile; fileRef = 00FAC114193FF1D8004BB1DC /* BLE.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 00FAC0DA193FEE5F004BB1DC /* Blink.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Blink.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 00FAC0DD193FEE5F004BB1DC /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 24 | 00FAC0E0193FEE5F004BB1DC /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 25 | 00FAC0E1193FEE5F004BB1DC /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 26 | 00FAC0E2193FEE5F004BB1DC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 27 | 00FAC0E5193FEE5F004BB1DC /* Blink-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Blink-Info.plist"; sourceTree = ""; }; 28 | 00FAC0E7193FEE5F004BB1DC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 29 | 00FAC0E9193FEE5F004BB1DC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 00FAC0EB193FEE5F004BB1DC /* Blink-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Blink-Prefix.pch"; sourceTree = ""; }; 31 | 00FAC0ED193FEE5F004BB1DC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; }; 32 | 00FAC0EF193FEE5F004BB1DC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | 00FAC0F0193FEE5F004BB1DC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 34 | 00FAC0F3193FEE5F004BB1DC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 35 | 00FAC0F5193FEE5F004BB1DC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 36 | 00FAC111193FF09D004BB1DC /* IOBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOBluetooth.framework; path = System/Library/Frameworks/IOBluetooth.framework; sourceTree = SDKROOT; }; 37 | 00FAC113193FF1D8004BB1DC /* BLEDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BLEDefines.h; sourceTree = ""; }; 38 | 00FAC114193FF1D8004BB1DC /* BLE.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BLE.m; sourceTree = ""; }; 39 | 00FAC115193FF1D8004BB1DC /* BLE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BLE.h; sourceTree = ""; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | 00FAC0D7193FEE5F004BB1DC /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | 00FAC112193FF09D004BB1DC /* IOBluetooth.framework in Frameworks */, 48 | 00FAC0DE193FEE5F004BB1DC /* Cocoa.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 00FAC0D1193FEE5F004BB1DC = { 56 | isa = PBXGroup; 57 | children = ( 58 | 00FAC0E3193FEE5F004BB1DC /* Blink */, 59 | 00FAC0DC193FEE5F004BB1DC /* Frameworks */, 60 | 00FAC0DB193FEE5F004BB1DC /* Products */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | 00FAC0DB193FEE5F004BB1DC /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 00FAC0DA193FEE5F004BB1DC /* Blink.app */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 00FAC0DC193FEE5F004BB1DC /* Frameworks */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 00FAC111193FF09D004BB1DC /* IOBluetooth.framework */, 76 | 00FAC0DD193FEE5F004BB1DC /* Cocoa.framework */, 77 | 00FAC0DF193FEE5F004BB1DC /* Other Frameworks */, 78 | ); 79 | name = Frameworks; 80 | sourceTree = ""; 81 | }; 82 | 00FAC0DF193FEE5F004BB1DC /* Other Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 00FAC0E0193FEE5F004BB1DC /* AppKit.framework */, 86 | 00FAC0E1193FEE5F004BB1DC /* CoreData.framework */, 87 | 00FAC0E2193FEE5F004BB1DC /* Foundation.framework */, 88 | ); 89 | name = "Other Frameworks"; 90 | sourceTree = ""; 91 | }; 92 | 00FAC0E3193FEE5F004BB1DC /* Blink */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 00FAC113193FF1D8004BB1DC /* BLEDefines.h */, 96 | 00FAC114193FF1D8004BB1DC /* BLE.m */, 97 | 00FAC115193FF1D8004BB1DC /* BLE.h */, 98 | 00FAC0EF193FEE5F004BB1DC /* AppDelegate.h */, 99 | 00FAC0F0193FEE5F004BB1DC /* AppDelegate.m */, 100 | 00FAC0F2193FEE5F004BB1DC /* MainMenu.xib */, 101 | 00FAC0F5193FEE5F004BB1DC /* Images.xcassets */, 102 | 00FAC0E4193FEE5F004BB1DC /* Supporting Files */, 103 | ); 104 | path = Blink; 105 | sourceTree = ""; 106 | }; 107 | 00FAC0E4193FEE5F004BB1DC /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 00FAC0E5193FEE5F004BB1DC /* Blink-Info.plist */, 111 | 00FAC0E6193FEE5F004BB1DC /* InfoPlist.strings */, 112 | 00FAC0E9193FEE5F004BB1DC /* main.m */, 113 | 00FAC0EB193FEE5F004BB1DC /* Blink-Prefix.pch */, 114 | 00FAC0EC193FEE5F004BB1DC /* Credits.rtf */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 00FAC0D9193FEE5F004BB1DC /* Blink */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 00FAC10B193FEE5F004BB1DC /* Build configuration list for PBXNativeTarget "Blink" */; 125 | buildPhases = ( 126 | 00FAC0D6193FEE5F004BB1DC /* Sources */, 127 | 00FAC0D7193FEE5F004BB1DC /* Frameworks */, 128 | 00FAC0D8193FEE5F004BB1DC /* Resources */, 129 | ); 130 | buildRules = ( 131 | ); 132 | dependencies = ( 133 | ); 134 | name = Blink; 135 | productName = Blink; 136 | productReference = 00FAC0DA193FEE5F004BB1DC /* Blink.app */; 137 | productType = "com.apple.product-type.application"; 138 | }; 139 | /* End PBXNativeTarget section */ 140 | 141 | /* Begin PBXProject section */ 142 | 00FAC0D2193FEE5F004BB1DC /* Project object */ = { 143 | isa = PBXProject; 144 | attributes = { 145 | LastUpgradeCheck = 0510; 146 | ORGANIZATIONNAME = "Babilim Light Industries"; 147 | }; 148 | buildConfigurationList = 00FAC0D5193FEE5F004BB1DC /* Build configuration list for PBXProject "Blink" */; 149 | compatibilityVersion = "Xcode 3.2"; 150 | developmentRegion = English; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | Base, 155 | ); 156 | mainGroup = 00FAC0D1193FEE5F004BB1DC; 157 | productRefGroup = 00FAC0DB193FEE5F004BB1DC /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 00FAC0D9193FEE5F004BB1DC /* Blink */, 162 | ); 163 | }; 164 | /* End PBXProject section */ 165 | 166 | /* Begin PBXResourcesBuildPhase section */ 167 | 00FAC0D8193FEE5F004BB1DC /* Resources */ = { 168 | isa = PBXResourcesBuildPhase; 169 | buildActionMask = 2147483647; 170 | files = ( 171 | 00FAC0E8193FEE5F004BB1DC /* InfoPlist.strings in Resources */, 172 | 00FAC0F6193FEE5F004BB1DC /* Images.xcassets in Resources */, 173 | 00FAC0EE193FEE5F004BB1DC /* Credits.rtf in Resources */, 174 | 00FAC0F4193FEE5F004BB1DC /* MainMenu.xib in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | 00FAC0D6193FEE5F004BB1DC /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | 00FAC116193FF1D8004BB1DC /* BLE.m in Sources */, 186 | 00FAC0F1193FEE5F004BB1DC /* AppDelegate.m in Sources */, 187 | 00FAC0EA193FEE5F004BB1DC /* main.m in Sources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXSourcesBuildPhase section */ 192 | 193 | /* Begin PBXVariantGroup section */ 194 | 00FAC0E6193FEE5F004BB1DC /* InfoPlist.strings */ = { 195 | isa = PBXVariantGroup; 196 | children = ( 197 | 00FAC0E7193FEE5F004BB1DC /* en */, 198 | ); 199 | name = InfoPlist.strings; 200 | sourceTree = ""; 201 | }; 202 | 00FAC0EC193FEE5F004BB1DC /* Credits.rtf */ = { 203 | isa = PBXVariantGroup; 204 | children = ( 205 | 00FAC0ED193FEE5F004BB1DC /* en */, 206 | ); 207 | name = Credits.rtf; 208 | sourceTree = ""; 209 | }; 210 | 00FAC0F2193FEE5F004BB1DC /* MainMenu.xib */ = { 211 | isa = PBXVariantGroup; 212 | children = ( 213 | 00FAC0F3193FEE5F004BB1DC /* Base */, 214 | ); 215 | name = MainMenu.xib; 216 | sourceTree = ""; 217 | }; 218 | /* End PBXVariantGroup section */ 219 | 220 | /* Begin XCBuildConfiguration section */ 221 | 00FAC109193FEE5F004BB1DC /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ALWAYS_SEARCH_USER_PATHS = NO; 225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 226 | CLANG_CXX_LIBRARY = "libc++"; 227 | CLANG_ENABLE_MODULES = YES; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | CLANG_WARN_BOOL_CONVERSION = YES; 230 | CLANG_WARN_CONSTANT_CONVERSION = YES; 231 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INT_CONVERSION = YES; 235 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 236 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 237 | COPY_PHASE_STRIP = NO; 238 | GCC_C_LANGUAGE_STANDARD = gnu99; 239 | GCC_DYNAMIC_NO_PIC = NO; 240 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 241 | GCC_OPTIMIZATION_LEVEL = 0; 242 | GCC_PREPROCESSOR_DEFINITIONS = ( 243 | "DEBUG=1", 244 | "$(inherited)", 245 | ); 246 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 251 | GCC_WARN_UNUSED_FUNCTION = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | MACOSX_DEPLOYMENT_TARGET = 10.8; 254 | ONLY_ACTIVE_ARCH = YES; 255 | SDKROOT = macosx; 256 | }; 257 | name = Debug; 258 | }; 259 | 00FAC10A193FEE5F004BB1DC /* Release */ = { 260 | isa = XCBuildConfiguration; 261 | buildSettings = { 262 | ALWAYS_SEARCH_USER_PATHS = NO; 263 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 264 | CLANG_CXX_LIBRARY = "libc++"; 265 | CLANG_ENABLE_MODULES = YES; 266 | CLANG_ENABLE_OBJC_ARC = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_CONSTANT_CONVERSION = YES; 269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 270 | CLANG_WARN_EMPTY_BODY = YES; 271 | CLANG_WARN_ENUM_CONVERSION = YES; 272 | CLANG_WARN_INT_CONVERSION = YES; 273 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 275 | COPY_PHASE_STRIP = YES; 276 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 277 | ENABLE_NS_ASSERTIONS = NO; 278 | GCC_C_LANGUAGE_STANDARD = gnu99; 279 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 282 | GCC_WARN_UNDECLARED_SELECTOR = YES; 283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 284 | GCC_WARN_UNUSED_FUNCTION = YES; 285 | GCC_WARN_UNUSED_VARIABLE = YES; 286 | MACOSX_DEPLOYMENT_TARGET = 10.8; 287 | SDKROOT = macosx; 288 | }; 289 | name = Release; 290 | }; 291 | 00FAC10C193FEE5F004BB1DC /* Debug */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 295 | COMBINE_HIDPI_IMAGES = YES; 296 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 297 | GCC_PREFIX_HEADER = "Blink/Blink-Prefix.pch"; 298 | INFOPLIST_FILE = "Blink/Blink-Info.plist"; 299 | PRODUCT_NAME = "$(TARGET_NAME)"; 300 | WRAPPER_EXTENSION = app; 301 | }; 302 | name = Debug; 303 | }; 304 | 00FAC10D193FEE5F004BB1DC /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 308 | COMBINE_HIDPI_IMAGES = YES; 309 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 310 | GCC_PREFIX_HEADER = "Blink/Blink-Prefix.pch"; 311 | INFOPLIST_FILE = "Blink/Blink-Info.plist"; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | WRAPPER_EXTENSION = app; 314 | }; 315 | name = Release; 316 | }; 317 | /* End XCBuildConfiguration section */ 318 | 319 | /* Begin XCConfigurationList section */ 320 | 00FAC0D5193FEE5F004BB1DC /* Build configuration list for PBXProject "Blink" */ = { 321 | isa = XCConfigurationList; 322 | buildConfigurations = ( 323 | 00FAC109193FEE5F004BB1DC /* Debug */, 324 | 00FAC10A193FEE5F004BB1DC /* Release */, 325 | ); 326 | defaultConfigurationIsVisible = 0; 327 | defaultConfigurationName = Release; 328 | }; 329 | 00FAC10B193FEE5F004BB1DC /* Build configuration list for PBXNativeTarget "Blink" */ = { 330 | isa = XCConfigurationList; 331 | buildConfigurations = ( 332 | 00FAC10C193FEE5F004BB1DC /* Debug */, 333 | 00FAC10D193FEE5F004BB1DC /* Release */, 334 | ); 335 | defaultConfigurationIsVisible = 0; 336 | }; 337 | /* End XCConfigurationList section */ 338 | }; 339 | rootObject = 00FAC0D2193FEE5F004BB1DC /* Project object */; 340 | } 341 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/project.xcworkspace/xcuserdata/aa.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/project.xcworkspace/xcuserdata/aa.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/xcuserdata/aa.xcuserdatad/xcschemes/Blink.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink.xcodeproj/xcuserdata/aa.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Blink.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 00FAC0D9193FEE5F004BB1DC 16 | 17 | primary 18 | 19 | 20 | 00FAC0FA193FEE5F004BB1DC 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Blink 4 | // 5 | // Created by Alasdair Allan on 05/06/2014. 6 | // Copyright (c) 2014 Babilim Light Industries. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BLE.h" 11 | 12 | @interface AppDelegate : NSObject 13 | 14 | @property (assign) IBOutlet NSWindow *window; 15 | @property (strong, nonatomic) BLE *ble; 16 | 17 | @property (weak) IBOutlet NSButton *connectButton; 18 | @property (weak) IBOutlet NSButton *toggleButton; 19 | @property (weak) IBOutlet NSTextField *label; 20 | 21 | - (IBAction)pushedConnect:(id)sender; 22 | - (IBAction)pushedToggle:(id)sender; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Blink 4 | // 5 | // Created by Alasdair Allan on 05/06/2014. 6 | // Copyright (c) 2014 Babilim Light Industries. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 14 | self.ble = [[BLE alloc] init]; 15 | [self.ble controlSetup:1]; 16 | self.ble.delegate = self; 17 | self.toggleButton.enabled = false; 18 | } 19 | 20 | - (IBAction)pushedConnect:(id)sender { 21 | if (self.ble.activePeripheral) { 22 | if(self.ble.activePeripheral.isConnected) { 23 | [[self.ble CM] cancelPeripheralConnection:[self.ble activePeripheral]]; 24 | return; 25 | } 26 | } 27 | 28 | if (self.ble.peripherals) { 29 | self.ble.peripherals = nil; 30 | } 31 | 32 | [self.ble findBLEPeripherals:2]; 33 | [NSTimer scheduledTimerWithTimeInterval:(float)2.0 target:self selector:@selector(connectionTimer:) userInfo:nil repeats:NO]; 34 | 35 | } 36 | 37 | -(void) connectionTimer:(NSTimer *)timer { 38 | if (self.ble.peripherals.count > 0) { 39 | int biscuit = -1; 40 | for (int i = 0; i < self.ble.peripherals.count; i++) { 41 | CBPeripheral *peripheral = [self.ble.peripherals objectAtIndex:i]; 42 | if ( [peripheral.name isEqualToString:@"Biscuit"] ) { 43 | biscuit = i; 44 | } 45 | } 46 | 47 | if ( biscuit != -1 ) { 48 | CBPeripheral *peripheral = [self.ble.peripherals objectAtIndex:biscuit]; 49 | [self.ble connectPeripheral:peripheral]; 50 | self.label.stringValue = [NSString stringWithFormat:@"Connecting to '%@'",peripheral.name]; 51 | } else { 52 | self.label.stringValue = @"Can not find BLE mini board"; 53 | } 54 | 55 | } else { 56 | self.label.stringValue = @"No BLE devices found"; 57 | } 58 | 59 | } 60 | 61 | - (IBAction)pushedToggle:(id)sender { 62 | UInt8 buf[1] = {0x01}; 63 | NSData *data = [[NSData alloc] initWithBytes:buf length:1]; 64 | [self.ble write:data]; 65 | NSLog(@"pushed button"); 66 | } 67 | 68 | #pragma mark - BLE delegate 69 | 70 | -(void) bleDidConnect { 71 | self.label.stringValue = @"Connected to BLE device"; 72 | self.connectButton.title = @"Disconnect"; 73 | self.toggleButton.enabled = true; 74 | } 75 | 76 | - (void)bleDidDisconnect { 77 | self.label.stringValue = @"Disconnected from BLE device"; 78 | self.connectButton.title = @"Connect"; 79 | self.toggleButton.enabled = false; 80 | } 81 | 82 | -(void) bleDidReceiveData:(unsigned char *)data length:(int)length { 83 | 84 | } 85 | 86 | -(void) bleDidUpdateRSSI:(NSNumber *) rssi { 87 | self.label.stringValue = [NSString stringWithFormat:@"RSSI Value: %@", rssi.stringValue]; 88 | 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/BLE.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | #import 15 | #if TARGET_OS_IPHONE 16 | #import 17 | #else 18 | #import 19 | #endif 20 | 21 | @protocol BLEDelegate 22 | @optional 23 | -(void) bleDidConnect; 24 | -(void) bleDidDisconnect; 25 | -(void) bleDidUpdateRSSI:(NSNumber *) rssi; 26 | -(void) bleDidReceiveData:(unsigned char *) data length:(int) length; 27 | @required 28 | @end 29 | 30 | @interface BLE : NSObject { 31 | 32 | } 33 | 34 | @property (nonatomic,assign) id delegate; 35 | @property (strong, nonatomic) NSMutableArray *peripherals; 36 | @property (strong, nonatomic) CBCentralManager *CM; 37 | @property (strong, nonatomic) CBPeripheral *activePeripheral; 38 | 39 | -(void) enableWrite; 40 | -(void) enableReadNotification:(CBPeripheral *)p; 41 | -(void) read; 42 | -(void) writeValue:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data; 43 | 44 | -(UInt16) readLibVer; 45 | -(UInt16) readFrameworkVersion; 46 | -(NSString *) readVendorName; 47 | -(BOOL) isConnected; 48 | -(int) readRSSI; 49 | -(void) write:(NSData *)d; 50 | 51 | -(int) controlSetup:(int) s; 52 | -(int) findBLEPeripherals:(int) timeout; 53 | -(void) connectPeripheral:(CBPeripheral *)peripheral; 54 | 55 | -(UInt16) swap:(UInt16) s; 56 | -(const char *) centralManagerStateToString:(int)state; 57 | -(void) scanTimer:(NSTimer *)timer; 58 | -(void) printKnownPeripherals; 59 | -(void) printPeripheralInfo:(CBPeripheral*)peripheral; 60 | 61 | -(void) getAllServicesFromPeripheral:(CBPeripheral *)p; 62 | -(void) getAllCharacteristicsFromPeripheral:(CBPeripheral *)p; 63 | -(CBService *) findServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p; 64 | -(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service; 65 | -(const char *) UUIDToString:(CFUUIDRef) UUID; 66 | -(const char *) CBUUIDToString:(CBUUID *) UUID; 67 | -(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2; 68 | -(int) compareCBUUIDToInt:(CBUUID *) UUID1 UUID2:(UInt16)UUID2; 69 | -(UInt16) CBUUIDToInt:(CBUUID *) UUID; 70 | -(int) UUIDSAreEqual:(CFUUIDRef)u1 u2:(CFUUIDRef)u2; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/BLE.m: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | #import "BLE.h" 15 | #import "BLEDefines.h" 16 | 17 | @implementation BLE 18 | 19 | @synthesize delegate; 20 | @synthesize CM; 21 | @synthesize peripherals; 22 | @synthesize activePeripheral; 23 | 24 | static UInt16 libver = 0; 25 | static unsigned char vendor_name[20] = {0}; 26 | static bool isConnected = false; 27 | static int rssi = 0; 28 | 29 | -(void) enableWrite 30 | { 31 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 32 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RESET_RX_UUID]; 33 | unsigned char bytes[] = {0x01}; 34 | NSData *d = [[NSData alloc] initWithBytes:bytes length:1]; 35 | [self writeValue:uuid_service characteristicUUID:uuid_char p:activePeripheral data:d]; 36 | } 37 | 38 | -(void) readLibVerFromPeripheral 39 | { 40 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 41 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_LIB_VERSION_UUID]; 42 | 43 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 44 | } 45 | 46 | -(void) readVendorNameFromPeripheral 47 | { 48 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 49 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_VENDOR_NAME_UUID]; 50 | 51 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 52 | } 53 | 54 | -(BOOL) isConnected 55 | { 56 | return isConnected; 57 | } 58 | 59 | -(void) read 60 | { 61 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 62 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]; 63 | 64 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 65 | } 66 | 67 | -(void) write:(NSData *)d 68 | { 69 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 70 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_TX_UUID]; 71 | 72 | [self writeValue:uuid_service characteristicUUID:uuid_char p:activePeripheral data:d]; 73 | } 74 | 75 | -(void) enableReadNotification:(CBPeripheral *)p 76 | { 77 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 78 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]; 79 | 80 | [self notification:uuid_service characteristicUUID:uuid_char p:p on:YES]; 81 | } 82 | 83 | -(void) notification:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p on:(BOOL)on 84 | { 85 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 86 | 87 | if (!service) 88 | { 89 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 90 | return; 91 | } 92 | 93 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 94 | 95 | if (!characteristic) 96 | { 97 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 98 | return; 99 | } 100 | 101 | [p setNotifyValue:on forCharacteristic:characteristic]; 102 | } 103 | 104 | -(int) readRSSI 105 | { 106 | return rssi; 107 | } 108 | 109 | -(UInt16) readLibVer 110 | { 111 | return libver; 112 | } 113 | 114 | -(UInt16) readFrameworkVersion 115 | { 116 | return BLE_FRAMEWORK_VERSION; 117 | } 118 | 119 | -(NSString *) readVendorName 120 | { 121 | return [NSString stringWithFormat:@"%s", vendor_name]; 122 | } 123 | 124 | -(void) readValue: (CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p 125 | { 126 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 127 | 128 | if (!service) 129 | { 130 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 131 | return; 132 | } 133 | 134 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 135 | 136 | if (!characteristic) 137 | { 138 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 139 | return; 140 | } 141 | 142 | [p readValueForCharacteristic:characteristic]; 143 | } 144 | 145 | -(void) writeValue:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data 146 | { 147 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 148 | 149 | if (!service) 150 | { 151 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 152 | return; 153 | } 154 | 155 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 156 | 157 | if (!characteristic) 158 | { 159 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 160 | return; 161 | } 162 | 163 | [p writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse]; 164 | } 165 | 166 | -(UInt16) swap:(UInt16)s 167 | { 168 | UInt16 temp = s << 8; 169 | temp |= (s >> 8); 170 | return temp; 171 | } 172 | 173 | - (int) controlSetup: (int) s 174 | { 175 | self.CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 176 | return 0; 177 | } 178 | 179 | - (int) findBLEPeripherals:(int) timeout 180 | { 181 | if (self.CM.state != CBCentralManagerStatePoweredOn) { 182 | printf("CoreBluetooth not correctly initialized !\r\n"); 183 | printf("State = %d (%s)\r\n", self.CM.state,[self centralManagerStateToString:self.CM.state]); 184 | return -1; 185 | } 186 | 187 | [NSTimer scheduledTimerWithTimeInterval:(float)timeout target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO]; 188 | 189 | #if TARGET_OS_IPHONE 190 | [self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]] options:nil]; 191 | #else 192 | [self.CM scanForPeripheralsWithServices:nil options:nil]; // Start scanning 193 | #endif 194 | 195 | NSLog(@"scanForPeripheralsWithServices"); 196 | 197 | return 0; // Started scanning OK ! 198 | } 199 | 200 | - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error; 201 | { 202 | done = false; 203 | 204 | [[self delegate] bleDidDisconnect]; 205 | 206 | isConnected = false; 207 | } 208 | 209 | - (void) connectPeripheral:(CBPeripheral *)peripheral { 210 | printf("Connecting to peripheral with UUID : %s\r\n",[self UUIDToString:peripheral.UUID]); 211 | self.activePeripheral = peripheral; 212 | self.activePeripheral.delegate = self; 213 | [self.CM connectPeripheral:self.activePeripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]]; 214 | } 215 | 216 | - (const char *) centralManagerStateToString: (int)state 217 | { 218 | switch(state) 219 | { 220 | case CBCentralManagerStateUnknown: 221 | return "State unknown (CBCentralManagerStateUnknown)"; 222 | case CBCentralManagerStateResetting: 223 | return "State resetting (CBCentralManagerStateUnknown)"; 224 | case CBCentralManagerStateUnsupported: 225 | return "State BLE unsupported (CBCentralManagerStateResetting)"; 226 | case CBCentralManagerStateUnauthorized: 227 | return "State unauthorized (CBCentralManagerStateUnauthorized)"; 228 | case CBCentralManagerStatePoweredOff: 229 | return "State BLE powered off (CBCentralManagerStatePoweredOff)"; 230 | case CBCentralManagerStatePoweredOn: 231 | return "State powered up and ready (CBCentralManagerStatePoweredOn)"; 232 | default: 233 | return "State unknown"; 234 | } 235 | 236 | return "Unknown state"; 237 | } 238 | 239 | - (void) scanTimer:(NSTimer *)timer 240 | { 241 | [self.CM stopScan]; 242 | printf("Stopped Scanning\r\n"); 243 | printf("Known peripherals : %d\r\n",[self.peripherals count]); 244 | [self printKnownPeripherals]; 245 | } 246 | 247 | - (void) printKnownPeripherals 248 | { 249 | int i; 250 | 251 | printf("List of currently known peripherals : \r\n"); 252 | 253 | for (i = 0; i < self.peripherals.count; i++) 254 | { 255 | CBPeripheral *p = [self.peripherals objectAtIndex:i]; 256 | 257 | if (p.UUID != NULL) 258 | { 259 | CFStringRef s = CFUUIDCreateString(NULL, p.UUID); 260 | printf("%d | %s\r\n",i,CFStringGetCStringPtr(s, 0)); 261 | } 262 | else 263 | printf("%d | NULL\r\n",i); 264 | 265 | [self printPeripheralInfo:p]; 266 | } 267 | } 268 | 269 | - (void) printPeripheralInfo:(CBPeripheral*)peripheral 270 | { 271 | printf("------------------------------------\n"); 272 | printf("Peripheral Info :\n"); 273 | 274 | if (peripheral.UUID != NULL) 275 | { 276 | CFStringRef s = CFUUIDCreateString(NULL, peripheral.UUID); 277 | printf("UUID : %s\n",CFStringGetCStringPtr(s, 0)); 278 | } 279 | else 280 | printf("UUID : NULL\n"); 281 | 282 | printf("Name : %s\n",[peripheral.name cStringUsingEncoding:NSStringEncodingConversionAllowLossy]); 283 | printf("-------------------------------------\n"); 284 | } 285 | 286 | - (int) UUIDSAreEqual:(CFUUIDRef)u1 u2:(CFUUIDRef)u2 287 | { 288 | CFUUIDBytes b1 = CFUUIDGetUUIDBytes(u1); 289 | CFUUIDBytes b2 = CFUUIDGetUUIDBytes(u2); 290 | 291 | if (memcmp(&b1, &b2, 16) == 0) { 292 | return 1; 293 | } 294 | else 295 | return 0; 296 | } 297 | 298 | -(void) getAllServicesFromPeripheral:(CBPeripheral *)p 299 | { 300 | [p discoverServices:nil]; // Discover all services without filter 301 | } 302 | 303 | -(void) getAllCharacteristicsFromPeripheral:(CBPeripheral *)p 304 | { 305 | for (int i=0; i < p.services.count; i++) 306 | { 307 | CBService *s = [p.services objectAtIndex:i]; 308 | // printf("Fetching characteristics for service with UUID : %s\r\n",[self CBUUIDToString:s.UUID]); 309 | [p discoverCharacteristics:nil forService:s]; 310 | } 311 | } 312 | 313 | -(const char *) CBUUIDToString:(CBUUID *) UUID 314 | { 315 | return [[UUID.data description] cStringUsingEncoding:NSStringEncodingConversionAllowLossy]; 316 | } 317 | 318 | -(const char *) UUIDToString:(CFUUIDRef)UUID 319 | { 320 | if (!UUID) 321 | return "NULL"; 322 | 323 | CFStringRef s = CFUUIDCreateString(NULL, UUID); 324 | 325 | return CFStringGetCStringPtr(s, 0); 326 | } 327 | 328 | -(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2 329 | { 330 | char b1[16]; 331 | char b2[16]; 332 | [UUID1.data getBytes:b1]; 333 | [UUID2.data getBytes:b2]; 334 | if (memcmp(b1, b2, UUID1.data.length) == 0)return 1; 335 | else return 0; 336 | } 337 | 338 | -(int) compareCBUUIDToInt:(CBUUID *)UUID1 UUID2:(UInt16)UUID2 339 | { 340 | char b1[16]; 341 | 342 | [UUID1.data getBytes:b1]; 343 | UInt16 b2 = [self swap:UUID2]; 344 | 345 | if (memcmp(b1, (char *)&b2, 2) == 0) 346 | return 1; 347 | else 348 | return 0; 349 | } 350 | 351 | -(UInt16) CBUUIDToInt:(CBUUID *) UUID 352 | { 353 | char b1[16]; 354 | [UUID.data getBytes:b1]; 355 | return ((b1[0] << 8) | b1[1]); 356 | } 357 | 358 | -(CBUUID *) IntToCBUUID:(UInt16)UUID 359 | { 360 | char t[16]; 361 | t[0] = ((UUID >> 8) & 0xff); t[1] = (UUID & 0xff); 362 | NSData *data = [[NSData alloc] initWithBytes:t length:16]; 363 | return [CBUUID UUIDWithData:data]; 364 | } 365 | 366 | -(CBService *) findServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p 367 | { 368 | for(int i = 0; i < p.services.count; i++) 369 | { 370 | CBService *s = [p.services objectAtIndex:i]; 371 | if ([self compareCBUUID:s.UUID UUID2:UUID]) return s; 372 | } 373 | 374 | return nil; //Service not found on this peripheral 375 | } 376 | 377 | -(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service 378 | { 379 | for(int i=0; i < service.characteristics.count; i++) 380 | { 381 | CBCharacteristic *c = [service.characteristics objectAtIndex:i]; 382 | if ([self compareCBUUID:c.UUID UUID2:UUID]) return c; 383 | } 384 | 385 | return nil; //Characteristic not found on this service 386 | } 387 | 388 | #if TARGET_OS_IPHONE 389 | //-- no need for iOS 390 | #else 391 | - (BOOL) isLECapableHardware 392 | { 393 | NSString * state = nil; 394 | 395 | switch ([CM state]) 396 | { 397 | case CBCentralManagerStateUnsupported: 398 | state = @"The platform/hardware doesn't support Bluetooth Low Energy."; 399 | break; 400 | case CBCentralManagerStateUnauthorized: 401 | state = @"The app is not authorized to use Bluetooth Low Energy."; 402 | break; 403 | case CBCentralManagerStatePoweredOff: 404 | state = @"Bluetooth is currently powered off."; 405 | break; 406 | case CBCentralManagerStatePoweredOn: 407 | return TRUE; 408 | case CBCentralManagerStateUnknown: 409 | default: 410 | return FALSE; 411 | 412 | } 413 | 414 | NSLog(@"Central manager state: %@", state); 415 | 416 | NSAlert *alert = [[NSAlert alloc] init]; 417 | [alert setMessageText:state]; 418 | [alert addButtonWithTitle:@"OK"]; 419 | [alert setIcon:[[NSImage alloc] initWithContentsOfFile:@"AppIcon"]]; 420 | [alert beginSheetModalForWindow:nil modalDelegate:self didEndSelector:nil contextInfo:nil]; 421 | return FALSE; 422 | } 423 | #endif 424 | 425 | - (void)centralManagerDidUpdateState:(CBCentralManager *)central 426 | { 427 | #if TARGET_OS_IPHONE 428 | printf("Status of CoreBluetooth central manager changed %d (%s)\r\n",central.state,[self centralManagerStateToString:central.state]); 429 | #else 430 | [self isLECapableHardware]; 431 | #endif 432 | } 433 | 434 | - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 435 | { 436 | if (!self.peripherals) 437 | self.peripherals = [[NSMutableArray alloc] initWithObjects:peripheral,nil]; 438 | else 439 | { 440 | for(int i = 0; i < self.peripherals.count; i++) 441 | { 442 | CBPeripheral *p = [self.peripherals objectAtIndex:i]; 443 | 444 | if ((p.UUID == NULL) || (peripheral.UUID == NULL)) 445 | continue; 446 | 447 | if ([self UUIDSAreEqual:p.UUID u2:peripheral.UUID]) 448 | { 449 | [self.peripherals replaceObjectAtIndex:i withObject:peripheral]; 450 | printf("Duplicate UUID found updating ...\n"); 451 | return; 452 | } 453 | } 454 | 455 | [self.peripherals addObject:peripheral]; 456 | 457 | printf("New UUID, adding\r\n"); 458 | } 459 | 460 | printf("didDiscoverPeripheral\r\n"); 461 | } 462 | 463 | - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 464 | { 465 | if (peripheral.UUID != NULL) 466 | printf("Connected to %s successful\n",[self UUIDToString:peripheral.UUID]); 467 | else 468 | printf("Connected to NULL successful\n"); 469 | self.activePeripheral = peripheral; 470 | [self.activePeripheral discoverServices:nil]; 471 | [self getAllServicesFromPeripheral:peripheral]; 472 | } 473 | 474 | static bool done = false; 475 | 476 | - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error 477 | { 478 | if (!error) 479 | { 480 | // printf("Characteristics of service with UUID : %s found\n",[self CBUUIDToString:service.UUID]); 481 | 482 | for (int i=0; i < service.characteristics.count; i++) 483 | { 484 | // CBCharacteristic *c = [service.characteristics objectAtIndex:i]; 485 | // printf("Found characteristic %s\n",[ self CBUUIDToString:c.UUID]); 486 | CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)]; 487 | 488 | if ([service.UUID isEqual:s.UUID]) 489 | { 490 | if (!done) 491 | { 492 | [self enableReadNotification:activePeripheral]; 493 | [self readLibVerFromPeripheral]; 494 | [self readVendorNameFromPeripheral]; 495 | 496 | [[self delegate] bleDidConnect]; 497 | 498 | isConnected = true; 499 | [activePeripheral readRSSI]; 500 | 501 | done = true; 502 | } 503 | 504 | break; 505 | } 506 | } 507 | } 508 | else 509 | { 510 | printf("Characteristic discorvery unsuccessful!\r\n"); 511 | } 512 | } 513 | 514 | - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 515 | { 516 | if (!error) 517 | { 518 | // printf("Services of peripheral with UUID : %s found\n",[self UUIDToString:peripheral.UUID]); 519 | [self getAllCharacteristicsFromPeripheral:peripheral]; 520 | } 521 | else 522 | { 523 | printf("Service discovery was unsuccessful!\n"); 524 | } 525 | } 526 | 527 | - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 528 | { 529 | if (!error) 530 | { 531 | // printf("Updated notification state for characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristic.UUID],[self CBUUIDToString:characteristic.service.UUID],[self UUIDToString:peripheral.UUID]); 532 | } 533 | else 534 | { 535 | printf("Error in setting notification state for characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristic.UUID],[self CBUUIDToString:characteristic.service.UUID],[self UUIDToString:peripheral.UUID]); 536 | printf("Error code was %s\r\n",[[error description] cStringUsingEncoding:NSStringEncodingConversionAllowLossy]); 537 | } 538 | } 539 | 540 | - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 541 | { 542 | unsigned char data[BLE_DEVICE_RX_READ_LEN]; 543 | 544 | static unsigned char buf[512]; 545 | static int len = 0; 546 | int data_len; 547 | 548 | if (!error) 549 | { 550 | if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]]) 551 | { 552 | data_len = characteristic.value.length; 553 | [characteristic.value getBytes:data length:data_len]; 554 | 555 | if (data_len == 20) 556 | { 557 | memcpy(&buf[len], data, 20); 558 | len += data_len; 559 | 560 | if (len >= 64) 561 | { 562 | [[self delegate] bleDidReceiveData:buf length:len]; 563 | len = 0; 564 | } 565 | } 566 | else if (data_len < 20) 567 | { 568 | memcpy(&buf[len], data, data_len); 569 | len += data_len; 570 | 571 | [[self delegate] bleDidReceiveData:buf length:len]; 572 | len = 0; 573 | } 574 | 575 | [self enableWrite]; 576 | } 577 | else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_VENDOR_NAME_UUID]]) 578 | { 579 | data_len = characteristic.value.length; 580 | [characteristic.value getBytes:vendor_name length:data_len]; 581 | // NSLog(@"Vendor: %s", vendor_name); 582 | } 583 | else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_LIB_VERSION_UUID]]) 584 | { 585 | [characteristic.value getBytes:&libver length:2]; 586 | // NSLog(@"Lib. ver.: %X", libver); 587 | } 588 | } 589 | else 590 | { 591 | printf("updateValueForCharacteristic failed!"); 592 | } 593 | } 594 | 595 | - (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error 596 | { 597 | if (!isConnected) 598 | return; 599 | 600 | if (rssi != peripheral.RSSI.intValue) 601 | { 602 | rssi = peripheral.RSSI.intValue; 603 | [[self delegate] bleDidUpdateRSSI:activePeripheral.RSSI]; 604 | } 605 | [activePeripheral readRSSI]; 606 | } 607 | 608 | @end 609 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/BLEDefines.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | // BLE Device Service 15 | #define BLE_DEVICE_SERVICE_UUID "713D0000-503E-4C75-BA94-3148F18D941E" 16 | 17 | #define BLE_DEVICE_VENDOR_NAME_UUID "713D0001-503E-4C75-BA94-3148F18D941E" 18 | 19 | #define BLE_DEVICE_RX_UUID "713D0002-503E-4C75-BA94-3148F18D941E" 20 | #define BLE_DEVICE_RX_READ_LEN 20 21 | 22 | #define BLE_DEVICE_TX_UUID "713D0003-503E-4C75-BA94-3148F18D941E" 23 | #define BLE_DEVICE_TX_WRITE_LEN 20 24 | 25 | #define BLE_DEVICE_RESET_RX_UUID "713D0004-503E-4C75-BA94-3148F18D941E" 26 | 27 | #define BLE_DEVICE_LIB_VERSION_UUID "713D0005-503E-4C75-BA94-3148F18D941E" 28 | 29 | #define BLE_FRAMEWORK_VERSION 0x0102 30 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 60 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/Blink-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | uk.co.babilim.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2014 Babilim Light Industries. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/Blink-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink for Mac/Blink/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Blink 4 | // 5 | // Created by Alasdair Allan on 05/06/2014. 6 | // Copyright (c) 2014 Babilim Light Industries. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) 12 | { 13 | return NSApplicationMain(argc, argv); 14 | } 15 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/Blink/Blink.ino: -------------------------------------------------------------------------------- 1 | 2 | int pinState = 0; 3 | 4 | void setup() { 5 | pinMode(12, OUTPUT); 6 | pinMode(13, OUTPUT); 7 | Serial.begin(57600); 8 | digitalWrite( 12, HIGH ); 9 | } 10 | 11 | void loop() { 12 | while( Serial.available() ) { 13 | byte dat = Serial.read(); 14 | //if ( dat == 0x01 ) { 15 | if ( pinState == 0 ) { 16 | pinState = 1; 17 | digitalWrite( 13, HIGH); 18 | } else { 19 | pinState = 0; 20 | digitalWrite( 13, LOW ); 21 | } 22 | //} 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/README.md: -------------------------------------------------------------------------------- 1 | #RedBearLab BLE Mini 2 | 3 | Simple Max OS X example application, with accompanying Arduino code and Arduino wiring diagram, to let you blink an LED on and off via BLE. 4 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/circuit.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/redbearlab/blemini/led_serial/circuit.fzz -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigoe/BLEDocs/0a06a1ac98cd3a68d59bc164fadbf15b5f06a76c/examples/redbearlab/blemini/led_serial/circuit.png -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/library/BLE.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | #import 15 | #if TARGET_OS_IPHONE 16 | #import 17 | #else 18 | #import 19 | #endif 20 | 21 | @protocol BLEDelegate 22 | @optional 23 | -(void) bleDidConnect; 24 | -(void) bleDidDisconnect; 25 | -(void) bleDidUpdateRSSI:(NSNumber *) rssi; 26 | -(void) bleDidReceiveData:(unsigned char *) data length:(int) length; 27 | @required 28 | @end 29 | 30 | @interface BLE : NSObject { 31 | 32 | } 33 | 34 | @property (nonatomic,assign) id delegate; 35 | @property (strong, nonatomic) NSMutableArray *peripherals; 36 | @property (strong, nonatomic) CBCentralManager *CM; 37 | @property (strong, nonatomic) CBPeripheral *activePeripheral; 38 | 39 | -(void) enableWrite; 40 | -(void) enableReadNotification:(CBPeripheral *)p; 41 | -(void) read; 42 | -(void) writeValue:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data; 43 | 44 | -(UInt16) readLibVer; 45 | -(UInt16) readFrameworkVersion; 46 | -(NSString *) readVendorName; 47 | -(BOOL) isConnected; 48 | -(int) readRSSI; 49 | -(void) write:(NSData *)d; 50 | 51 | -(int) controlSetup:(int) s; 52 | -(int) findBLEPeripherals:(int) timeout; 53 | -(void) connectPeripheral:(CBPeripheral *)peripheral; 54 | 55 | -(UInt16) swap:(UInt16) s; 56 | -(const char *) centralManagerStateToString:(int)state; 57 | -(void) scanTimer:(NSTimer *)timer; 58 | -(void) printKnownPeripherals; 59 | -(void) printPeripheralInfo:(CBPeripheral*)peripheral; 60 | 61 | -(void) getAllServicesFromPeripheral:(CBPeripheral *)p; 62 | -(void) getAllCharacteristicsFromPeripheral:(CBPeripheral *)p; 63 | -(CBService *) findServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p; 64 | -(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service; 65 | -(const char *) UUIDToString:(CFUUIDRef) UUID; 66 | -(const char *) CBUUIDToString:(CBUUID *) UUID; 67 | -(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2; 68 | -(int) compareCBUUIDToInt:(CBUUID *) UUID1 UUID2:(UInt16)UUID2; 69 | -(UInt16) CBUUIDToInt:(CBUUID *) UUID; 70 | -(int) UUIDSAreEqual:(CFUUIDRef)u1 u2:(CFUUIDRef)u2; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/library/BLE.m: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | #import "BLE.h" 15 | #import "BLEDefines.h" 16 | 17 | @implementation BLE 18 | 19 | @synthesize delegate; 20 | @synthesize CM; 21 | @synthesize peripherals; 22 | @synthesize activePeripheral; 23 | 24 | static UInt16 libver = 0; 25 | static unsigned char vendor_name[20] = {0}; 26 | static bool isConnected = false; 27 | static int rssi = 0; 28 | 29 | -(void) enableWrite 30 | { 31 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 32 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RESET_RX_UUID]; 33 | unsigned char bytes[] = {0x01}; 34 | NSData *d = [[NSData alloc] initWithBytes:bytes length:1]; 35 | [self writeValue:uuid_service characteristicUUID:uuid_char p:activePeripheral data:d]; 36 | } 37 | 38 | -(void) readLibVerFromPeripheral 39 | { 40 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 41 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_LIB_VERSION_UUID]; 42 | 43 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 44 | } 45 | 46 | -(void) readVendorNameFromPeripheral 47 | { 48 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 49 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_VENDOR_NAME_UUID]; 50 | 51 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 52 | } 53 | 54 | -(BOOL) isConnected 55 | { 56 | return isConnected; 57 | } 58 | 59 | -(void) read 60 | { 61 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 62 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]; 63 | 64 | [self readValue:uuid_service characteristicUUID:uuid_char p:activePeripheral]; 65 | } 66 | 67 | -(void) write:(NSData *)d 68 | { 69 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 70 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_TX_UUID]; 71 | 72 | [self writeValue:uuid_service characteristicUUID:uuid_char p:activePeripheral data:d]; 73 | } 74 | 75 | -(void) enableReadNotification:(CBPeripheral *)p 76 | { 77 | CBUUID *uuid_service = [CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]; 78 | CBUUID *uuid_char = [CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]; 79 | 80 | [self notification:uuid_service characteristicUUID:uuid_char p:p on:YES]; 81 | } 82 | 83 | -(void) notification:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p on:(BOOL)on 84 | { 85 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 86 | 87 | if (!service) 88 | { 89 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 90 | return; 91 | } 92 | 93 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 94 | 95 | if (!characteristic) 96 | { 97 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 98 | return; 99 | } 100 | 101 | [p setNotifyValue:on forCharacteristic:characteristic]; 102 | } 103 | 104 | -(int) readRSSI 105 | { 106 | return rssi; 107 | } 108 | 109 | -(UInt16) readLibVer 110 | { 111 | return libver; 112 | } 113 | 114 | -(UInt16) readFrameworkVersion 115 | { 116 | return BLE_FRAMEWORK_VERSION; 117 | } 118 | 119 | -(NSString *) readVendorName 120 | { 121 | return [NSString stringWithFormat:@"%s", vendor_name]; 122 | } 123 | 124 | -(void) readValue: (CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p 125 | { 126 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 127 | 128 | if (!service) 129 | { 130 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 131 | return; 132 | } 133 | 134 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 135 | 136 | if (!characteristic) 137 | { 138 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 139 | return; 140 | } 141 | 142 | [p readValueForCharacteristic:characteristic]; 143 | } 144 | 145 | -(void) writeValue:(CBUUID *)serviceUUID characteristicUUID:(CBUUID *)characteristicUUID p:(CBPeripheral *)p data:(NSData *)data 146 | { 147 | CBService *service = [self findServiceFromUUID:serviceUUID p:p]; 148 | 149 | if (!service) 150 | { 151 | printf("Could not find service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 152 | return; 153 | } 154 | 155 | CBCharacteristic *characteristic = [self findCharacteristicFromUUID:characteristicUUID service:service]; 156 | 157 | if (!characteristic) 158 | { 159 | printf("Could not find characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristicUUID],[self CBUUIDToString:serviceUUID],[self UUIDToString:p.UUID]); 160 | return; 161 | } 162 | 163 | [p writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse]; 164 | } 165 | 166 | -(UInt16) swap:(UInt16)s 167 | { 168 | UInt16 temp = s << 8; 169 | temp |= (s >> 8); 170 | return temp; 171 | } 172 | 173 | - (int) controlSetup: (int) s 174 | { 175 | self.CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; 176 | return 0; 177 | } 178 | 179 | - (int) findBLEPeripherals:(int) timeout 180 | { 181 | if (self.CM.state != CBCentralManagerStatePoweredOn) { 182 | printf("CoreBluetooth not correctly initialized !\r\n"); 183 | printf("State = %d (%s)\r\n", self.CM.state,[self centralManagerStateToString:self.CM.state]); 184 | return -1; 185 | } 186 | 187 | [NSTimer scheduledTimerWithTimeInterval:(float)timeout target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO]; 188 | 189 | #if TARGET_OS_IPHONE 190 | [self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@BLE_DEVICE_SERVICE_UUID]] options:nil]; 191 | #else 192 | [self.CM scanForPeripheralsWithServices:nil options:nil]; // Start scanning 193 | #endif 194 | 195 | NSLog(@"scanForPeripheralsWithServices"); 196 | 197 | return 0; // Started scanning OK ! 198 | } 199 | 200 | - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error; 201 | { 202 | done = false; 203 | 204 | [[self delegate] bleDidDisconnect]; 205 | 206 | isConnected = false; 207 | } 208 | 209 | - (void) connectPeripheral:(CBPeripheral *)peripheral { 210 | printf("Connecting to peripheral with UUID : %s\r\n",[self UUIDToString:peripheral.UUID]); 211 | self.activePeripheral = peripheral; 212 | self.activePeripheral.delegate = self; 213 | [self.CM connectPeripheral:self.activePeripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]]; 214 | } 215 | 216 | - (const char *) centralManagerStateToString: (int)state 217 | { 218 | switch(state) 219 | { 220 | case CBCentralManagerStateUnknown: 221 | return "State unknown (CBCentralManagerStateUnknown)"; 222 | case CBCentralManagerStateResetting: 223 | return "State resetting (CBCentralManagerStateUnknown)"; 224 | case CBCentralManagerStateUnsupported: 225 | return "State BLE unsupported (CBCentralManagerStateResetting)"; 226 | case CBCentralManagerStateUnauthorized: 227 | return "State unauthorized (CBCentralManagerStateUnauthorized)"; 228 | case CBCentralManagerStatePoweredOff: 229 | return "State BLE powered off (CBCentralManagerStatePoweredOff)"; 230 | case CBCentralManagerStatePoweredOn: 231 | return "State powered up and ready (CBCentralManagerStatePoweredOn)"; 232 | default: 233 | return "State unknown"; 234 | } 235 | 236 | return "Unknown state"; 237 | } 238 | 239 | - (void) scanTimer:(NSTimer *)timer 240 | { 241 | [self.CM stopScan]; 242 | printf("Stopped Scanning\r\n"); 243 | printf("Known peripherals : %d\r\n",[self.peripherals count]); 244 | [self printKnownPeripherals]; 245 | } 246 | 247 | - (void) printKnownPeripherals 248 | { 249 | int i; 250 | 251 | printf("List of currently known peripherals : \r\n"); 252 | 253 | for (i = 0; i < self.peripherals.count; i++) 254 | { 255 | CBPeripheral *p = [self.peripherals objectAtIndex:i]; 256 | 257 | if (p.UUID != NULL) 258 | { 259 | CFStringRef s = CFUUIDCreateString(NULL, p.UUID); 260 | printf("%d | %s\r\n",i,CFStringGetCStringPtr(s, 0)); 261 | } 262 | else 263 | printf("%d | NULL\r\n",i); 264 | 265 | [self printPeripheralInfo:p]; 266 | } 267 | } 268 | 269 | - (void) printPeripheralInfo:(CBPeripheral*)peripheral 270 | { 271 | printf("------------------------------------\n"); 272 | printf("Peripheral Info :\n"); 273 | 274 | if (peripheral.UUID != NULL) 275 | { 276 | CFStringRef s = CFUUIDCreateString(NULL, peripheral.UUID); 277 | printf("UUID : %s\n",CFStringGetCStringPtr(s, 0)); 278 | } 279 | else 280 | printf("UUID : NULL\n"); 281 | 282 | printf("Name : %s\n",[peripheral.name cStringUsingEncoding:NSStringEncodingConversionAllowLossy]); 283 | printf("-------------------------------------\n"); 284 | } 285 | 286 | - (int) UUIDSAreEqual:(CFUUIDRef)u1 u2:(CFUUIDRef)u2 287 | { 288 | CFUUIDBytes b1 = CFUUIDGetUUIDBytes(u1); 289 | CFUUIDBytes b2 = CFUUIDGetUUIDBytes(u2); 290 | 291 | if (memcmp(&b1, &b2, 16) == 0) { 292 | return 1; 293 | } 294 | else 295 | return 0; 296 | } 297 | 298 | -(void) getAllServicesFromPeripheral:(CBPeripheral *)p 299 | { 300 | [p discoverServices:nil]; // Discover all services without filter 301 | } 302 | 303 | -(void) getAllCharacteristicsFromPeripheral:(CBPeripheral *)p 304 | { 305 | for (int i=0; i < p.services.count; i++) 306 | { 307 | CBService *s = [p.services objectAtIndex:i]; 308 | // printf("Fetching characteristics for service with UUID : %s\r\n",[self CBUUIDToString:s.UUID]); 309 | [p discoverCharacteristics:nil forService:s]; 310 | } 311 | } 312 | 313 | -(const char *) CBUUIDToString:(CBUUID *) UUID 314 | { 315 | return [[UUID.data description] cStringUsingEncoding:NSStringEncodingConversionAllowLossy]; 316 | } 317 | 318 | -(const char *) UUIDToString:(CFUUIDRef)UUID 319 | { 320 | if (!UUID) 321 | return "NULL"; 322 | 323 | CFStringRef s = CFUUIDCreateString(NULL, UUID); 324 | 325 | return CFStringGetCStringPtr(s, 0); 326 | } 327 | 328 | -(int) compareCBUUID:(CBUUID *) UUID1 UUID2:(CBUUID *)UUID2 329 | { 330 | char b1[16]; 331 | char b2[16]; 332 | [UUID1.data getBytes:b1]; 333 | [UUID2.data getBytes:b2]; 334 | if (memcmp(b1, b2, UUID1.data.length) == 0)return 1; 335 | else return 0; 336 | } 337 | 338 | -(int) compareCBUUIDToInt:(CBUUID *)UUID1 UUID2:(UInt16)UUID2 339 | { 340 | char b1[16]; 341 | 342 | [UUID1.data getBytes:b1]; 343 | UInt16 b2 = [self swap:UUID2]; 344 | 345 | if (memcmp(b1, (char *)&b2, 2) == 0) 346 | return 1; 347 | else 348 | return 0; 349 | } 350 | 351 | -(UInt16) CBUUIDToInt:(CBUUID *) UUID 352 | { 353 | char b1[16]; 354 | [UUID.data getBytes:b1]; 355 | return ((b1[0] << 8) | b1[1]); 356 | } 357 | 358 | -(CBUUID *) IntToCBUUID:(UInt16)UUID 359 | { 360 | char t[16]; 361 | t[0] = ((UUID >> 8) & 0xff); t[1] = (UUID & 0xff); 362 | NSData *data = [[NSData alloc] initWithBytes:t length:16]; 363 | return [CBUUID UUIDWithData:data]; 364 | } 365 | 366 | -(CBService *) findServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p 367 | { 368 | for(int i = 0; i < p.services.count; i++) 369 | { 370 | CBService *s = [p.services objectAtIndex:i]; 371 | if ([self compareCBUUID:s.UUID UUID2:UUID]) return s; 372 | } 373 | 374 | return nil; //Service not found on this peripheral 375 | } 376 | 377 | -(CBCharacteristic *) findCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service 378 | { 379 | for(int i=0; i < service.characteristics.count; i++) 380 | { 381 | CBCharacteristic *c = [service.characteristics objectAtIndex:i]; 382 | if ([self compareCBUUID:c.UUID UUID2:UUID]) return c; 383 | } 384 | 385 | return nil; //Characteristic not found on this service 386 | } 387 | 388 | #if TARGET_OS_IPHONE 389 | //-- no need for iOS 390 | #else 391 | - (BOOL) isLECapableHardware 392 | { 393 | NSString * state = nil; 394 | 395 | switch ([CM state]) 396 | { 397 | case CBCentralManagerStateUnsupported: 398 | state = @"The platform/hardware doesn't support Bluetooth Low Energy."; 399 | break; 400 | case CBCentralManagerStateUnauthorized: 401 | state = @"The app is not authorized to use Bluetooth Low Energy."; 402 | break; 403 | case CBCentralManagerStatePoweredOff: 404 | state = @"Bluetooth is currently powered off."; 405 | break; 406 | case CBCentralManagerStatePoweredOn: 407 | return TRUE; 408 | case CBCentralManagerStateUnknown: 409 | default: 410 | return FALSE; 411 | 412 | } 413 | 414 | NSLog(@"Central manager state: %@", state); 415 | 416 | NSAlert *alert = [[NSAlert alloc] init]; 417 | [alert setMessageText:state]; 418 | [alert addButtonWithTitle:@"OK"]; 419 | [alert setIcon:[[NSImage alloc] initWithContentsOfFile:@"AppIcon"]]; 420 | [alert beginSheetModalForWindow:nil modalDelegate:self didEndSelector:nil contextInfo:nil]; 421 | return FALSE; 422 | } 423 | #endif 424 | 425 | - (void)centralManagerDidUpdateState:(CBCentralManager *)central 426 | { 427 | #if TARGET_OS_IPHONE 428 | printf("Status of CoreBluetooth central manager changed %d (%s)\r\n",central.state,[self centralManagerStateToString:central.state]); 429 | #else 430 | [self isLECapableHardware]; 431 | #endif 432 | } 433 | 434 | - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI 435 | { 436 | if (!self.peripherals) 437 | self.peripherals = [[NSMutableArray alloc] initWithObjects:peripheral,nil]; 438 | else 439 | { 440 | for(int i = 0; i < self.peripherals.count; i++) 441 | { 442 | CBPeripheral *p = [self.peripherals objectAtIndex:i]; 443 | 444 | if ((p.UUID == NULL) || (peripheral.UUID == NULL)) 445 | continue; 446 | 447 | if ([self UUIDSAreEqual:p.UUID u2:peripheral.UUID]) 448 | { 449 | [self.peripherals replaceObjectAtIndex:i withObject:peripheral]; 450 | printf("Duplicate UUID found updating ...\n"); 451 | return; 452 | } 453 | } 454 | 455 | [self.peripherals addObject:peripheral]; 456 | 457 | printf("New UUID, adding\r\n"); 458 | } 459 | 460 | printf("didDiscoverPeripheral\r\n"); 461 | } 462 | 463 | - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral 464 | { 465 | if (peripheral.UUID != NULL) 466 | printf("Connected to %s successful\n",[self UUIDToString:peripheral.UUID]); 467 | else 468 | printf("Connected to NULL successful\n"); 469 | self.activePeripheral = peripheral; 470 | [self.activePeripheral discoverServices:nil]; 471 | [self getAllServicesFromPeripheral:peripheral]; 472 | } 473 | 474 | static bool done = false; 475 | 476 | - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error 477 | { 478 | if (!error) 479 | { 480 | // printf("Characteristics of service with UUID : %s found\n",[self CBUUIDToString:service.UUID]); 481 | 482 | for (int i=0; i < service.characteristics.count; i++) 483 | { 484 | // CBCharacteristic *c = [service.characteristics objectAtIndex:i]; 485 | // printf("Found characteristic %s\n",[ self CBUUIDToString:c.UUID]); 486 | CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)]; 487 | 488 | if ([service.UUID isEqual:s.UUID]) 489 | { 490 | if (!done) 491 | { 492 | [self enableReadNotification:activePeripheral]; 493 | [self readLibVerFromPeripheral]; 494 | [self readVendorNameFromPeripheral]; 495 | 496 | [[self delegate] bleDidConnect]; 497 | 498 | isConnected = true; 499 | [activePeripheral readRSSI]; 500 | 501 | done = true; 502 | } 503 | 504 | break; 505 | } 506 | } 507 | } 508 | else 509 | { 510 | printf("Characteristic discorvery unsuccessful!\r\n"); 511 | } 512 | } 513 | 514 | - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error 515 | { 516 | if (!error) 517 | { 518 | // printf("Services of peripheral with UUID : %s found\n",[self UUIDToString:peripheral.UUID]); 519 | [self getAllCharacteristicsFromPeripheral:peripheral]; 520 | } 521 | else 522 | { 523 | printf("Service discovery was unsuccessful!\n"); 524 | } 525 | } 526 | 527 | - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 528 | { 529 | if (!error) 530 | { 531 | // printf("Updated notification state for characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristic.UUID],[self CBUUIDToString:characteristic.service.UUID],[self UUIDToString:peripheral.UUID]); 532 | } 533 | else 534 | { 535 | printf("Error in setting notification state for characteristic with UUID %s on service with UUID %s on peripheral with UUID %s\r\n",[self CBUUIDToString:characteristic.UUID],[self CBUUIDToString:characteristic.service.UUID],[self UUIDToString:peripheral.UUID]); 536 | printf("Error code was %s\r\n",[[error description] cStringUsingEncoding:NSStringEncodingConversionAllowLossy]); 537 | } 538 | } 539 | 540 | - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error 541 | { 542 | unsigned char data[BLE_DEVICE_RX_READ_LEN]; 543 | 544 | static unsigned char buf[512]; 545 | static int len = 0; 546 | int data_len; 547 | 548 | if (!error) 549 | { 550 | if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_RX_UUID]]) 551 | { 552 | data_len = characteristic.value.length; 553 | [characteristic.value getBytes:data length:data_len]; 554 | 555 | if (data_len == 20) 556 | { 557 | memcpy(&buf[len], data, 20); 558 | len += data_len; 559 | 560 | if (len >= 64) 561 | { 562 | [[self delegate] bleDidReceiveData:buf length:len]; 563 | len = 0; 564 | } 565 | } 566 | else if (data_len < 20) 567 | { 568 | memcpy(&buf[len], data, data_len); 569 | len += data_len; 570 | 571 | [[self delegate] bleDidReceiveData:buf length:len]; 572 | len = 0; 573 | } 574 | 575 | [self enableWrite]; 576 | } 577 | else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_VENDOR_NAME_UUID]]) 578 | { 579 | data_len = characteristic.value.length; 580 | [characteristic.value getBytes:vendor_name length:data_len]; 581 | // NSLog(@"Vendor: %s", vendor_name); 582 | } 583 | else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@BLE_DEVICE_LIB_VERSION_UUID]]) 584 | { 585 | [characteristic.value getBytes:&libver length:2]; 586 | // NSLog(@"Lib. ver.: %X", libver); 587 | } 588 | } 589 | else 590 | { 591 | printf("updateValueForCharacteristic failed!"); 592 | } 593 | } 594 | 595 | - (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error 596 | { 597 | if (!isConnected) 598 | return; 599 | 600 | if (rssi != peripheral.RSSI.intValue) 601 | { 602 | rssi = peripheral.RSSI.intValue; 603 | [[self delegate] bleDidUpdateRSSI:activePeripheral.RSSI]; 604 | } 605 | [activePeripheral readRSSI]; 606 | } 607 | 608 | @end 609 | -------------------------------------------------------------------------------- /examples/redbearlab/blemini/led_serial/library/BLEDefines.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Copyright (c) 2012 RedBearLab 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | 12 | */ 13 | 14 | // BLE Device Service 15 | #define BLE_DEVICE_SERVICE_UUID "713D0000-503E-4C75-BA94-3148F18D941E" 16 | 17 | #define BLE_DEVICE_VENDOR_NAME_UUID "713D0001-503E-4C75-BA94-3148F18D941E" 18 | 19 | #define BLE_DEVICE_RX_UUID "713D0002-503E-4C75-BA94-3148F18D941E" 20 | #define BLE_DEVICE_RX_READ_LEN 20 21 | 22 | #define BLE_DEVICE_TX_UUID "713D0003-503E-4C75-BA94-3148F18D941E" 23 | #define BLE_DEVICE_TX_WRITE_LEN 20 24 | 25 | #define BLE_DEVICE_RESET_RX_UUID "713D0004-503E-4C75-BA94-3148F18D941E" 26 | 27 | #define BLE_DEVICE_LIB_VERSION_UUID "713D0005-503E-4C75-BA94-3148F18D941E" 28 | 29 | #define BLE_FRAMEWORK_VERSION 0x0102 30 | --------------------------------------------------------------------------------