void setup_cli(){ struct termios term = {0}; if (tcgetattr(0, &term) < 0) perror("tcsetattr()"); term.c_lflag &= ~ICANON; term.c_lflag &= ~ECHO; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (tcsetattr(0, TCSANOW, &term) < 0) perror("tcsetattr ICANON"); stdin_source.fd = 0; // stdin stdin_source.process = &stdin_process; run_loop_add_data_source(&stdin_source); }
static int h4_open(void *transport_config){ // open uart hal_uart_dma_init(); hal_uart_dma_set_block_received(h4_block_received); hal_uart_dma_set_block_sent(h4_block_sent); // set up data_source run_loop_add_data_source(&hci_transport_h4_dma_ds); // h4_init_sm(); tx_state = TX_IDLE; return 0; }
/** * create socket data_source for unix domain socket */ int socket_connection_create_unix(char *path){ // create data_source_t data_source_t *ds = malloc( sizeof(data_source_t)); if (ds == NULL) return -1; ds->fd = 0; ds->process = socket_connection_accept; // create unix socket if ((ds->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) { log_error( "Error creating socket ...(%s)\n", strerror(errno)); free(ds); return -1; } log_info ("Socket created at %s\n", path); struct sockaddr_un addr; memset(&addr, 0, sizeof(addr)); #ifndef ANDROID addr.sun_family = AF_UNIX; #else addr.sun_family = AF_LOCAL; #endif strcpy(addr.sun_path, path); unlink(path); const int y = 1; setsockopt(ds->fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); if (bind ( ds->fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { log_error( "Error on bind() ...(%s)\n", strerror(errno)); free(ds); return -1; } if (listen (ds->fd, MAX_PENDING_CONNECTIONS)) { log_error( "Error on listen() ...(%s)\n", strerror(errno)); free(ds); return -1; } run_loop_add_data_source(ds); log_info ("Server up and running ...\n"); return 0; }
/* * Register listening sockets with our run loop */ void socket_connection_launchd_register_fd_array(launch_data_t listening_fd_array){ int i; for (i = 0; i < launch_data_array_get_count(listening_fd_array); i++) { // get fd launch_data_t tempi = launch_data_array_get_index (listening_fd_array, i); int listening_fd = launch_data_get_fd(tempi); launch_data_free (tempi); log_info("file descriptor = %u\n", listening_fd); // create data_source_t for fd data_source_t *ds = malloc( sizeof(data_source_t)); if (ds == NULL) return; ds->process = socket_connection_accept; ds->fd = listening_fd; run_loop_add_data_source(ds); } }
static int h4_open(void *transport_config){ // open uart hal_uart_dma_init(); hal_uart_dma_set_block_received(h4_block_received); hal_uart_dma_set_block_sent(h4_block_sent); hal_uart_dma_set_csr_irq_handler(ehcill_cts_irq_handler); // set up data_source run_loop_add_data_source(&hci_transport_h4_dma_ds); // init state machines h4_rx_init_sm(); tx_state = TX_IDLE; tx_len = 0; return 0; }
connection_t * socket_connection_register_new_connection(int fd){ // create connection objec connection_t * conn = malloc( sizeof(connection_t)); if (conn == NULL) return 0; linked_item_set_user( &conn->item, conn); conn->ds.fd = fd; conn->ds.process = socket_connection_hci_process; // prepare state machine and socket_connection_init_statemachine(conn); // add this socket to the run_loop run_loop_add_data_source( &conn->ds ); // and the connection list linked_list_add( &connections, &conn->item); return conn; }
/*============================================================================= =============================================================================*/ static int h4_open(void *config) { /* Initialise H4 receiver. */ rx.enqueueIdx = 0; rx.dequeueIdx = 0; advanceToNextBuffer(); BSP_BTUART_EnableRxCallback(h4_rx_data); /* Prepare for 1st H4 packet type ID. */ rx.state = H4_W4_PACKET_TYPE; rx.remainingInState = 1; BSP_BTUART_AnounceDmaReceiverSize(rx.remainingInState); hciTransportH4.dataSource.process = h4_reader_process; run_loop_add_data_source(&hciTransportH4.dataSource); return 0; }
/** * create socket data_source for tcp socket * * @return data_source object. If null, check errno */ int socket_connection_create_tcp(int port){ // create data_source_t data_source_t *ds = malloc( sizeof(data_source_t)); if (ds == NULL) return -1; ds->fd = 0; ds->process = socket_connection_accept; // create tcp socket if ((ds->fd = socket (PF_INET, SOCK_STREAM, 0)) < 0) { log_error("Error creating socket ...(%s)\n", strerror(errno)); free(ds); return -1; } log_info ("Socket created for port %u\n", port); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons (port); memset (&addr.sin_addr, 0, sizeof (addr.sin_addr)); const int y = 1; setsockopt(ds->fd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); if (bind ( ds->fd, (struct sockaddr *) &addr, sizeof (addr) ) ) { log_error("Error on bind() ...(%s)\n", strerror(errno)); free(ds); return -1; } if (listen (ds->fd, MAX_PENDING_CONNECTIONS)) { log_error("Error on listen() ...(%s)\n", strerror(errno)); free(ds); return -1; } run_loop_add_data_source(ds); log_info ("Server up and running ...\n"); return 0; }
/** * try to dispatch packet for all "parked" connections. * if dispatch is successful, a connection is added again to run loop * pre: connections get parked iff packet was dispatched but could not be sent */ void socket_connection_retry_parked(){ // log_info("socket_connection_hci_process retry parked\n"); linked_item_t *it = (linked_item_t *) &parked; while (it->next) { connection_t * conn = (connection_t *) it->next; // dispatch packet !!! connection, type, channel, data, size log_info("socket_connection_hci_process retry parked #0\n"); int dispatch_err = (*socket_connection_packet_callback)(conn, READ_BT_16( conn->buffer, 0), READ_BT_16( conn->buffer, 2), &conn->buffer[sizeof(packet_header_t)], READ_BT_16( conn->buffer, 4)); // "un-park" if successful if (!dispatch_err) { log_info("socket_connection_hci_process dispatch succeeded -> un-park connection\n"); it->next = it->next->next; run_loop_add_data_source( (data_source_t *) conn); } else { it = it->next; } } }
static int h4_open(void *transport_config) { hci_uart_config = (hci_uart_config_t*) transport_config; struct termios toptions; int flags = O_RDWR | O_NOCTTY | O_NONBLOCK; int fd = open(hci_uart_config->device_name, flags); if (fd == -1) { perror("init_serialport: Unable to open port "); perror(hci_uart_config->device_name); return -1; } if (tcgetattr(fd, &toptions) < 0) { perror("init_serialport: Couldn't get term attributes"); return -1; } cfmakeraw(&toptions); // make raw // 8N1 toptions.c_cflag &= ~CSTOPB; toptions.c_cflag |= CS8; if (hci_uart_config->flowcontrol) { // with flow control toptions.c_cflag |= CRTSCTS; } else { // no flow control toptions.c_cflag &= ~CRTSCTS; } toptions.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl // see: http://unixwiz.net/techtips/termios-vmin-vtime.html toptions.c_cc[VMIN] = 1; toptions.c_cc[VTIME] = 0; if( tcsetattr(fd, TCSANOW, &toptions) < 0) { perror("init_serialport: Couldn't set term attributes"); return -1; } // set up data_source hci_transport_h4->ds = (data_source_t*) malloc(sizeof(data_source_t)); if (!hci_transport_h4->ds) return -1; hci_transport_h4->uart_fd = fd; hci_transport_h4->ds->fd = fd; hci_transport_h4->ds->process = h4_process; run_loop_add_data_source(hci_transport_h4->ds); // also set baudrate if (h4_set_baudrate(hci_uart_config->baudrate_init) < 0) { return -1; } // init state machine bytes_to_read = 1; h4_state = H4_W4_PACKET_TYPE; read_pos = 0; return 0; }
static int h4_open(void *transport_config) { hci_uart_config = (hci_uart_config_t *) transport_config; int fd = socket(PF_NETGRAPH, SOCK_STREAM, NG_CONTROL); if (fd < 0) { perror("socket(HCI_IF)"); goto err_out0; } // get node address struct ioctl_arg_t { uint32_t result; char socket_name[96]; } ioctl_arg; memset((void *) &ioctl_arg, 0x00, sizeof(struct ioctl_arg_t)); strcpy((char *) &ioctl_arg.socket_name, SOCKET_DEVICE); if (ioctl(fd, SOCK_IOCTL_VAL, &ioctl_arg) != 0) { perror("ioctl(fd_sock, SOCK_IOCTL_VAL)"); goto err_out1; } // setup sock addr struct struct sockaddr_ng sock_addr; sock_addr.sg_len = sizeof(struct sockaddr_ng); sock_addr.sg_family = PF_NETGRAPH; sock_addr.sg_subtype = 0x02; sock_addr.sg_node = ioctl_arg.result; sock_addr.sg_null = 0; // connect if (connect(fd, (const struct sockaddr *) &sock_addr, sizeof(struct sockaddr_ng)) != 0) { perror("connect(fd_sock)"); goto err_out2; } // configure UART struct termios toptions; socklen_t toptions_len = sizeof(struct termios); if (getsockopt(fd, SO_ACCEPTCONN, GETSOCKOPT_VAL, &toptions, &toptions_len) != 0) { perror("getsockopt(fd_sock)"); goto err_out3; } cfmakeraw(&toptions); speed_t brate = (speed_t) hci_uart_config->baudrate_init; cfsetspeed(&toptions, brate); toptions.c_iflag |= IGNPAR; toptions.c_cflag = 0x00038b00; if (setsockopt(fd, SO_ACCEPTCONN, SETSOCKOPT_VAL, &toptions, toptions_len) != 0) { perror("setsockopt(fd_sock)"); goto err_out4; } // set up data_source hci_transport_h4->ds = malloc(sizeof(data_source_t)); if (!hci_transport_h4->ds) return -1; hci_transport_h4->uart_fd = fd; hci_transport_h4->ds->fd = fd; hci_transport_h4->ds->process = h4_process; run_loop_add_data_source(hci_transport_h4->ds); // init state machine bytes_to_read = 1; h4_state = H4_W4_PACKET_TYPE; read_pos = 0; return 0; err_out4: err_out3: err_out2: err_out1: close(fd); err_out0: fprintf(stderr, "h4_open error\n"); return -1; }
static int h4_open(void *transport_config){ hci_uart_config = (hci_uart_config_t*) transport_config; struct termios toptions; int flags = O_RDWR | O_NOCTTY; int fd = open(hci_uart_config->device_name, flags); if (fd == -1) { perror("init_serialport: Unable to open port "); perror(hci_uart_config->device_name); return -1; } if (tcgetattr(fd, &toptions) < 0) { perror("init_serialport: Couldn't get term attributes"); return -1; } speed_t brate = hci_uart_config->baudrate_init; // let you override switch below if needed switch(hci_uart_config->baudrate_init) { case 57600: brate=B57600; break; case 115200: brate=B115200; break; #ifdef B230400 case 230400: brate=B230400; break; #endif #ifdef B460800 case 460800: brate=B460800; break; #endif #ifdef B921600 case 921600: brate=B921600; break; #endif } cfsetspeed(&toptions, brate); // 8N1 toptions.c_cflag &= ~PARENB; toptions.c_cflag &= ~CSTOPB; toptions.c_cflag &= ~CSIZE; toptions.c_cflag |= CS8; if (hci_uart_config->flowcontrol) { // with flow control toptions.c_cflag |= CRTSCTS; } else { // no flow control toptions.c_cflag &= ~CRTSCTS; } toptions.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw toptions.c_oflag &= ~OPOST; // make raw // see: http://unixwiz.net/techtips/termios-vmin-vtime.html toptions.c_cc[VMIN] = 1; toptions.c_cc[VTIME] = 0; if( tcsetattr(fd, TCSANOW, &toptions) < 0) { perror("init_serialport: Couldn't set term attributes"); return -1; } // set up data_source hci_transport_h4->ds = malloc(sizeof(data_source_t)); if (!hci_transport_h4->ds) return -1; hci_transport_h4->uart_fd = fd; hci_transport_h4->ds->fd = fd; hci_transport_h4->ds->process = h4_process; run_loop_add_data_source(hci_transport_h4->ds); // init state machine bytes_to_read = 1; h4_state = H4_W4_PACKET_TYPE; read_pos = 0; return 0; }
static int usb_open(void *transport_config){ int r; sco_state_machine_init(); sco_ring_init(); handle_packet = NULL; // default endpoint addresses event_in_addr = 0x81; // EP1, IN interrupt acl_in_addr = 0x82; // EP2, IN bulk acl_out_addr = 0x02; // EP2, OUT bulk sco_in_addr = 0x83; // EP3, IN isochronous sco_out_addr = 0x03; // EP3, OUT isochronous // USB init r = libusb_init(NULL); if (r < 0) return -1; libusb_state = LIB_USB_OPENED; // configure debug level libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING); #ifdef HAVE_USB_VENDOR_ID_AND_PRODUCT_ID // Use a specified device log_info("Want vend: %04x, prod: %04x", USB_VENDOR_ID, USB_PRODUCT_ID); handle = libusb_open_device_with_vid_pid(NULL, USB_VENDOR_ID, USB_PRODUCT_ID); if (!handle){ log_error("libusb_open_device_with_vid_pid failed!"); usb_close(handle); return -1; } log_info("libusb open %d, handle %p", r, handle); r = prepare_device(handle); if (r < 0){ usb_close(handle); return -1; } #else // Scan system for an appropriate devices libusb_device **devs; ssize_t cnt; log_info("Scanning for USB Bluetooth device"); cnt = libusb_get_device_list(NULL, &devs); if (cnt < 0) { usb_close(handle); return -1; } int startIndex = 0; dev = NULL; while (1){ int deviceIndex = scan_for_bt_device(devs, startIndex); if (deviceIndex < 0){ break; } startIndex = deviceIndex+1; log_info("USB Bluetooth device found, index %u", deviceIndex); handle = NULL; r = libusb_open(devs[deviceIndex], &handle); if (r < 0) { log_error("libusb_open failed!"); handle = NULL; continue; } log_info("libusb open %d, handle %p", r, handle); // reset device libusb_reset_device(handle); if (r < 0) { log_error("libusb_reset_device failed!"); libusb_close(handle); handle = NULL; continue; } // device found r = prepare_device(handle); if (r < 0){ continue; } libusb_state = LIB_USB_INTERFACE_CLAIMED; break; } libusb_free_device_list(devs, 1); if (handle == 0){ log_error("No USB Bluetooth device found"); return -1; } scan_for_bt_endpoints(); #endif // allocate transfer handlers int c; for (c = 0 ; c < ASYNC_BUFFERS ; c++) { event_in_transfer[c] = libusb_alloc_transfer(0); // 0 isochronous transfers Events acl_in_transfer[c] = libusb_alloc_transfer(0); // 0 isochronous transfers ACL in if ( !event_in_transfer[c] || !acl_in_transfer[c]) { usb_close(handle); return LIBUSB_ERROR_NO_MEM; } } command_out_transfer = libusb_alloc_transfer(0); acl_out_transfer = libusb_alloc_transfer(0); // TODO check for error libusb_state = LIB_USB_TRANSFERS_ALLOCATED; #ifdef HAVE_SCO // incoming for (c = 0 ; c < ASYNC_BUFFERS ; c++) { sco_in_transfer[c] = libusb_alloc_transfer(NUM_ISO_PACKETS); // isochronous transfers SCO in log_info("Alloc iso transfer"); if (!sco_in_transfer[c]) { usb_close(handle); return LIBUSB_ERROR_NO_MEM; } // configure sco_in handlers libusb_fill_iso_transfer(sco_in_transfer[c], handle, sco_in_addr, hci_sco_in_buffer[c], SCO_PACKET_SIZE, NUM_ISO_PACKETS, async_callback, NULL, 0); libusb_set_iso_packet_lengths(sco_in_transfer[c], ISO_PACKET_SIZE); r = libusb_submit_transfer(sco_in_transfer[c]); log_info("Submit iso transfer res = %d", r); if (r) { log_error("Error submitting isochronous in transfer %d", r); usb_close(handle); return r; } } // outgoing for (c=0; c < SCO_RING_BUFFER_COUNT ; c++){ sco_ring_transfers[c] = libusb_alloc_transfer(NUM_ISO_PACKETS); // 1 isochronous transfers SCO out - up to 3 parts } #endif for (c = 0 ; c < ASYNC_BUFFERS ; c++) { // configure event_in handlers libusb_fill_interrupt_transfer(event_in_transfer[c], handle, event_in_addr, hci_event_in_buffer[c], HCI_ACL_BUFFER_SIZE, async_callback, NULL, 0) ; r = libusb_submit_transfer(event_in_transfer[c]); if (r) { log_error("Error submitting interrupt transfer %d", r); usb_close(handle); return r; } // configure acl_in handlers libusb_fill_bulk_transfer(acl_in_transfer[c], handle, acl_in_addr, hci_acl_in_buffer[c] + HCI_INCOMING_PRE_BUFFER_SIZE, HCI_ACL_BUFFER_SIZE, async_callback, NULL, 0) ; r = libusb_submit_transfer(acl_in_transfer[c]); if (r) { log_error("Error submitting bulk in transfer %d", r); usb_close(handle); return r; } } // Check for pollfds functionality doing_pollfds = libusb_pollfds_handle_timeouts(NULL); // NOTE: using pollfds doesn't work on Linux, so it is disable until further investigation here doing_pollfds = 0; if (doing_pollfds) { log_info("Async using pollfds:"); const struct libusb_pollfd ** pollfd = libusb_get_pollfds(NULL); for (num_pollfds = 0 ; pollfd[num_pollfds] ; num_pollfds++); pollfd_data_sources = malloc(sizeof(data_source_t) * num_pollfds); if (!pollfd_data_sources){ log_error("Cannot allocate data sources for pollfds"); usb_close(handle); return 1; } for (r = 0 ; r < num_pollfds ; r++) { data_source_t *ds = &pollfd_data_sources[r]; ds->fd = pollfd[r]->fd; ds->process = usb_process_ds; run_loop_add_data_source(ds); log_info("%u: %p fd: %u, events %x", r, pollfd[r], pollfd[r]->fd, pollfd[r]->events); } free(pollfd); } else { log_info("Async using timers:"); usb_timer.process = usb_process_ts; run_loop_set_timer(&usb_timer, AYSNC_POLLING_INTERVAL_MS); run_loop_add_timer(&usb_timer); usb_timer_active = 1; } return 0; }
// main int main ( void ) { // Initialize the processor and peripherals. // Init Clock // CPU 32MHz // Peripheral 8MHz CLKDIV = 0x0000; unsigned int pll_startup_counter = 600; CLKDIVbits.PLLEN = 1; while(pll_startup_counter--); // Configure U2RX - put on pin 17 (RP8) RPINR19bits.U2RXR = 8; // Configure U2TX - put on pin 16 (RP7) RPOR3bits.RP7R = 5; // Analog IN Disable AD1PCFG = 0xffff; EnablePullUpCN12; // Port output setup mPORTBOutputConfig(0x8000); // Init UART UART2Init(); // Init USB if ( USBHostInit(0) != TRUE ) { UART2PrintString( "ERR USBHostInit\r\n" ); while (1); } /// GET STARTED with BTstack /// btstack_memory_init(); run_loop_init(RUN_LOOP_EMBEDDED); // init HCI hci_transport_t * transport = hci_transport_usb_instance(); bt_control_t * control = NULL; hci_uart_config_t * config = NULL; remote_device_db_t * remote_db = NULL;//(remote_device_db_t *) &remote_device_db_memory; hci_init(transport, config, control, remote_db); // init L2CAP l2cap_init(); l2cap_register_packet_handler(bt_packet_handler); // init RFCOMM rfcomm_init(); rfcomm_register_packet_handler(bt_packet_handler); rfcomm_register_service_internal(NULL, rfcomm_channel_nr, 100); // reserved channel, mtu=100 // init SDP, create record for SPP and register with SDP sdp_init(); memset(spp_service_buffer, 0, sizeof(spp_service_buffer)); service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer; sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP"); // printf("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record))); sdp_register_service_internal(NULL, service_record_item); // usbhost data_source_t usbhost; usbhost.process = &usbhost_process; run_loop_add_data_source(&usbhost); data_source_t swtask; swtask.process = &sw_process; run_loop_add_data_source(&swtask); // go! run_loop_execute(); return 0; } // main
// main int main(void) { // stop watchdog timer WDTCTL = WDTPW + WDTHOLD; //Initialize clock and peripherals halBoardInit(); halBoardStartXT1(); halBoardSetSystemClock(SYSCLK_16MHZ); // init debug UART halUsbInit(); // init LEDs P1OUT |= LED_1 | LED_2; P1DIR |= LED_1 | LED_2; /*//init linkLED P1OUT &= ~BIT0; P1DIR |= BIT0;*/ //Setup Input Port 2 initSwitch(2, BIT0); initSwitch(2, BIT1); initSwitch(2, BIT2); initSwitch(2, BIT3); //tie port3 and unused pins of port 2 /*P3OUT = 0; P3DIR = 0xFF; P3SEL = 0; P2OUT &= 0x0F; P2DIR |= 0xF0; P2SEL &= 0x0F;*/ /// GET STARTED with BTstack /// btstack_memory_init(); run_loop_init(RUN_LOOP_EMBEDDED); // add gpio port 2 to run loop // default values port2_status = P2IN & 0x0F; data_source_t data_src_port2; data_src_port2.process = port2_poll; data_src_port2.fd = 0; run_loop_add_data_source(&data_src_port2); // init HCI hci_transport_t * transport = hci_transport_h4_dma_instance(); bt_control_t * control = bt_control_cc256x_instance(); hci_uart_config_t * config = hci_uart_config_cc256x_instance(); remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; hci_init(transport, config, control, remote_db); // use eHCILL bt_control_cc256x_enable_ehcill(1); // init L2CAP l2cap_init(); l2cap_register_packet_handler(bt_packet_handler); l2cap_register_service_internal(NULL, l2cap_packet_handler, 0x1001, L2CAP_MINIMAL_MTU); // ready - enable irq used in h4 task __enable_interrupt(); // turn on! if(hci_power_control(HCI_POWER_ON)) printf("power on failed"); //init i2c initi2c(); // go! run_loop_execute(); // happy compiler! return 0; }