diff --git a/example/libusb/Makefile b/example/libusb/Makefile index 271027f3c..5da5bf111 100644 --- a/example/libusb/Makefile +++ b/example/libusb/Makefile @@ -38,7 +38,9 @@ COMMON_OBJ = $(COMMON:.c=.o) # create firmware image from common objects and example source file -all: ../../include/btstack/version.h sdp_rfcomm_query sdp_general_query spp_counter ble_server +all: ../../include/btstack/version.h ble_client +#sdp_rfcomm_query sdp_general_query spp_counter ble_server ble_client + #spp-usb l2cap-server-usb l2cap-client-usb l2cap-server-uart l2cap-client-uart ../../include/btstack/version.h: @@ -63,8 +65,12 @@ profile.h: profile.gatt ble_server: ${CORE_OBJ} ${COMMON_OBJ} rijndael.c ble_server.c profile.h ${CC} ${CORE_OBJ} ${COMMON_OBJ} rijndael.c ble_server.c ${CFLAGS} ${LDFLAGS} -o $@ +ble_client: ${CORE_OBJ} ${COMMON_OBJ} rijndael.c ble_client.c profile.h + ${CC} ${CORE_OBJ} ${COMMON_OBJ} rijndael.c ble_client.c ${CFLAGS} ${LDFLAGS} -o $@ + clean: - rm -f spp_counter sdp_rfcomm_query sdp_general_query spp_counter_ssp *.o *.out *.hex + rm -f spp_counter sdp_rfcomm_query sdp_general_query spp_counter_ssp ble_server ble_client + rm -f *.o *.out *.hex rm -f ${BTSTACK_ROOT}/src/*.o rm -f ${BTSTACK_ROOT}/ble/*.o rm -f ${BTSTACK_ROOT}/chipset-cc256x/*.o diff --git a/example/libusb/ble_client.c b/example/libusb/ble_client.c new file mode 100644 index 000000000..142317d05 --- /dev/null +++ b/example/libusb/ble_client.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2011-2012 by Matthias Ringwald + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. This software may not be used in a commercial product + * without an explicit license granted by the copyright holder. + * + * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +//***************************************************************************** +// +// BLE Client +// +//***************************************************************************** + +// TODO: seperate BR/EDR from LE ACL buffers +// TODO: move LE init into HCI +// .. + +// NOTE: Supports only a single connection + +#include +#include +#include +#include +#include + +#include "config.h" + +#include "debug.h" +#include "btstack_memory.h" +#include "hci.h" +#include "hci_dump.h" + +#include "l2cap.h" + +#include "att.h" + +// API + +void gatt_client_init(); +void gatt_client_start_scan(); +// creates one event per found peripheral device +// EVENT: type (8), addr_type (8), addr(48), rssi(8), ad_len(8), ad_data(ad_len*8) +void gatt_client_stop_scan(); + +// END API + +// gatt client state +static uint8_t requested_scan_state = 0; +static uint8_t scan_state = 0; + + +void gatt_client_init(){ + requested_scan_state = 0; + scan_state = 0; +} + +static void gatt_client_run(){ + if (!hci_can_send_packet_now(HCI_COMMAND_DATA_PACKET)) return; + if (scan_state == requested_scan_state) return; + + if (requested_scan_state){ + printf("Starting scan...\n"); + } else { + printf("Stopping scan...\n"); + } + + hci_send_cmd(&hci_le_set_scan_enable, requested_scan_state, 0); +} + +void gatt_client_start_scan(){ + requested_scan_state = 1; + gatt_client_run(); +} + +void gatt_client_stop_scan(){ + requested_scan_state = 0; + gatt_client_run(); +} + +static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + switch (packet_type) { + + case HCI_EVENT_PACKET: + switch (packet[0]) { + + case BTSTACK_EVENT_STATE: + // bt stack activated, get started - set local name + if (packet[2] == HCI_STATE_WORKING) { + printf("Working!\n"); + gatt_client_start_scan(); + } + break; + + case HCI_EVENT_COMMAND_COMPLETE: + if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_enable)){ + scan_state = requested_scan_state; + } + break; + + case HCI_EVENT_LE_META: + switch (packet[2]) { + case HCI_SUBEVENT_LE_ADVERTISING_REPORT: + // reset connection MTU + printf("Received ad ...\n"); + break; + default: + break; + } + break; + + default: + break; + } + } + + gatt_client_run(); +} + + +void setup(void){ + /// GET STARTED with BTstack /// + btstack_memory_init(); + run_loop_init(RUN_LOOP_POSIX); + + // use logger: format HCI_DUMP_PACKETLOGGER, HCI_DUMP_BLUEZ or HCI_DUMP_STDOUT + hci_dump_open("/tmp/hci_dump.pklg", HCI_DUMP_PACKETLOGGER); + + // init HCI + hci_transport_t * transport = hci_transport_usb_instance(); + hci_uart_config_t * config = NULL; + bt_control_t * control = NULL; + remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; + + hci_init(transport, config, control, remote_db); + + l2cap_init(); + //l2cap_register_fixed_channel(packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL); + l2cap_register_packet_handler(packet_handler); +} + +// main == setup +int main(void) +{ + setup(); + + // turn on! + hci_power_control(HCI_POWER_ON); + + // go! + run_loop_execute(); + + // happy compiler! + return 0; +}