11664436fSMatthias Ringwald /* 21664436fSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 31664436fSMatthias Ringwald * 41664436fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 51664436fSMatthias Ringwald * modification, are permitted provided that the following conditions 61664436fSMatthias Ringwald * are met: 71664436fSMatthias Ringwald * 81664436fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 91664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 101664436fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 111664436fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 121664436fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 131664436fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 141664436fSMatthias Ringwald * contributors may be used to endorse or promote products derived 151664436fSMatthias Ringwald * from this software without specific prior written permission. 161664436fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 171664436fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 181664436fSMatthias Ringwald * monetary gain. 191664436fSMatthias Ringwald * 201664436fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 211664436fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 221664436fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 251664436fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 261664436fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 271664436fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 281664436fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 291664436fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 301664436fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311664436fSMatthias Ringwald * SUCH DAMAGE. 321664436fSMatthias Ringwald * 331664436fSMatthias Ringwald * Please inquire about commercial licensing options at 341664436fSMatthias Ringwald * [email protected] 351664436fSMatthias Ringwald * 361664436fSMatthias Ringwald */ 371664436fSMatthias Ringwald 381664436fSMatthias Ringwald 391664436fSMatthias Ringwald // ***************************************************************************** 401664436fSMatthias Ringwald // 411664436fSMatthias Ringwald // att device demo 421664436fSMatthias Ringwald // 431664436fSMatthias Ringwald // ***************************************************************************** 441664436fSMatthias Ringwald 451664436fSMatthias Ringwald // TODO: seperate BR/EDR from LE ACL buffers 461664436fSMatthias Ringwald // TODO: move LE init into HCI 471664436fSMatthias Ringwald // .. 481664436fSMatthias Ringwald 491664436fSMatthias Ringwald // NOTE: Supports only a single connection 501664436fSMatthias Ringwald 511664436fSMatthias Ringwald #include <stdint.h> 521664436fSMatthias Ringwald #include <stdio.h> 531664436fSMatthias Ringwald #include <stdlib.h> 541664436fSMatthias Ringwald #include <string.h> 551664436fSMatthias Ringwald 561664436fSMatthias Ringwald #include "btstack_config.h" 571664436fSMatthias Ringwald 581664436fSMatthias Ringwald #include <msp430x54x.h> 591664436fSMatthias Ringwald 601664436fSMatthias Ringwald #include "btstack_chipset_cc256x.h" 611664436fSMatthias Ringwald #include "hal_board.h" 621664436fSMatthias Ringwald #include "hal_compat.h" 631664436fSMatthias Ringwald #include "hal_usb.h" 641664436fSMatthias Ringwald #include "hal_lcd.h" 651664436fSMatthias Ringwald #include "hal_usb.h" 661664436fSMatthias Ringwald #include "UserExperienceGraphics.h" 671664436fSMatthias Ringwald 681664436fSMatthias Ringwald #include "btstack.h" 691664436fSMatthias Ringwald 701664436fSMatthias Ringwald #define FONT_HEIGHT 12 // Each character has 13 lines 711664436fSMatthias Ringwald #define FONT_WIDTH 8 721664436fSMatthias Ringwald #define MAX_CHR01_VALUE_LENGTH 40 731664436fSMatthias Ringwald 741664436fSMatthias Ringwald static uint16_t chr01_value_length = 0; 751664436fSMatthias Ringwald static char chr01_value[MAX_CHR01_VALUE_LENGTH]; 761664436fSMatthias Ringwald static char chr02_value = 0; 771664436fSMatthias Ringwald 781664436fSMatthias Ringwald void doLCD(void){ 791664436fSMatthias Ringwald //Initialize LCD and backlight 801664436fSMatthias Ringwald // 138 x 110, 4-level grayscale pixels. 811664436fSMatthias Ringwald halLcdInit(); 821664436fSMatthias Ringwald // halLcdBackLightInit(); 831664436fSMatthias Ringwald // halLcdSetBackLight(0); // 8 for normal 841664436fSMatthias Ringwald halLcdSetContrast(100); 851664436fSMatthias Ringwald halLcdClearScreen(); 861664436fSMatthias Ringwald halLcdImage(TI_TINY_BUG, 4, 32, 104, 12 ); 871664436fSMatthias Ringwald 881664436fSMatthias Ringwald halLcdPrintLine("BTstack on ", 0, 0); 891664436fSMatthias Ringwald halLcdPrintLine("TI MSP430", 1, 0); 901664436fSMatthias Ringwald halLcdPrintLine("LE Write Test", 2, 0); 911664436fSMatthias Ringwald halLcdPrintLine("NOT CONNECTED", 4, 0); 921664436fSMatthias Ringwald halLcdPrintLine("Attribute 0x0022:", 6, 0); 931664436fSMatthias Ringwald halLcdPrintLine("- NO VALUE -", 7, 0); 941664436fSMatthias Ringwald } 951664436fSMatthias Ringwald 961664436fSMatthias Ringwald void overwriteLine(int line, char *text){ 971664436fSMatthias Ringwald halLcdClearImage(130, FONT_HEIGHT, 0, line*FONT_HEIGHT); 981664436fSMatthias Ringwald halLcdPrintLine(text, line, 0); 991664436fSMatthias Ringwald } 1001664436fSMatthias Ringwald 1011664436fSMatthias Ringwald // enable LE, setup ADV data 1021664436fSMatthias Ringwald static void app_packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 1031664436fSMatthias Ringwald if (packet_type != HCI_EVENT_PACKET) return; 1041664436fSMatthias Ringwald bd_addr_t addr; 1051664436fSMatthias Ringwald uint8_t adv_data[] = { 02, 01, 05, 03, 02, 0xf0, 0xff }; 1061664436fSMatthias Ringwald 1071664436fSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 1081664436fSMatthias Ringwald case BTSTACK_EVENT_STATE: 1091664436fSMatthias Ringwald // bt stack activated, get started - set local name 1101664436fSMatthias Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 1111664436fSMatthias Ringwald printf("Working!\n"); 1121664436fSMatthias Ringwald hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data); 1131664436fSMatthias Ringwald } 1141664436fSMatthias Ringwald break; 1151664436fSMatthias Ringwald 1161664436fSMatthias Ringwald case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED: 1171664436fSMatthias Ringwald if (packet[2]) { 1181664436fSMatthias Ringwald overwriteLine(4, "CONNECTED"); 1191664436fSMatthias Ringwald } else { 1201664436fSMatthias Ringwald overwriteLine(4, "NOT CONNECTED"); 1211664436fSMatthias Ringwald } 1221664436fSMatthias Ringwald break; 1231664436fSMatthias Ringwald 1241664436fSMatthias Ringwald case HCI_EVENT_DISCONNECTION_COMPLETE: 1251664436fSMatthias Ringwald // restart advertising 1261664436fSMatthias Ringwald hci_send_cmd(&hci_le_set_advertise_enable, 1); 1271664436fSMatthias Ringwald break; 1281664436fSMatthias Ringwald 1291664436fSMatthias Ringwald case HCI_EVENT_COMMAND_COMPLETE: 1301664436fSMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)){ 1311664436fSMatthias Ringwald reverse_bd_addr(&packet[6], addr); 1321664436fSMatthias Ringwald printf("BD ADDR: %s\n", bd_addr_to_str(addr)); 1331664436fSMatthias Ringwald break; 1341664436fSMatthias Ringwald } 1351664436fSMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_set_advertising_data)){ 1361664436fSMatthias Ringwald hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data); 1371664436fSMatthias Ringwald break; 1381664436fSMatthias Ringwald } 1391664436fSMatthias Ringwald if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_le_set_scan_response_data)){ 1401664436fSMatthias Ringwald hci_send_cmd(&hci_le_set_advertise_enable, 1); 1411664436fSMatthias Ringwald break; 1421664436fSMatthias Ringwald } 1431664436fSMatthias Ringwald default: 1441664436fSMatthias Ringwald break; 1451664436fSMatthias Ringwald } 1461664436fSMatthias Ringwald 1471664436fSMatthias Ringwald } 1481664436fSMatthias Ringwald 1491664436fSMatthias Ringwald // test profile 1501664436fSMatthias Ringwald #include "profile.h" 1511664436fSMatthias Ringwald 1521664436fSMatthias Ringwald static uint16_t get_read_att_value_len(uint16_t att_handle){ 1531664436fSMatthias Ringwald uint16_t value_len; 1541664436fSMatthias Ringwald switch(att_handle){ 1551664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE: 1561664436fSMatthias Ringwald value_len = chr01_value_length; 1571664436fSMatthias Ringwald break; 1581664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE: 1591664436fSMatthias Ringwald value_len = 1; 1601664436fSMatthias Ringwald break; 1611664436fSMatthias Ringwald default: 1621664436fSMatthias Ringwald value_len = 0; 1631664436fSMatthias Ringwald break; 1641664436fSMatthias Ringwald } 1651664436fSMatthias Ringwald return value_len; 1661664436fSMatthias Ringwald } 1671664436fSMatthias Ringwald 1681664436fSMatthias Ringwald static uint16_t get_write_att_value_len(uint16_t att_handle){ 1691664436fSMatthias Ringwald uint16_t value_len; 1701664436fSMatthias Ringwald switch(att_handle){ 1711664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE: 1721664436fSMatthias Ringwald value_len = MAX_CHR01_VALUE_LENGTH; 1731664436fSMatthias Ringwald break; 1741664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE: 1751664436fSMatthias Ringwald value_len = 1; 1761664436fSMatthias Ringwald break; 1771664436fSMatthias Ringwald default: 1781664436fSMatthias Ringwald value_len = 0; 1791664436fSMatthias Ringwald break; 1801664436fSMatthias Ringwald } 1811664436fSMatthias Ringwald return value_len; 1821664436fSMatthias Ringwald } 1831664436fSMatthias Ringwald 1841664436fSMatthias Ringwald static uint16_t get_bytes_to_copy(uint16_t value_len, uint16_t offset, uint16_t buffer_size){ 1851664436fSMatthias Ringwald if (value_len <= offset ) return 0; 1861664436fSMatthias Ringwald 1871664436fSMatthias Ringwald uint16_t bytes_to_copy = value_len - offset; 1881664436fSMatthias Ringwald if (bytes_to_copy > buffer_size) { 1891664436fSMatthias Ringwald bytes_to_copy = buffer_size; 1901664436fSMatthias Ringwald } 1911664436fSMatthias Ringwald return bytes_to_copy; 1921664436fSMatthias Ringwald } 1931664436fSMatthias Ringwald 1941664436fSMatthias 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){ 1951664436fSMatthias Ringwald printf("READ Callback, handle %04x\n", att_handle); 1961664436fSMatthias Ringwald uint16_t value_len = get_read_att_value_len(att_handle); 1971664436fSMatthias Ringwald if (!buffer) return value_len; 1981664436fSMatthias Ringwald 1991664436fSMatthias Ringwald uint16_t bytes_to_copy = get_bytes_to_copy(value_len, offset, buffer_size); 2001664436fSMatthias Ringwald if (!bytes_to_copy) return 0; 2011664436fSMatthias Ringwald 2021664436fSMatthias Ringwald switch(att_handle){ 2031664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE: 2041664436fSMatthias Ringwald memcpy(buffer, &chr01_value[offset], bytes_to_copy); 2051664436fSMatthias Ringwald break; 2061664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE: 2071664436fSMatthias Ringwald buffer[offset] = chr02_value; 2081664436fSMatthias Ringwald break; 2091664436fSMatthias Ringwald } 2101664436fSMatthias Ringwald return bytes_to_copy; 2111664436fSMatthias Ringwald } 2121664436fSMatthias Ringwald 2131664436fSMatthias Ringwald // write requests 2141664436fSMatthias 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){ 2151664436fSMatthias Ringwald printf("WRITE Callback, handle %04x\n", att_handle); 2161664436fSMatthias Ringwald 2171664436fSMatthias Ringwald uint16_t value_len = get_write_att_value_len(att_handle); 2181664436fSMatthias Ringwald uint16_t bytes_to_copy = get_bytes_to_copy(value_len, offset,buffer_size); 2191664436fSMatthias Ringwald if (!bytes_to_copy) return ATT_ERROR_INVALID_OFFSET; 2201664436fSMatthias Ringwald 2211664436fSMatthias Ringwald switch(att_handle){ 2221664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF1_01_VALUE_HANDLE: 2231664436fSMatthias Ringwald buffer[buffer_size] = 0; 2241664436fSMatthias Ringwald memcpy(&chr01_value[offset], buffer, bytes_to_copy); 2251664436fSMatthias Ringwald chr01_value_length = bytes_to_copy + offset; 2261664436fSMatthias Ringwald 2271664436fSMatthias Ringwald printf("New text: %s\n", buffer); 2281664436fSMatthias Ringwald overwriteLine(7, (char*)buffer); 2291664436fSMatthias Ringwald break; 2301664436fSMatthias Ringwald case ATT_CHARACTERISTIC_FFF2_01_VALUE_HANDLE: 2311664436fSMatthias Ringwald printf("New value: %u\n", buffer[offset]); 2321664436fSMatthias Ringwald if (buffer[offset]) { 2331664436fSMatthias Ringwald LED_PORT_OUT |= LED_2; 2341664436fSMatthias Ringwald } else { 2351664436fSMatthias Ringwald LED_PORT_OUT &= ~LED_2; 2361664436fSMatthias Ringwald } 2371664436fSMatthias Ringwald chr02_value = buffer[offset]; 2381664436fSMatthias Ringwald break; 2391664436fSMatthias Ringwald } 2401664436fSMatthias Ringwald return 0; 2411664436fSMatthias Ringwald } 2421664436fSMatthias Ringwald 2431664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]); 2441664436fSMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 2451664436fSMatthias Ringwald 2461664436fSMatthias Ringwald // show off 2471664436fSMatthias Ringwald doLCD(); 2481664436fSMatthias Ringwald 2491664436fSMatthias Ringwald // set up l2cap_le 2501664436fSMatthias Ringwald l2cap_init(); 2511664436fSMatthias Ringwald 2521664436fSMatthias Ringwald // setup le device db 2531664436fSMatthias Ringwald le_device_db_init(); 2541664436fSMatthias Ringwald 2551664436fSMatthias Ringwald // setup SM: Display only 2561664436fSMatthias Ringwald sm_init(); 2571664436fSMatthias Ringwald sm_set_io_capabilities(IO_CAPABILITY_DISPLAY_ONLY); 2581664436fSMatthias Ringwald sm_set_authentication_requirements( SM_AUTHREQ_BONDING | SM_AUTHREQ_MITM_PROTECTION); 2591664436fSMatthias Ringwald 2601664436fSMatthias Ringwald // setup ATT server 2611664436fSMatthias Ringwald att_server_init(profile_data, NULL, att_write_callback); 2621664436fSMatthias Ringwald att_server_register_packet_handler(app_packet_handler); 2631664436fSMatthias Ringwald 2641664436fSMatthias Ringwald printf("Run...\n\r"); 2651664436fSMatthias Ringwald 2661664436fSMatthias Ringwald // turn on! 2671664436fSMatthias Ringwald hci_power_control(HCI_POWER_ON); 2681664436fSMatthias Ringwald 2691664436fSMatthias Ringwald LED_PORT_OUT &= ~LED_2; 2701664436fSMatthias Ringwald 2711664436fSMatthias Ringwald return 0; 2721664436fSMatthias Ringwald } 2731664436fSMatthias Ringwald 274