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