1*f1b34e8dSMatthias Ringwald /* 2*f1b34e8dSMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*f1b34e8dSMatthias Ringwald * 4*f1b34e8dSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*f1b34e8dSMatthias Ringwald * modification, are permitted provided that the following conditions 6*f1b34e8dSMatthias Ringwald * are met: 7*f1b34e8dSMatthias Ringwald * 8*f1b34e8dSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*f1b34e8dSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*f1b34e8dSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*f1b34e8dSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*f1b34e8dSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*f1b34e8dSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*f1b34e8dSMatthias Ringwald * contributors may be used to endorse or promote products derived 15*f1b34e8dSMatthias Ringwald * from this software without specific prior written permission. 16*f1b34e8dSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*f1b34e8dSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*f1b34e8dSMatthias Ringwald * monetary gain. 19*f1b34e8dSMatthias Ringwald * 20*f1b34e8dSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*f1b34e8dSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*f1b34e8dSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*f1b34e8dSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*f1b34e8dSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*f1b34e8dSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*f1b34e8dSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*f1b34e8dSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*f1b34e8dSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*f1b34e8dSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*f1b34e8dSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*f1b34e8dSMatthias Ringwald * SUCH DAMAGE. 32*f1b34e8dSMatthias Ringwald * 33*f1b34e8dSMatthias Ringwald * Please inquire about commercial licensing options at 34*f1b34e8dSMatthias Ringwald * [email protected] 35*f1b34e8dSMatthias Ringwald * 36*f1b34e8dSMatthias Ringwald */ 37*f1b34e8dSMatthias Ringwald 38*f1b34e8dSMatthias Ringwald #include "btstack_config.h" 39*f1b34e8dSMatthias Ringwald 40*f1b34e8dSMatthias Ringwald #include <stdint.h> 41*f1b34e8dSMatthias Ringwald #include <stdio.h> 42*f1b34e8dSMatthias Ringwald #include <stdlib.h> 43*f1b34e8dSMatthias Ringwald #include <string.h> 44*f1b34e8dSMatthias Ringwald 45*f1b34e8dSMatthias Ringwald #include "btstack_run_loop.h" 46*f1b34e8dSMatthias Ringwald #include "l2cap.h" 47*f1b34e8dSMatthias Ringwald #include "rfcomm.h" 48*f1b34e8dSMatthias Ringwald #include "btstack_event.h" 49*f1b34e8dSMatthias Ringwald #include "classic/goep_client.h" 50*f1b34e8dSMatthias Ringwald #include "classic/pbap_client.h" 51*f1b34e8dSMatthias Ringwald 52*f1b34e8dSMatthias Ringwald #ifdef HAVE_POSIX_STDIN 53*f1b34e8dSMatthias Ringwald #include <unistd.h> 54*f1b34e8dSMatthias Ringwald #include "stdin_support.h" 55*f1b34e8dSMatthias Ringwald #endif 56*f1b34e8dSMatthias Ringwald 57*f1b34e8dSMatthias Ringwald #ifndef HAVE_POSIX_STDIN 58*f1b34e8dSMatthias Ringwald static int step = 0; 59*f1b34e8dSMatthias Ringwald #endif 60*f1b34e8dSMatthias Ringwald 61*f1b34e8dSMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); 62*f1b34e8dSMatthias Ringwald 63*f1b34e8dSMatthias Ringwald static bd_addr_t remote_addr; 64*f1b34e8dSMatthias Ringwald // MBP2016 "F4-0F-24-3B-1B-E1" 65*f1b34e8dSMatthias Ringwald // Nexus 7 "30-85-A9-54-2E-78" 66*f1b34e8dSMatthias Ringwald static const char * remote_addr_string = "30-85-A9-54-2E-78"; 67*f1b34e8dSMatthias Ringwald 68*f1b34e8dSMatthias Ringwald static btstack_packet_callback_registration_t hci_event_callback_registration; 69*f1b34e8dSMatthias Ringwald static uint16_t pbap_cid; 70*f1b34e8dSMatthias Ringwald 71*f1b34e8dSMatthias Ringwald #ifdef HAVE_POSIX_STDIN 72*f1b34e8dSMatthias Ringwald 73*f1b34e8dSMatthias Ringwald // Testig User Interface 74*f1b34e8dSMatthias Ringwald static void show_usage(void){ 75*f1b34e8dSMatthias Ringwald bd_addr_t iut_address; 76*f1b34e8dSMatthias Ringwald gap_local_bd_addr(iut_address); 77*f1b34e8dSMatthias Ringwald 78*f1b34e8dSMatthias Ringwald printf("\n--- Bluetooth PBAP Client (HF) Test Console %s ---\n", bd_addr_to_str(iut_address)); 79*f1b34e8dSMatthias Ringwald printf("\n"); 80*f1b34e8dSMatthias Ringwald printf("a - establish PBAP connection to %s\n", bd_addr_to_str(remote_addr)); 81*f1b34e8dSMatthias Ringwald printf("b - set phonebook '/telecom/pb'\n"); 82*f1b34e8dSMatthias Ringwald printf("c - set phonebook '/SIM1/telecom/pb'\n"); 83*f1b34e8dSMatthias Ringwald printf("d - pull phonebook\n"); 84*f1b34e8dSMatthias Ringwald printf("e - disconnnect\n"); 85*f1b34e8dSMatthias Ringwald printf("---\n"); 86*f1b34e8dSMatthias Ringwald printf("Ctrl-c - exit\n"); 87*f1b34e8dSMatthias Ringwald printf("---\n"); 88*f1b34e8dSMatthias Ringwald } 89*f1b34e8dSMatthias Ringwald 90*f1b34e8dSMatthias Ringwald static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type){ 91*f1b34e8dSMatthias Ringwald UNUSED(ds); 92*f1b34e8dSMatthias Ringwald UNUSED(callback_type); 93*f1b34e8dSMatthias Ringwald 94*f1b34e8dSMatthias Ringwald char cmd = btstack_stdin_read(); 95*f1b34e8dSMatthias Ringwald 96*f1b34e8dSMatthias Ringwald switch (cmd){ 97*f1b34e8dSMatthias Ringwald case 'a': 98*f1b34e8dSMatthias Ringwald printf("[+] Connecting to %s...\n", bd_addr_to_str(remote_addr)); 99*f1b34e8dSMatthias Ringwald pbap_connect(&packet_handler, remote_addr, &pbap_cid); 100*f1b34e8dSMatthias Ringwald break; 101*f1b34e8dSMatthias Ringwald case 'b': 102*f1b34e8dSMatthias Ringwald printf("[+] Set Phonebook 'telecom/pb'\n"); 103*f1b34e8dSMatthias Ringwald pbap_set_phonebook(pbap_cid, "telecom/pb"); 104*f1b34e8dSMatthias Ringwald break; 105*f1b34e8dSMatthias Ringwald case 'c': 106*f1b34e8dSMatthias Ringwald printf("[+] Set Phonebook 'SIM1/telecom/pb'\n"); 107*f1b34e8dSMatthias Ringwald pbap_set_phonebook(pbap_cid, "SIM1/telecom/pb"); 108*f1b34e8dSMatthias Ringwald break; 109*f1b34e8dSMatthias Ringwald case 'd': 110*f1b34e8dSMatthias Ringwald pbap_pull_phonebook(pbap_cid); 111*f1b34e8dSMatthias Ringwald break; 112*f1b34e8dSMatthias Ringwald case 'e': 113*f1b34e8dSMatthias Ringwald pbap_disconnect(pbap_cid); 114*f1b34e8dSMatthias Ringwald break; 115*f1b34e8dSMatthias Ringwald default: 116*f1b34e8dSMatthias Ringwald show_usage(); 117*f1b34e8dSMatthias Ringwald break; 118*f1b34e8dSMatthias Ringwald } 119*f1b34e8dSMatthias Ringwald } 120*f1b34e8dSMatthias Ringwald 121*f1b34e8dSMatthias Ringwald // packet handler for interactive console 122*f1b34e8dSMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 123*f1b34e8dSMatthias Ringwald UNUSED(channel); 124*f1b34e8dSMatthias Ringwald UNUSED(size); 125*f1b34e8dSMatthias Ringwald int i; 126*f1b34e8dSMatthias Ringwald switch (packet_type){ 127*f1b34e8dSMatthias Ringwald case HCI_EVENT_PACKET: 128*f1b34e8dSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 129*f1b34e8dSMatthias Ringwald case BTSTACK_EVENT_STATE: 130*f1b34e8dSMatthias Ringwald // BTstack activated, get started 131*f1b34e8dSMatthias Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 132*f1b34e8dSMatthias Ringwald show_usage(); 133*f1b34e8dSMatthias Ringwald } 134*f1b34e8dSMatthias Ringwald break; 135*f1b34e8dSMatthias Ringwald case HCI_EVENT_PBAP_META: 136*f1b34e8dSMatthias Ringwald switch (hci_event_pbap_meta_get_subevent_code(packet)){ 137*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_CONNECTION_OPENED: 138*f1b34e8dSMatthias Ringwald printf("[+] Connected\n"); 139*f1b34e8dSMatthias Ringwald break; 140*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_CONNECTION_CLOSED: 141*f1b34e8dSMatthias Ringwald printf("[+] Connection closed\n"); 142*f1b34e8dSMatthias Ringwald break; 143*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_OPERATION_COMPLETED: 144*f1b34e8dSMatthias Ringwald printf("[+] Operation complete\n"); 145*f1b34e8dSMatthias Ringwald break; 146*f1b34e8dSMatthias Ringwald default: 147*f1b34e8dSMatthias Ringwald break; 148*f1b34e8dSMatthias Ringwald } 149*f1b34e8dSMatthias Ringwald break; 150*f1b34e8dSMatthias Ringwald default: 151*f1b34e8dSMatthias Ringwald break; 152*f1b34e8dSMatthias Ringwald } 153*f1b34e8dSMatthias Ringwald break; 154*f1b34e8dSMatthias Ringwald case PBAP_DATA_PACKET: 155*f1b34e8dSMatthias Ringwald for (i=0;i<size;i++){ 156*f1b34e8dSMatthias Ringwald printf("%c", packet[i]); 157*f1b34e8dSMatthias Ringwald } 158*f1b34e8dSMatthias Ringwald break; 159*f1b34e8dSMatthias Ringwald default: 160*f1b34e8dSMatthias Ringwald break; 161*f1b34e8dSMatthias Ringwald } 162*f1b34e8dSMatthias Ringwald } 163*f1b34e8dSMatthias Ringwald #else 164*f1b34e8dSMatthias Ringwald 165*f1b34e8dSMatthias Ringwald // packet handler for emdded system with fixed operation sequence 166*f1b34e8dSMatthias Ringwald static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ 167*f1b34e8dSMatthias Ringwald UNUSED(channel); 168*f1b34e8dSMatthias Ringwald UNUSED(size); 169*f1b34e8dSMatthias Ringwald int i; 170*f1b34e8dSMatthias Ringwald switch (packet_type){ 171*f1b34e8dSMatthias Ringwald case HCI_EVENT_PACKET: 172*f1b34e8dSMatthias Ringwald switch (hci_event_packet_get_type(packet)) { 173*f1b34e8dSMatthias Ringwald case BTSTACK_EVENT_STATE: 174*f1b34e8dSMatthias Ringwald // BTstack activated, get started 175*f1b34e8dSMatthias Ringwald if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ 176*f1b34e8dSMatthias Ringwald printf("[+] Connect to Phone Book Server on %s\n", bd_addr_to_str(remote_addr)); 177*f1b34e8dSMatthias Ringwald pbap_connect(&packet_handler, remote_addr, &pbap_cid); 178*f1b34e8dSMatthias Ringwald } 179*f1b34e8dSMatthias Ringwald break; 180*f1b34e8dSMatthias Ringwald case HCI_EVENT_PBAP_META: 181*f1b34e8dSMatthias Ringwald switch (hci_event_pbap_meta_get_subevent_code(packet)){ 182*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_CONNECTION_OPENED: 183*f1b34e8dSMatthias Ringwald printf("[+] Connected\n"); 184*f1b34e8dSMatthias Ringwald printf("[+] Pull phonebook\n"); 185*f1b34e8dSMatthias Ringwald pbap_pull_phonebook(pbap_cid); 186*f1b34e8dSMatthias Ringwald break; 187*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_CONNECTION_CLOSED: 188*f1b34e8dSMatthias Ringwald printf("[+] Connection closed\n"); 189*f1b34e8dSMatthias Ringwald break; 190*f1b34e8dSMatthias Ringwald case PBAP_SUBEVENT_OPERATION_COMPLETED: 191*f1b34e8dSMatthias Ringwald printf("[+] Operation complete\n"); 192*f1b34e8dSMatthias Ringwald printf("[+] Pull Phonebook complete\n"); 193*f1b34e8dSMatthias Ringwald pbap_disconnect(pbap_cid); 194*f1b34e8dSMatthias Ringwald break; 195*f1b34e8dSMatthias Ringwald default: 196*f1b34e8dSMatthias Ringwald break; 197*f1b34e8dSMatthias Ringwald } 198*f1b34e8dSMatthias Ringwald break; 199*f1b34e8dSMatthias Ringwald default: 200*f1b34e8dSMatthias Ringwald break; 201*f1b34e8dSMatthias Ringwald } 202*f1b34e8dSMatthias Ringwald break; 203*f1b34e8dSMatthias Ringwald case PBAP_DATA_PACKET: 204*f1b34e8dSMatthias Ringwald for (i=0;i<size;i++){ 205*f1b34e8dSMatthias Ringwald printf("%c", packet[i]); 206*f1b34e8dSMatthias Ringwald } 207*f1b34e8dSMatthias Ringwald break; 208*f1b34e8dSMatthias Ringwald default: 209*f1b34e8dSMatthias Ringwald break; 210*f1b34e8dSMatthias Ringwald } 211*f1b34e8dSMatthias Ringwald } 212*f1b34e8dSMatthias Ringwald #endif 213*f1b34e8dSMatthias Ringwald 214*f1b34e8dSMatthias Ringwald int btstack_main(int argc, const char * argv[]); 215*f1b34e8dSMatthias Ringwald int btstack_main(int argc, const char * argv[]){ 216*f1b34e8dSMatthias Ringwald 217*f1b34e8dSMatthias Ringwald (void)argc; 218*f1b34e8dSMatthias Ringwald (void)argv; 219*f1b34e8dSMatthias Ringwald 220*f1b34e8dSMatthias Ringwald sscanf_bd_addr(remote_addr_string, remote_addr); 221*f1b34e8dSMatthias Ringwald 222*f1b34e8dSMatthias Ringwald // register for HCI events 223*f1b34e8dSMatthias Ringwald hci_event_callback_registration.callback = &packet_handler; 224*f1b34e8dSMatthias Ringwald hci_add_event_handler(&hci_event_callback_registration); 225*f1b34e8dSMatthias Ringwald 226*f1b34e8dSMatthias Ringwald // init L2CAP 227*f1b34e8dSMatthias Ringwald l2cap_init(); 228*f1b34e8dSMatthias Ringwald 229*f1b34e8dSMatthias Ringwald // init RFCOM 230*f1b34e8dSMatthias Ringwald rfcomm_init(); 231*f1b34e8dSMatthias Ringwald 232*f1b34e8dSMatthias Ringwald // init GOEP Client 233*f1b34e8dSMatthias Ringwald goep_client_init(); 234*f1b34e8dSMatthias Ringwald 235*f1b34e8dSMatthias Ringwald // init PBAP Client 236*f1b34e8dSMatthias Ringwald pbap_client_init(); 237*f1b34e8dSMatthias Ringwald 238*f1b34e8dSMatthias Ringwald #ifdef HAVE_POSIX_STDIN 239*f1b34e8dSMatthias Ringwald btstack_stdin_setup(stdin_process); 240*f1b34e8dSMatthias Ringwald #endif 241*f1b34e8dSMatthias Ringwald 242*f1b34e8dSMatthias Ringwald // turn on! 243*f1b34e8dSMatthias Ringwald hci_power_control(HCI_POWER_ON); 244*f1b34e8dSMatthias Ringwald 245*f1b34e8dSMatthias Ringwald return 0; 246*f1b34e8dSMatthias Ringwald } 247