xref: /btstack/port/archive/msp-exp430f5438-cc2564b/example/ble_server.c (revision 1664436fd643daf66517dc309e6cc72448e8a86d)
1*1664436fSMatthias Ringwald /*
2*1664436fSMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*1664436fSMatthias Ringwald  *
4*1664436fSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*1664436fSMatthias Ringwald  * modification, are permitted provided that the following conditions
6*1664436fSMatthias Ringwald  * are met:
7*1664436fSMatthias Ringwald  *
8*1664436fSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*1664436fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*1664436fSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*1664436fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*1664436fSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*1664436fSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*1664436fSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*1664436fSMatthias Ringwald  *    from this software without specific prior written permission.
16*1664436fSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*1664436fSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*1664436fSMatthias Ringwald  *    monetary gain.
19*1664436fSMatthias Ringwald  *
20*1664436fSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*1664436fSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*1664436fSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*1664436fSMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*1664436fSMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*1664436fSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*1664436fSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*1664436fSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*1664436fSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*1664436fSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*1664436fSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*1664436fSMatthias Ringwald  * SUCH DAMAGE.
32*1664436fSMatthias Ringwald  *
33*1664436fSMatthias Ringwald  * Please inquire about commercial licensing options at
34*1664436fSMatthias Ringwald  * [email protected]
35*1664436fSMatthias Ringwald  *
36*1664436fSMatthias Ringwald  */
37*1664436fSMatthias Ringwald 
38*1664436fSMatthias Ringwald 
39*1664436fSMatthias Ringwald // *****************************************************************************
40*1664436fSMatthias Ringwald //
41*1664436fSMatthias Ringwald // att device demo
42*1664436fSMatthias Ringwald //
43*1664436fSMatthias Ringwald // *****************************************************************************
44*1664436fSMatthias Ringwald 
45*1664436fSMatthias Ringwald // TODO: seperate BR/EDR from LE ACL buffers
46*1664436fSMatthias Ringwald // TODO: move LE init into HCI
47*1664436fSMatthias Ringwald // ..
48*1664436fSMatthias Ringwald 
49*1664436fSMatthias Ringwald // NOTE: Supports only a single connection
50*1664436fSMatthias Ringwald 
51*1664436fSMatthias Ringwald #include <stdint.h>
52*1664436fSMatthias Ringwald #include <stdio.h>
53*1664436fSMatthias Ringwald #include <stdlib.h>
54*1664436fSMatthias Ringwald #include <string.h>
55*1664436fSMatthias Ringwald 
56*1664436fSMatthias Ringwald #include "btstack_config.h"
57*1664436fSMatthias Ringwald 
58*1664436fSMatthias Ringwald #include <msp430x54x.h>
59*1664436fSMatthias Ringwald 
60*1664436fSMatthias Ringwald #include "btstack_chipset_cc256x.h"
61*1664436fSMatthias Ringwald #include "hal_board.h"
62*1664436fSMatthias Ringwald #include "hal_compat.h"
63*1664436fSMatthias Ringwald #include "hal_usb.h"
64*1664436fSMatthias Ringwald #include "hal_lcd.h"
65*1664436fSMatthias Ringwald #include "hal_usb.h"
66*1664436fSMatthias Ringwald #include "UserExperienceGraphics.h"
67*1664436fSMatthias Ringwald 
68*1664436fSMatthias Ringwald #include "btstack.h"
69*1664436fSMatthias Ringwald 
70*1664436fSMatthias Ringwald #define FONT_HEIGHT		12                    // Each character has 13 lines
71*1664436fSMatthias Ringwald #define FONT_WIDTH       8
72*1664436fSMatthias Ringwald #define MAX_CHR01_VALUE_LENGTH 40
73*1664436fSMatthias Ringwald 
74*1664436fSMatthias Ringwald static uint16_t chr01_value_length = 0;
75*1664436fSMatthias Ringwald static char chr01_value[MAX_CHR01_VALUE_LENGTH];
76*1664436fSMatthias Ringwald static char chr02_value = 0;
77*1664436fSMatthias Ringwald 
78*1664436fSMatthias Ringwald void doLCD(void){
79*1664436fSMatthias Ringwald     //Initialize LCD and backlight
80*1664436fSMatthias Ringwald     // 138 x 110, 4-level grayscale pixels.
81*1664436fSMatthias Ringwald     halLcdInit();
82*1664436fSMatthias Ringwald     // halLcdBackLightInit();
83*1664436fSMatthias Ringwald     // halLcdSetBackLight(0);  // 8 for normal
84*1664436fSMatthias Ringwald     halLcdSetContrast(100);
85*1664436fSMatthias Ringwald     halLcdClearScreen();
86*1664436fSMatthias Ringwald     halLcdImage(TI_TINY_BUG, 4, 32, 104, 12 );
87*1664436fSMatthias Ringwald 
88*1664436fSMatthias Ringwald     halLcdPrintLine("BTstack on ", 0, 0);
89*1664436fSMatthias Ringwald     halLcdPrintLine("TI MSP430", 1, 0);
90*1664436fSMatthias Ringwald     halLcdPrintLine("LE Write Test", 2, 0);
91*1664436fSMatthias Ringwald     halLcdPrintLine("NOT CONNECTED", 4, 0);
92*1664436fSMatthias Ringwald     halLcdPrintLine("Attribute 0x0022:", 6, 0);
93*1664436fSMatthias Ringwald     halLcdPrintLine("- NO VALUE -", 7, 0);
94*1664436fSMatthias Ringwald }
95*1664436fSMatthias Ringwald 
96*1664436fSMatthias Ringwald void overwriteLine(int line, char *text){
97*1664436fSMatthias Ringwald     halLcdClearImage(130, FONT_HEIGHT, 0, line*FONT_HEIGHT);
98*1664436fSMatthias Ringwald     halLcdPrintLine(text, line, 0);
99*1664436fSMatthias Ringwald }
100*1664436fSMatthias Ringwald 
101*1664436fSMatthias Ringwald // enable LE, setup ADV data
102*1664436fSMatthias Ringwald static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
103*1664436fSMatthias Ringwald     if (packet_type != HCI_EVENT_PACKET) return;
104*1664436fSMatthias Ringwald     bd_addr_t addr;
105*1664436fSMatthias Ringwald     uint8_t adv_data[] = { 02, 01, 05,   03, 02, 0xf0, 0xff };
106*1664436fSMatthias Ringwald 
107*1664436fSMatthias Ringwald     switch (hci_event_packet_get_type(packet)) {
108*1664436fSMatthias Ringwald         case BTSTACK_EVENT_STATE:
109*1664436fSMatthias Ringwald             // bt stack activated, get started - set local name
110*1664436fSMatthias Ringwald             if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){
111*1664436fSMatthias Ringwald                 printf("Working!\n");
112*1664436fSMatthias Ringwald                 hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
113*1664436fSMatthias Ringwald             }
114*1664436fSMatthias Ringwald             break;
115*1664436fSMatthias Ringwald 
116*1664436fSMatthias Ringwald         case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
117*1664436fSMatthias Ringwald             if (packet[2]) {
118*1664436fSMatthias Ringwald                 overwriteLine(4, "CONNECTED");
119*1664436fSMatthias Ringwald             } else {
120*1664436fSMatthias Ringwald                 overwriteLine(4, "NOT CONNECTED");
121*1664436fSMatthias Ringwald             }
122*1664436fSMatthias Ringwald             break;
123*1664436fSMatthias Ringwald 
124*1664436fSMatthias Ringwald         case HCI_EVENT_DISCONNECTION_COMPLETE:
125*1664436fSMatthias Ringwald             // restart advertising
126*1664436fSMatthias Ringwald             hci_send_cmd(&hci_le_set_advertise_enable, 1);
127*1664436fSMatthias Ringwald             break;
128*1664436fSMatthias Ringwald 
129*1664436fSMatthias Ringwald         case HCI_EVENT_COMMAND_COMPLETE:
130*1664436fSMatthias Ringwald             if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){
131*1664436fSMatthias Ringwald                 reverse_bd_addr(&packet[6], addr);
132*1664436fSMatthias Ringwald                 printf("BD ADDR: %s\n", bd_addr_to_str(addr));
133*1664436fSMatthias Ringwald                 break;
134*1664436fSMatthias Ringwald             }
135*1664436fSMatthias Ringwald             if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_set_advertising_data)){
136*1664436fSMatthias Ringwald                hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
137*1664436fSMatthias Ringwald                break;
138*1664436fSMatthias Ringwald             }
139*1664436fSMatthias Ringwald             if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_set_scan_response_data)){
140*1664436fSMatthias Ringwald                hci_send_cmd(&hci_le_set_advertise_enable, 1);
141*1664436fSMatthias Ringwald                break;
142*1664436fSMatthias Ringwald             }
143*1664436fSMatthias Ringwald         default:
144*1664436fSMatthias Ringwald             break;
145*1664436fSMatthias Ringwald     }
146*1664436fSMatthias Ringwald 
147*1664436fSMatthias Ringwald }
148*1664436fSMatthias Ringwald 
149*1664436fSMatthias Ringwald // test profile
150*1664436fSMatthias Ringwald #include "profile.h"
151*1664436fSMatthias Ringwald 
152*1664436fSMatthias Ringwald static uint16_t get_read_att_value_len(uint16_t att_handle){
153*1664436fSMatthias Ringwald     uint16_t value_len;
154*1664436fSMatthias Ringwald     switch(att_handle){
155*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE:
156*1664436fSMatthias Ringwald             value_len = chr01_value_length;
157*1664436fSMatthias Ringwald             break;
158*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE:
159*1664436fSMatthias Ringwald             value_len = 1;
160*1664436fSMatthias Ringwald             break;
161*1664436fSMatthias Ringwald         default:
162*1664436fSMatthias Ringwald             value_len = 0;
163*1664436fSMatthias Ringwald             break;
164*1664436fSMatthias Ringwald     }
165*1664436fSMatthias Ringwald     return value_len;
166*1664436fSMatthias Ringwald }
167*1664436fSMatthias Ringwald 
168*1664436fSMatthias Ringwald static uint16_t get_write_att_value_len(uint16_t att_handle){
169*1664436fSMatthias Ringwald     uint16_t value_len;
170*1664436fSMatthias Ringwald     switch(att_handle){
171*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE:
172*1664436fSMatthias Ringwald             value_len = MAX_CHR01_VALUE_LENGTH;
173*1664436fSMatthias Ringwald             break;
174*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE:
175*1664436fSMatthias Ringwald             value_len = 1;
176*1664436fSMatthias Ringwald             break;
177*1664436fSMatthias Ringwald         default:
178*1664436fSMatthias Ringwald             value_len = 0;
179*1664436fSMatthias Ringwald             break;
180*1664436fSMatthias Ringwald     }
181*1664436fSMatthias Ringwald     return value_len;
182*1664436fSMatthias Ringwald }
183*1664436fSMatthias Ringwald 
184*1664436fSMatthias Ringwald static uint16_t get_bytes_to_copy(uint16_t value_len, uint16_t offset, uint16_t buffer_size){
185*1664436fSMatthias Ringwald     if (value_len <= offset ) return 0;
186*1664436fSMatthias Ringwald 
187*1664436fSMatthias Ringwald     uint16_t bytes_to_copy = value_len - offset;
188*1664436fSMatthias Ringwald     if (bytes_to_copy > buffer_size) {
189*1664436fSMatthias Ringwald         bytes_to_copy = buffer_size;
190*1664436fSMatthias Ringwald     }
191*1664436fSMatthias Ringwald     return bytes_to_copy;
192*1664436fSMatthias Ringwald }
193*1664436fSMatthias Ringwald 
194*1664436fSMatthias Ringwald uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
195*1664436fSMatthias Ringwald     printf("READ Callback, handle %04x\n", att_handle);
196*1664436fSMatthias Ringwald     uint16_t value_len = get_read_att_value_len(att_handle);
197*1664436fSMatthias Ringwald     if (!buffer) return value_len;
198*1664436fSMatthias Ringwald 
199*1664436fSMatthias Ringwald     uint16_t bytes_to_copy = get_bytes_to_copy(value_len, offset, buffer_size);
200*1664436fSMatthias Ringwald     if (!bytes_to_copy) return 0;
201*1664436fSMatthias Ringwald 
202*1664436fSMatthias Ringwald     switch(att_handle){
203*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE:
204*1664436fSMatthias Ringwald             memcpy(buffer, &chr01_value[offset], bytes_to_copy);
205*1664436fSMatthias Ringwald             break;
206*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE:
207*1664436fSMatthias Ringwald             buffer[offset] = chr02_value;
208*1664436fSMatthias Ringwald             break;
209*1664436fSMatthias Ringwald     }
210*1664436fSMatthias Ringwald     return bytes_to_copy;
211*1664436fSMatthias Ringwald }
212*1664436fSMatthias Ringwald 
213*1664436fSMatthias Ringwald // write requests
214*1664436fSMatthias Ringwald static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size){
215*1664436fSMatthias Ringwald     printf("WRITE Callback, handle %04x\n", att_handle);
216*1664436fSMatthias Ringwald 
217*1664436fSMatthias Ringwald     uint16_t value_len = get_write_att_value_len(att_handle);
218*1664436fSMatthias Ringwald     uint16_t bytes_to_copy = get_bytes_to_copy(value_len, offset,buffer_size);
219*1664436fSMatthias Ringwald     if (!bytes_to_copy) return ATT_ERROR_INVALID_OFFSET;
220*1664436fSMatthias Ringwald 
221*1664436fSMatthias Ringwald     switch(att_handle){
222*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE:
223*1664436fSMatthias Ringwald             buffer[buffer_size] = 0;
224*1664436fSMatthias Ringwald             memcpy(&chr01_value[offset], buffer, bytes_to_copy);
225*1664436fSMatthias Ringwald             chr01_value_length = bytes_to_copy + offset;
226*1664436fSMatthias Ringwald 
227*1664436fSMatthias Ringwald             printf("New text: %s\n", buffer);
228*1664436fSMatthias Ringwald             overwriteLine(7, (char*)buffer);
229*1664436fSMatthias Ringwald             break;
230*1664436fSMatthias Ringwald         case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE:
231*1664436fSMatthias Ringwald             printf("New value: %u\n", buffer[offset]);
232*1664436fSMatthias Ringwald             if (buffer[offset]) {
233*1664436fSMatthias Ringwald                 LED_PORT_OUT |= LED_2;
234*1664436fSMatthias Ringwald             } else {
235*1664436fSMatthias Ringwald                 LED_PORT_OUT &= ~LED_2;
236*1664436fSMatthias Ringwald             }
237*1664436fSMatthias Ringwald             chr02_value = buffer[offset];
238*1664436fSMatthias Ringwald             break;
239*1664436fSMatthias Ringwald     }
240*1664436fSMatthias Ringwald     return 0;
241*1664436fSMatthias Ringwald }
242*1664436fSMatthias Ringwald 
243*1664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]);
244*1664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]){
245*1664436fSMatthias Ringwald 
246*1664436fSMatthias Ringwald     // show off
247*1664436fSMatthias Ringwald     doLCD();
248*1664436fSMatthias Ringwald 
249*1664436fSMatthias Ringwald     // set up l2cap_le
250*1664436fSMatthias Ringwald     l2cap_init();
251*1664436fSMatthias Ringwald 
252*1664436fSMatthias Ringwald     // setup le device db
253*1664436fSMatthias Ringwald     le_device_db_init();
254*1664436fSMatthias Ringwald 
255*1664436fSMatthias Ringwald     // setup SM: Display only
256*1664436fSMatthias Ringwald     sm_init();
257*1664436fSMatthias Ringwald     sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY);
258*1664436fSMatthias Ringwald     sm_set_authentication_requirements( SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION);
259*1664436fSMatthias Ringwald 
260*1664436fSMatthias Ringwald     // setup ATT server
261*1664436fSMatthias Ringwald     att_server_init(profile_data, NULL, att_write_callback);
262*1664436fSMatthias Ringwald     att_server_register_packet_handler(app_packet_handler);
263*1664436fSMatthias Ringwald 
264*1664436fSMatthias Ringwald 	printf("Run...\n\r");
265*1664436fSMatthias Ringwald 
266*1664436fSMatthias Ringwald     // turn on!
267*1664436fSMatthias Ringwald 	hci_power_control(HCI_POWER_ON);
268*1664436fSMatthias Ringwald 
269*1664436fSMatthias Ringwald     LED_PORT_OUT &= ~LED_2;
270*1664436fSMatthias Ringwald 
271*1664436fSMatthias Ringwald     return 0;
272*1664436fSMatthias Ringwald }
273*1664436fSMatthias Ringwald 
274