1414
1515/*
1616 * This sketch demonstrate how to run both Central and Peripheral roles
17- * at the same tiem
17+ * at the same time. It will act as a relay between an central (mobile)
18+ * to another peripheral using bleuart service.
1819 */
1920#include < bluefruit.h>
2021
@@ -35,149 +36,178 @@ void setup()
3536 Bluefruit.begin (true , true );
3637 // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
3738 Bluefruit.setTxPower (4 );
38- Bluefruit.setName (" Bluefruit52" );
39+ Bluefruit.setName (" Bluefruit52 duo" );
40+
41+ // Callbacks for Peripheral
42+ Bluefruit.setConnectCallback (prph_connect_callback);
43+ Bluefruit.setDisconnectCallback (prph_disconnect_callback);
3944
4045 // Callbacks for Central
4146 Bluefruit.Central .setConnectCallback (cent_connect_callback);
4247 Bluefruit.Central .setDisconnectCallback (cent_disconnect_callback);
4348
44-
49+ // Configure and Start BLE Uart Service
50+ bleuart.begin ();
51+ bleuart.setRxCallback (prph_bleuart_rx_callback);
4552
4653 // Init BLE Central Uart Serivce
4754 clientUart.begin ();
48- clientUart.setRxCallback (bleuart_rx_callback );
55+ clientUart.setRxCallback (cent_bleuart_rx_callback );
4956
5057
5158 /* Start Central Scanning
5259 * - Enable auto scan if disconnected
5360 * - Interval = 100 ms, window = 80 ms
61+ * - Filter only accept bleuart service
5462 * - Don't use active scan
5563 * - Start(timeout) with timeout = 0 will scan forever (until connected)
5664 */
5765 Bluefruit.Scanner .setRxCallback (scan_callback);
5866 Bluefruit.Scanner .restartOnDisconnect (true );
5967 Bluefruit.Scanner .setInterval (160 , 80 ); // in unit of 0.625 ms
68+ Bluefruit.Scanner .filterUuid (bleuart.uuid );
6069 Bluefruit.Scanner .useActiveScan (false );
61- Bluefruit.Scanner .start (0 ); // // 0 = Don't stop scanning after n seconds
70+ Bluefruit.Scanner .start (0 ); // 0 = Don't stop scanning after n seconds
71+
72+ // Set up and start advertising
73+ startAdv ();
6274}
6375
64- /* *
65- * Callback invoked when scanner pick up an advertising data
66- * @param report Structural advertising data
67- */
76+ void startAdv (void )
77+ {
78+ // Advertising packet
79+ Bluefruit.Advertising .addFlags (BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
80+ Bluefruit.Advertising .addTxPower ();
81+
82+ // Include bleuart 128-bit uuid
83+ Bluefruit.Advertising .addService (bleuart);
84+
85+ // Secondary Scan Response packet (optional)
86+ // Since there is no room for 'Name' in Advertising packet
87+ Bluefruit.ScanResponse .addName ();
88+
89+ /* Start Advertising
90+ * - Enable auto advertising if disconnected
91+ * - Interval: fast mode = 20 ms, slow mode = 152.5 ms
92+ * - Timeout for fast mode is 30 seconds
93+ * - Start(timeout) with timeout = 0 will advertise forever (until connected)
94+ *
95+ * For recommended advertising interval
96+ * https://developer.apple.com/library/content/qa/qa1931/_index.html
97+ */
98+ Bluefruit.Advertising .restartOnDisconnect (true );
99+ Bluefruit.Advertising .setInterval (32 , 244 ); // in unit of 0.625 ms
100+ Bluefruit.Advertising .setFastTimeout (30 ); // number of seconds in fast mode
101+ Bluefruit.Advertising .start (0 ); // 0 = Don't stop advertising after n seconds
102+ }
103+
104+ void loop ()
105+ {
106+ // do nothing, all the work is done in callback
107+ }
108+
109+ /* ------------------------------------------------------------------*/
110+ /* Peripheral
111+ *------------------------------------------------------------------*/
112+ void prph_connect_callback (uint16_t conn_handle)
113+ {
114+ char peer_name[32 ] = { 0 };
115+ Bluefruit.Gap .getPeerName (conn_handle, peer_name, sizeof (peer_name));
116+
117+ Serial.print (" [Prph] Connected to " );
118+ Serial.println (peer_name);
119+ }
120+
121+ void prph_disconnect_callback (uint16_t conn_handle, uint8_t reason)
122+ {
123+ (void ) conn_handle;
124+ (void ) reason;
125+
126+ Serial.println ();
127+ Serial.println (" [Prph] Disconnected" );
128+ }
129+
130+ void prph_bleuart_rx_callback (void )
131+ {
132+ // Forward data from Mobile to our peripheral
133+ char str[20 +1 ] = { 0 };
134+ bleuart.read (str, 20 );
135+
136+ Serial.print (" [Prph] RX: " );
137+ Serial.println (str);
138+
139+ if ( clientUart.discovered () )
140+ {
141+ clientUart.print (str);
142+ }else
143+ {
144+ bleuart.println (" [Prph] Central role not connected" );
145+ }
146+ }
147+
148+ /* ------------------------------------------------------------------*/
149+ /* Central
150+ *------------------------------------------------------------------*/
68151void scan_callback (ble_gap_evt_adv_report_t * report)
69152{
70153 // Check if advertising contain BleUart service
71154 if ( Bluefruit.Scanner .checkReportForService (report, clientUart) )
72155 {
73- Serial.print (" BLE UART service detected. Connecting ... " );
156+ Serial.println (" BLE UART service detected. Connecting ... " );
74157
75158 // Connect to device with bleuart service in advertising
76159 Bluefruit.Central .connect (report);
77160 }
78161}
79162
80- /* *
81- * Callback invoked when an connection is established
82- * @param conn_handle
83- */
84163void cent_connect_callback (uint16_t conn_handle)
85164{
86- Serial.println (" Connected" );
87-
88- Serial.print (" Dicovering DIS ... " );
89- if ( clientDis.discover (conn_handle) )
90- {
91- Serial.println (" Found it" );
92- char buffer[32 +1 ];
93-
94- // read and print out Manufacturer
95- memset (buffer, 0 , sizeof (buffer));
96- if ( clientDis.getManufacturer (buffer, sizeof (buffer)) )
97- {
98- Serial.print (" Manufacturer: " );
99- Serial.println (buffer);
100- }
101-
102- // read and print out Model Number
103- memset (buffer, 0 , sizeof (buffer));
104- if ( clientDis.getModel (buffer, sizeof (buffer)) )
105- {
106- Serial.print (" Model: " );
107- Serial.println (buffer);
108- }
109-
110- Serial.println ();
111- }
165+ char peer_name[32 ] = { 0 };
166+ Bluefruit.Gap .getPeerName (conn_handle, peer_name, sizeof (peer_name));
112167
113- Serial.print (" Discovering BLE Uart Service ... " );
168+ Serial.print (" [Cent] Connected to " );
169+ Serial.println (peer_name);;
114170
115171 if ( clientUart.discover (conn_handle) )
116172 {
117- Serial.println (" Found it" );
118-
119- Serial.println (" Enable TXD's notify" );
173+ // Enable TXD's notify
120174 clientUart.enableTXD ();
121-
122- Serial.println (" Ready to receive from peripheral" );
123175 }else
124176 {
125- Serial.println (" Found NONE" );
126-
127177 // disconect since we couldn't find bleuart service
128178 Bluefruit.Central .disconnect (conn_handle);
129179 }
130180}
131181
132- /* *
133- * Callback invoked when a connection is dropped
134- * @param conn_handle
135- * @param reason
136- */
137182void cent_disconnect_callback (uint16_t conn_handle, uint8_t reason)
138183{
139184 (void ) conn_handle;
140185 (void ) reason;
141186
142- Serial.println (" Disconnected" );
187+ Serial.println (" [Cent] Disconnected" );
143188}
144189
145190/* *
146191 * Callback invoked when uart received data
147- * @param uart_svc Reference object to the service where the data
192+ * @param cent_uart Reference object to the service where the data
148193 * arrived. In this example it is clientUart
149194 */
150- void bleuart_rx_callback (BLEClientUart& uart_svc )
195+ void cent_bleuart_rx_callback (BLEClientUart& cent_uart )
151196{
152- Serial.print (" [RX]: " );
153-
154- while ( uart_svc.available () )
155- {
156- Serial.print ( (char ) uart_svc.read () );
157- }
158-
159- Serial.println ();
160- }
197+ char str[20 +1 ] = { 0 };
198+ cent_uart.read (str, 20 );
199+
200+ Serial.print (" [Cent] RX: " );
201+ Serial.println (str);
161202
162- void loop ()
163- {
164- if ( Bluefruit.Central .connected () )
203+ if ( bleuart.notifyEnabled () )
165204 {
166- // Not discovered yet
167- if ( clientUart.discovered () )
168- {
169- // Discovered means in working state
170- // Get Serial input and send to Peripheral
171- if ( Serial.available () )
172- {
173- delay (2 ); // delay a bit for all characters to arrive
174-
175- char str[20 +1 ] = { 0 };
176- Serial.readBytes (str, 20 );
177-
178- clientUart.print ( str );
179- }
180- }
181- }
205+ // Forward data from our peripheral to Mobile
206+ bleuart.print ( str );
207+ }else
208+ {
209+ // response with no prph message
210+ clientUart.println (" [Cent] Peripheral role not connected" );
211+ }
182212}
183213
0 commit comments