int tune::scan_for_services(unsigned int mode, unsigned int min, unsigned int max, bool epg, scan_progress_callback progress_cb, void* progress_context, chandump_callback chandump_cb, void* chandump_context, bool wait_for_results) { unsigned int count = 0; unsigned int total_count = 0; if (!mode) mode = SCAN_VSB; for (scan_mode = SCAN_VSB; scan_mode <= SCAN_QAM; scan_mode++) if (mode & scan_mode) { count = 0; if (0 != start_scan(scan_mode, min, max, epg, progress_cb, progress_context)) return -1; if (wait_for_results) { count += get_scan_results(true, chandump_cb, chandump_context); total_count += count; #if 0 for (map_chan_to_ts_id::const_iterator iter = channels.begin(); iter != channels.end(); ++iter) fprintf(stderr, "found ts_id %05d on channel %d\n", iter->second, iter->first); channels.clear(); // #endif fprintf(stderr, "found %d services\n", count); } } if (count != total_count) fprintf(stderr, "found %d services in total\n", total_count); return 0; }
/* mode,channel_arr,scantime */ static int l_start_scan(lua_State *L, void *param) { CHK_STR(L, 2); CHK_NUM(L, 3); CHK_NUM(L, 4); CHK_TAB(L, 5); mode_ioctl_st *mode_ioctl = (mode_ioctl_st *)param; assert(mode_ioctl && mode_ioctl->ioctl_func); ugw_ext_scan_params_t st; st.scan_mode = lua_tointeger(L, 3); assert(st.scan_mode == 1 || st.scan_mode == 2); int i = 0; lua_pushnil(L); while (i < MAX_SCAN_CHAN_CNT && lua_next(L, -2)) { CHK_NUM(L, -1); st.scan_channel_list[i] = lua_tonumber(L, -1); lua_pop(L, 1); i++; } if (i == 0) { lua_pushboolean(L, 1); return 1; } st.channel_num = i; st.scan_per_channel_time = lua_tointeger(L, 4); int ret = start_scan(sock, lua_tostring(L, 2), &st); CHK_RET(ret, mode_ioctl); }
static void continue_bonding(){ if (has_more_bonding_requests()){ do_next_bonding_request(); return; } start_scan(); }
int tune::start_scan(unsigned int mode, unsigned int min, unsigned int max, bool epg, scan_progress_callback progress_cb, void *progress_context) { //channels.clear(); scan_channel_list.clear(); unsigned int scan_min = min; unsigned int scan_max = max; if (mode != SCAN_QAM) mode = SCAN_VSB; scan_mode = mode; switch (scan_mode) { default: case SCAN_VSB: scan_min = (min) ? min : 2; scan_max = (max) ? max : 69; break; case SCAN_QAM: scan_min = (min) ? min : 2; scan_max = (max) ? max : 133; break; } for (unsigned int channel = scan_min; channel <= scan_max; channel++) scan_channel_list[channel] = false; // TODO: set true if channel found return start_scan(mode, epg, progress_cb, progress_context); }
static void continue_remote_names(void){ if (has_more_remote_name_requests()){ do_next_remote_name_request(); return; } start_scan(); }
int main( int argc, char **argv ) { if (argc != 2) usage(); start_scan(argv[1]); return 0; }
int tune::scan_for_services(unsigned int mode, char *channel_list, bool epg, scan_progress_callback progress_cb, void* progress_context, chandump_callback chandump_cb, void* chandump_context, bool wait_for_results) { unsigned int count = 0; if (!mode) mode = SCAN_VSB; if (0 != start_scan(scan_mode, channel_list, epg, progress_cb, progress_context)) return -1; if (wait_for_results) { count += get_scan_results(true, chandump_cb, chandump_context); fprintf(stderr, "found %d services\n", count); } return 0; }
void reception::scan () { channels.clear(); channels_list->clear(); progress_bar->setValue(0); progress_bar->setVisible(true); scan_button->setEnabled (false); current_frequency_index = 0; scan_in_progress = true; select_button->setEnabled(false); stop_scan_button->setEnabled(true); std::cout << "reception_thread::run" << std::endl; std::string frontend_path = "/dev/dvb/adapter" + adapter_edit->text ().toStdString () + "/frontend" + frontend_edit->text ().toStdString (); std::cout << "opening " << frontend_path << std::endl; frontendfd = open(frontend_path.c_str (), O_RDONLY|O_RDWR); start_scan (); }
void reception::lock_end () { progress_bar->setValue(progress_bar->value () + 1); assert(scan_thread != 0); scan_thread->exit (); scan_thread->wait (); delete scan_thread; scan_thread = 0; if(current_frequency_index+1 != sizeof(frequencies)/sizeof(frequencies[0]) && !should_stop_scan) { ++current_frequency_index; start_scan (); } else { scan_finished(); } }
void reception::lock_error () { std::cout << "lock_error, trying next " << current_frequency_index << std::endl; progress_bar->setValue(progress_bar->value () + 1); assert(scan_thread != 0); scan_thread->exit (); scan_thread->wait (); delete scan_thread; scan_thread = 0; if(current_frequency_index != sizeof(frequencies)/sizeof(frequencies[0]) && !should_stop_scan) { ++current_frequency_index; start_scan (); } else { scan_finished(); } }
int parse(const char* file, program_t* p) { int r = 0; FILE* fp = NULL; prog = p; prog->file = strdup(file); assert(prog != NULL); if (file != NULL) { fp = fopen(file, "r"); if (fp == NULL) { fprintf(stderr, "Failed to open %s\n", file); return -1; } } else { fp = stdin; file = "<stdin>"; } r = start_scan(fp, file); if (r < 0) { return r; } init_variant(&value); init_variant(&next_value); next_token = scan_token(&next_value); read_program(); return result; }
int Ndb_move_data::move_data(Ndb* ndb) { int ret = 0; Op& op = m_op; Stat& stat = m_stat; stat.rows_moved = 0; // keep rows_total do { const NDB_TICKS now = NdbTick_getCurrentTicks(); ndb_srand((unsigned)now.getUint64()); reset_error(); CHK2(m_source != 0 && m_target != 0, (Error::InvalidState, "source / target not defined")); op.ndb = ndb; CHK1(m_error.code == 0); CHK1(check_tables() == 0); CHK1(start_scan() == 0); while (1) { CHK1(move_batch() == 0); stat.rows_moved += op.rows_in_batch; stat.rows_total += op.rows_in_batch; stat.truncated += op.truncated_in_batch; require(op.end_of_scan == (op.rows_in_batch == 0)); if (op.end_of_scan) break; } CHK1(ret == 0); } while (0); close_op(ndb, ret); return ret; }
SANE_Status sane_start (SANE_Handle handle) { Abaton_Scanner *s = handle; SANE_Status status; /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ calc_parameters (s); if (s->fd < 0) { /* this is the first (and maybe only) pass... */ status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: open of %s failed: %s\n", s->hw->sane.name, sane_strstatus (status)); return status; } } status = wait_ready (s->fd); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: wait_ready() failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = request_sense (s); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "sane_start: request_sense revealed error: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = set_window (s); if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "open: set scan area command failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } s->scanning = SANE_TRUE; s->AbortedByUser = SANE_FALSE; status = start_scan (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; return SANE_STATUS_GOOD; stop_scanner_and_return: s->scanning = SANE_FALSE; s->AbortedByUser = SANE_FALSE; return status; }
void* tune::scan_thread() { if (!is_scan()) { scan_progress_t progress; progress.total = (unsigned int)scan_channel_list.size(), progress.current = 0, progress.physical_channel = 0, state |= TUNE_STATE_SCAN; feeder.parser.set_scan_mode(true); feeder.parser.set_epg_mode(scan_epg); for (channel_map::const_iterator iter = scan_channel_list.begin(); iter != scan_channel_list.end(); ++iter) { unsigned int channel = iter->first; progress.current++; progress.physical_channel = channel; if (f_kill_thread) break; #if 0 map_chan_to_ts_id::const_iterator iter = channels.find(channel); if (iter != channels.end()) { #else if (channels.count(channel)) { #endif fprintf(stderr, "ALREADY SCANNED CHANNEL %d\n", channel); continue; } fprintf(stderr, "scan channel %d...\n", channel); if (scan_progress_cb) scan_progress_cb(scan_progress_context, &progress); if ((!f_kill_thread) && ((tune_channel((scan_mode == SCAN_VSB) ? DVBTEE_VSB_8 : DVBTEE_QAM_256, channel)) && (wait_for_lock_or_timeout(2000)))) { if (f_kill_thread) break; switch (fe_type) { default: case DVBTEE_FE_ATSC: feeder.parser.set_channel_info(channel, (scan_mode == SCAN_VSB) ? atsc_vsb_chan_to_freq(channel) : atsc_qam_chan_to_freq(channel), (scan_mode == SCAN_VSB) ? "8VSB" : "QAM_256"); break; case DVBTEE_FE_OFDM: feeder.parser.set_channel_info(channel, dvbt_chan_to_freq(channel), ((channel <= 12) ? "INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO" : "INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_AUTO:FEC_AUTO:QAM_AUTO:TRANSMISSION_MODE_AUTO:GUARD_INTERVAL_AUTO:HIERARCHY_AUTO")); break; } if (0 == start_feed()) { int timeout = (scan_epg) ? 16 : (fe_type == DVBTEE_FE_ATSC) ? 4 : 12; while ((!f_kill_thread) && (timeout)) { if (scan_epg) feeder.wait_for_epg(1000); else feeder.wait_for_psip(1000); timeout--; } stop_feed(); channels[channel] = feeder.parser.get_ts_id(); } // else what if we cant start the feed??? } } close_fe(); scan_complete = true; state &= ~TUNE_STATE_SCAN; } pthread_exit(NULL); } #define CHAR_CMD_COMMA "," int tune::start_scan(unsigned int mode, char *channel_list, bool epg, scan_progress_callback progress_cb, void *progress_context) { char *save; char *item = strtok_r(channel_list, CHAR_CMD_COMMA, &save); scan_channel_list.clear(); if (item) while (item) { #if 0 if (!item) item = channel_list; #endif scan_channel_list[atoi(item)] = false; item = strtok_r(NULL, CHAR_CMD_COMMA, &save); } else scan_channel_list[atoi(channel_list)] = false; return start_scan(mode, epg, progress_cb, progress_context); }
SANE_Status sane_start (SANE_Handle handle) { Tamarack_Scanner *s = handle; SANE_Status status; int fds[2]; /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ status = sane_get_parameters (s, 0); if (status != SANE_STATUS_GOOD) return status; if (s->fd < 0) { /* translate options into s->mode for convenient access: */ s->mode = make_mode (s->val[OPT_MODE].s); if (s->mode == TRUECOLOR) { if (s->val[OPT_PREVIEW].w && s->val[OPT_GRAY_PREVIEW].w) { /* Force gray-scale mode when previewing. */ s->mode = GREYSCALE; s->params.format = SANE_FRAME_GRAY; s->params.bytes_per_line = s->params.pixels_per_line; s->params.last_frame = SANE_TRUE; } } status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0); if (status != SANE_STATUS_GOOD) { DBG(1, "open: open of %s failed: %s\n", s->hw->sane.name, sane_strstatus (status)); return status; } } status = wait_ready (s->fd); if (status != SANE_STATUS_GOOD) { DBG(1, "open: wait_ready() failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = scan_area_and_windows (s); if (status != SANE_STATUS_GOOD) { DBG(1, "open: set scan area command failed: %s\n", sane_strstatus (status)); goto stop_scanner_and_return; } status = mode_select (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; s->scanning = SANE_TRUE; status = start_scan (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; status = get_image_status (s); if (status != SANE_STATUS_GOOD) goto stop_scanner_and_return; s->line = 0; if (pipe (fds) < 0) return SANE_STATUS_IO_ERROR; s->pipe = fds[0]; s->reader_pipe = fds[1]; s->reader_pid = sanei_thread_begin (reader_process, (void *) s); if (sanei_thread_is_forked()) close (s->reader_pipe); return SANE_STATUS_GOOD; stop_scanner_and_return: do_cancel (s); return status; }
static int stdin_process(struct data_source *ds){ read(ds->fd, &cmd, 1); switch (cmd){ case 'a': memcpy(device_addr, pts_addr, 6); log_info("USER:\'%c\'", cmd); printf("Establish HFP service level connection to PTS module %s...\n", bd_addr_to_str(device_addr)); hfp_ag_establish_service_level_connection(device_addr); break; case 'A': log_info("USER:\'%c\'", cmd); printf("Release HFP service level connection.\n"); hfp_ag_release_service_level_connection(device_addr); break; case 'z': memcpy(device_addr, speaker_addr, 6); log_info("USER:\'%c\'", cmd); printf("Establish HFP service level connection to %s...\n", bd_addr_to_str(device_addr)); hfp_ag_establish_service_level_connection(device_addr); break; case 'Z': log_info("USER:\'%c\'", cmd); printf("Release HFP service level connection to %s...\n", bd_addr_to_str(device_addr)); hfp_ag_release_service_level_connection(device_addr); break; case 'b': log_info("USER:\'%c\'", cmd); printf("Establish Audio connection %s...\n", bd_addr_to_str(device_addr)); hfp_ag_establish_audio_connection(device_addr); break; case 'B': log_info("USER:\'%c\'", cmd); printf("Release Audio connection.\n"); hfp_ag_release_audio_connection(device_addr); break; case 'c': log_info("USER:\'%c\'", cmd); printf("Simulate incoming call from 1234567\n"); hfp_ag_set_clip(129, "1234567"); hfp_ag_incoming_call(); break; case 'm': log_info("USER:\'%c\'", cmd); printf("Simulate incoming call from 7654321\n"); hfp_ag_set_clip(129, "7654321"); hfp_ag_incoming_call(); break; case 'C': log_info("USER:\'%c\'", cmd); printf("Simulate terminate call\n"); hfp_ag_call_dropped(); break; case 'd': log_info("USER:\'%c\'", cmd); printf("Report AG failure\n"); hfp_ag_report_extended_audio_gateway_error_result_code(device_addr, HFP_CME_ERROR_AG_FAILURE); break; case 'e': log_info("USER:\'%c\'", cmd); printf("Answer call on AG\n"); hfp_ag_answer_incoming_call(); break; case 'E': log_info("USER:\'%c\'", cmd); printf("Reject call on AG\n"); hfp_ag_terminate_call(); break; case 'f': log_info("USER:\'%c\'", cmd); printf("Disable cellular network\n"); hfp_ag_set_registration_status(0); break; case 'F': log_info("USER:\'%c\'", cmd); printf("Enable cellular network\n"); hfp_ag_set_registration_status(1); break; case 'g': log_info("USER:\'%c\'", cmd); printf("Set signal strength to 0\n"); hfp_ag_set_signal_strength(0); break; case 'G': log_info("USER:\'%c\'", cmd); printf("Set signal strength to 5\n"); hfp_ag_set_signal_strength(5); break; case 'h': log_info("USER:\'%c\'", cmd); printf("Disable roaming\n"); hfp_ag_set_roaming_status(0); break; case 'H': log_info("USER:\'%c\'", cmd); printf("Enable roaming\n"); hfp_ag_set_roaming_status(1); break; case 'i': log_info("USER:\'%c\'", cmd); printf("Set battery level to 3\n"); hfp_ag_set_battery_level(3); break; case 'I': log_info("USER:\'%c\'", cmd); printf("Set battery level to 5\n"); hfp_ag_set_battery_level(5); break; case 'j': log_info("USER:\'%c\'", cmd); printf("Answering call on remote side\n"); hfp_ag_outgoing_call_established(); break; case 'r': log_info("USER:\'%c\'", cmd); printf("Disable in-band ring tone\n"); hfp_ag_set_use_in_band_ring_tone(0); break; case 'k': log_info("USER:\'%c\'", cmd); printf("Memory 1 cleared\n"); memory_1_enabled = 0; break; case 'K': log_info("USER:\'%c\'", cmd); printf("Memory 1 set\n"); memory_1_enabled = 1; break; case 'l': log_info("USER:\'%c\'", cmd); printf("Last dialed number cleared\n"); hfp_ag_clear_last_dialed_number(); break; case 'L': log_info("USER:\'%c\'", cmd); printf("Outgoing call connected, ringing\n"); hfp_ag_outgoing_call_ringing(); break; case 'n': log_info("USER:\'%c\'", cmd); printf("Disable Voice Recognition\n"); hfp_ag_activate_voice_recognition(device_addr, 0); break; case 'N': log_info("USER:\'%c\'", cmd); printf("Enable Voice Recognition\n"); hfp_ag_activate_voice_recognition(device_addr, 1); break; case 'o': log_info("USER:\'%c\'", cmd); printf("Set speaker gain to 0 (minimum)\n"); hfp_ag_set_speaker_gain(device_addr, 0); break; case 'O': log_info("USER:\'%c\'", cmd); printf("Set speaker gain to 9 (default)\n"); hfp_ag_set_speaker_gain(device_addr, 9); break; case 'p': log_info("USER:\'%c\'", cmd); printf("Set speaker gain to 12 (higher)\n"); hfp_ag_set_speaker_gain(device_addr, 12); break; case 'P': log_info("USER:\'%c\'", cmd); printf("Set speaker gain to 15 (maximum)\n"); hfp_ag_set_speaker_gain(device_addr, 15); break; case 'q': log_info("USER:\'%c\'", cmd); printf("Set microphone gain to 0\n"); hfp_ag_set_microphone_gain(device_addr, 0); break; case 'Q': log_info("USER:\'%c\'", cmd); printf("Set microphone gain to 9\n"); hfp_ag_set_microphone_gain(device_addr, 9); break; case 's': log_info("USER:\'%c\'", cmd); printf("Set microphone gain to 12\n"); hfp_ag_set_microphone_gain(device_addr, 12); break; case 'S': log_info("USER:\'%c\'", cmd); printf("Set microphone gain to 15\n"); hfp_ag_set_microphone_gain(device_addr, 15); break; case 'R': log_info("USER:\'%c\'", cmd); printf("Enable in-band ring tone\n"); hfp_ag_set_use_in_band_ring_tone(1); break; case 't': log_info("USER:\'%c\'", cmd); printf("Terminate HCI connection.\n"); gap_disconnect(handle); break; case 'u': log_info("USER:\'%c\'", cmd); printf("Join held call\n"); hfp_ag_join_held_call(); break; case 'v': start_scan(); break; case 'w': log_info("USER:\'%c\'", cmd); printf("AG: Put incoming call on hold (Response and Hold)\n"); hfp_ag_hold_incoming_call(); break; case 'x': log_info("USER:\'%c\'", cmd); printf("AG: Accept held incoming call (Response and Hold)\n"); hfp_ag_accept_held_incoming_call(); break; case 'X': log_info("USER:\'%c\'", cmd); printf("AG: Reject held incoming call (Response and Hold)\n"); hfp_ag_reject_held_incoming_call(); break; default: show_usage(); break; } return 0; }
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ //static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t addr; int i; int index; int numResponses; // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = hci_event_packet_get_type(packet); switch(state){ case INIT: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI state = W4_INQUIRY_MODE_COMPLETE; } break; case W4_INQUIRY_MODE_COMPLETE: switch(event){ case HCI_EVENT_COMMAND_COMPLETE: if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_write_inquiry_mode)) { start_scan(); state = ACTIVE; } break; case HCI_EVENT_COMMAND_STATUS: if (HCI_EVENT_IS_COMMAND_STATUS(packet, hci_write_inquiry_mode)) { printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]); start_scan(); state = ACTIVE; } break; default: break; } break; case ACTIVE: switch(event){ case HCI_EVENT_INQUIRY_RESULT: case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{ numResponses = hci_event_inquiry_result_get_num_responses(packet); int offset = 3; for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ reverse_bd_addr(&packet[offset], addr); offset += 6; index = getDeviceIndexForAddress(addr); if (index >= 0) continue; // already in our list memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = packet[offset]; offset += 1; if (event == HCI_EVENT_INQUIRY_RESULT){ offset += 2; // Reserved + Reserved devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = 0; } else { offset += 1; // Reserved devices[deviceCount].classOfDevice = little_endian_read_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = little_endian_read_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = packet[offset]; offset += 1; } devices[deviceCount].state = REMOTE_NAME_REQUEST; printf("Device found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, devices[deviceCount].clockOffset, devices[deviceCount].rssi); deviceCount++; } break; } case HCI_EVENT_INQUIRY_COMPLETE: for (i=0;i<deviceCount;i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; case DAEMON_EVENT_REMOTE_NAME_CACHED: reverse_bd_addr(&packet[3], addr); printf("Cached remote name for %s: '%s'\n", bd_addr_to_str(addr), &packet[9]); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: reverse_bd_addr(&packet[3], addr); index = getDeviceIndexForAddress(addr); if (index >= 0) { if (packet[2] == 0) { printf("Name: '%s'\n", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; } else { printf("Failed to get name: page timeout\n"); } } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; default: break; } break; default: break; } }
static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t addr; int i; int numResponses; // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = packet[0]; switch(state){ case INIT: if (packet[2] == HCI_STATE_WORKING) { hci_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI state = W4_INQUIRY_MODE_COMPLETE; } break; case W4_INQUIRY_MODE_COMPLETE: if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { start_scan(); state = ACTIVE; } break; case ACTIVE: switch(event){ case HCI_EVENT_INQUIRY_RESULT: case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI:{ numResponses = packet[2]; int offset = 3; for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ bt_flip_addr(addr, &packet[offset]); offset += 6; int index = getDeviceIndexForAddress(addr); if (index >= 0) continue; // already in our list memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = packet[offset]; offset += 1; if (event == HCI_EVENT_INQUIRY_RESULT){ offset += 2; // Reserved + Reserved devices[deviceCount].classOfDevice = READ_BT_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = READ_BT_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = 0; } else { offset += 1; // Reserved devices[deviceCount].classOfDevice = READ_BT_24(packet, offset); offset += 3; devices[deviceCount].clockOffset = READ_BT_16(packet, offset) & 0x7fff; offset += 2; devices[deviceCount].rssi = packet[offset]; offset += 1; } devices[deviceCount].state = BONDING_REQUEST; printf("Device found: %s with COD: 0x%06x, pageScan %d, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, devices[deviceCount].clockOffset, devices[deviceCount].rssi); deviceCount++; } break; } case HCI_EVENT_INQUIRY_COMPLETE: continue_bonding(); break; case GAP_DEDICATED_BONDING_COMPLETED: // data: event(8), len(8), status (8), bd_addr(48) printf("GAP Dedicated Bonding Complete, status %u\n", packet[2]); bt_flip_addr(addr, &packet[3]); int index = getDeviceIndexForAddress(addr); if (index >= 0) { devices[index].state = BONDING_COMPLETED; } continue_bonding(); break; default: break; } break; default: break; } }
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ //static void packet_handler (uint8_t packet_type, uint8_t *packet, uint16_t size){ bd_addr_t addr; int i; int numResponses; // printf("packet_handler: pt: 0x%02x, packet[0]: 0x%02x\n", packet_type, packet[0]); if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = packet[0]; switch(state){ case INIT: if (packet[2] == HCI_STATE_WORKING) { bt_send_cmd(&hci_write_inquiry_mode, 0x01); // with RSSI state = W4_INQUIRY_MODE_COMPLETE; } break; case W4_INQUIRY_MODE_COMPLETE: switch(event){ case HCI_EVENT_COMMAND_COMPLETE: if ( COMMAND_COMPLETE_EVENT(packet, hci_write_inquiry_mode) ) { start_scan(); state = ACTIVE; } break; case HCI_EVENT_COMMAND_STATUS: if ( COMMAND_STATUS_EVENT(packet, hci_write_inquiry_mode) ) { printf("Ignoring error (0x%x) from hci_write_inquiry_mode.\n", packet[2]); start_scan(); state = ACTIVE; } break; default: break; } break; case ACTIVE: switch(event){ case HCI_EVENT_INQUIRY_RESULT: case HCI_EVENT_INQUIRY_RESULT_WITH_RSSI: numResponses = packet[2]; for (i=0; i<numResponses && deviceCount < MAX_DEVICES;i++){ bt_flip_addr(addr, &packet[3+i*6]); int index = getDeviceIndexForAddress(addr); if (index >= 0) continue; memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = packet [3 + numResponses*(6) + i*1]; if (event == HCI_EVENT_INQUIRY_RESULT){ devices[deviceCount].classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1+1) + i*3); devices[deviceCount].clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+1+3) + i*2) & 0x7fff; devices[deviceCount].rssi = 0; } else { devices[deviceCount].classOfDevice = READ_BT_24(packet, 3 + numResponses*(6+1+1) + i*3); devices[deviceCount].clockOffset = READ_BT_16(packet, 3 + numResponses*(6+1+1+3) + i*2) & 0x7fff; devices[deviceCount].rssi = packet [3 + numResponses*(6+1+1+3+2) + i*1]; } devices[deviceCount].state = REMOTE_NAME_REQUEST; printf("Device found: %s with COD: 0x%06x, pageScan %u, clock offset 0x%04x, rssi 0x%02x\n", bd_addr_to_str(addr), devices[deviceCount].classOfDevice, devices[deviceCount].pageScanRepetitionMode, devices[deviceCount].clockOffset, devices[deviceCount].rssi); deviceCount++; } break; case HCI_EVENT_INQUIRY_COMPLETE: for (i=0;i<deviceCount;i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; case BTSTACK_EVENT_REMOTE_NAME_CACHED: bt_flip_addr(addr, &packet[3]); printf("Cached remote name for %s: '%s'\n", bd_addr_to_str(addr), &packet[9]); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: bt_flip_addr(addr, &packet[3]); int index = getDeviceIndexForAddress(addr); if (index >= 0) { if (packet[2] == 0) { printf("Name: '%s'\n", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; } else { printf("Failed to get name: page timeout\n"); } } if (has_more_remote_name_requests()){ do_next_remote_name_request(); break; } start_scan(); break; default: break; } break; default: break; } }
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ UNUSED(channel); UNUSED(size); bd_addr_t addr; int i; int index; if (packet_type != HCI_EVENT_PACKET) return; uint8_t event = hci_event_packet_get_type(packet); switch(state){ /* @text In INIT, an inquiry scan is started, and the application transits to * ACTIVE state. */ case INIT: switch(event){ case BTSTACK_EVENT_STATE: if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING){ start_scan(); state = ACTIVE; } break; default: break; } break; /* @text In ACTIVE, the following events are processed: * - GAP Inquiry result event: BTstack provides a unified inquiry result that contain * Class of Device (CoD), page scan mode, clock offset. RSSI and name (from EIR) are optional. * - Inquiry complete event: the remote name is requested for devices without a fetched * name. The state of a remote name can be one of the following: * REMOTE_NAME_REQUEST, REMOTE_NAME_INQUIRED, or REMOTE_NAME_FETCHED. * - Remote name request complete event: the remote name is stored in the table and the * state is updated to REMOTE_NAME_FETCHED. The query of remote names is continued. */ case ACTIVE: switch(event){ case GAP_EVENT_INQUIRY_RESULT: if (deviceCount >= MAX_DEVICES) break; // already full gap_event_inquiry_result_get_bd_addr(packet, addr); index = getDeviceIndexForAddress(addr); if (index >= 0) break; // already in our list memcpy(devices[deviceCount].address, addr, 6); devices[deviceCount].pageScanRepetitionMode = gap_event_inquiry_result_get_page_scan_repetition_mode(packet); devices[deviceCount].clockOffset = gap_event_inquiry_result_get_clock_offset(packet); // print info printf("Device found: %s ", bd_addr_to_str(addr)); printf("with COD: 0x%06x, ", (unsigned int) gap_event_inquiry_result_get_class_of_device(packet)); printf("pageScan %d, ", devices[deviceCount].pageScanRepetitionMode); printf("clock offset 0x%04x",devices[deviceCount].clockOffset); if (gap_event_inquiry_result_get_rssi_available(packet)){ printf(", rssi %d dBm", (int8_t) gap_event_inquiry_result_get_rssi(packet)); } if (gap_event_inquiry_result_get_name_available(packet)){ char name_buffer[240]; int name_len = gap_event_inquiry_result_get_name_len(packet); memcpy(name_buffer, gap_event_inquiry_result_get_name(packet), name_len); name_buffer[name_len] = 0; printf(", name '%s'", name_buffer); devices[deviceCount].state = REMOTE_NAME_FETCHED;; } else { devices[deviceCount].state = REMOTE_NAME_REQUEST; } printf("\n"); deviceCount++; break; case GAP_EVENT_INQUIRY_COMPLETE: for (i=0;i<deviceCount;i++) { // retry remote name request if (devices[i].state == REMOTE_NAME_INQUIRED) devices[i].state = REMOTE_NAME_REQUEST; } continue_remote_names(); break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: reverse_bd_addr(&packet[3], addr); index = getDeviceIndexForAddress(addr); if (index >= 0) { if (packet[2] == 0) { printf("Name: '%s'\n", &packet[9]); devices[index].state = REMOTE_NAME_FETCHED; } else { printf("Failed to get name: page timeout\n"); } } continue_remote_names(); break; default: break; } break; default: break; } }
int main(int argc, char **argv) { int scan_length = 8, truncate = 0, verbose = -1, flush = 0; FILE * out_file = stdout; int dev_id, dev_sd, opt, rc; bluetrax_inquiry_complete_t record; static struct option options[] = { {"truncate", no_argument, 0, 't'}, {"file", required_argument, 0, 'f'}, {"length", required_argument, 0, 'l'}, {"verbose", optional_argument, 0, 'v'}, {"flush", no_argument, 0, 'u'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; while ((opt=getopt_long(argc, argv, "+f:tl:vuh", options, NULL)) != -1) { switch (opt) { case 't': if (out_file != stdout) { syslog(LOG_ERR, "--truncate must be passed before --file"); exit(EXIT_FAILURE); } truncate = 1; break; case 'f': if (truncate) { out_file = fopen(optarg, "w"); } else { out_file = fopen(optarg, "a"); } if (out_file == NULL) { syslog(LOG_ERR, "failed to open output file: %m"); exit(EXIT_FAILURE); } break; case 'l': scan_length = atoi(optarg); if (scan_length < 1 || scan_length > 100) { fprintf(stderr, "bad scan length: %s\n", optarg); exit(EXIT_FAILURE); } break; case 'v': if (optarg) { verbose = 0; } else { verbose = 1; } break; case 'u': flush = 1; break; case 'h': default: print_usage(argv); exit(EXIT_SUCCESS); } } argc -= optind; argv += optind; if (argc != 0) { print_usage(argv); exit(EXIT_FAILURE); } /* use syslog for logging */ openlog(NULL, LOG_PID | LOG_PERROR | LOG_CONS, LOG_USER); switch(verbose) { case -1: setlogmask(LOG_UPTO(LOG_NOTICE)); break; case 0: setlogmask(LOG_UPTO(LOG_ERR)); break; /* else: verbose output: log everything */ } if (!setup_signals()) { syslog(LOG_ERR, "setup_signals: %m"); return EXIT_FAILURE; } /* use the default bluetooth device */ dev_id = hci_get_route(NULL); if (dev_id < 0) { syslog(LOG_ERR, "hci_get_route: %m"); return EXIT_FAILURE; } dev_sd = hci_open_dev(dev_id); if (dev_sd < 0) { syslog(LOG_ERR, "hci_open_dev: %m"); return EXIT_FAILURE; } rc = start_scan(dev_sd, scan_length); if (rc == EXIT_SUCCESS) { /* write a fake 'complete' record with the start time of the first scan */ gettimeofday(&record.time, NULL); rc = write_inquiry_complete(out_file, record); if (rc == EXIT_SUCCESS) rc = run_scan(dev_sd, scan_length, flush, out_file); stop_scan(dev_sd); } /* recovery: * restart bluetooth * I've seen toggling inqmode bring it back to life on my laptop after a * period in which nothing was being detected; I've now seem this twice * on my netbook: run * hciconfig hci0 inqmode 0 * hciconfig hci0 inqmode 1 * and it seems to be happy again. It was detecting only some devices (a GPS * logger but not my phone or computer) */ hci_close_dev(dev_sd); return rc; }
int stdin_process(struct data_source *ds){ char buffer; read(ds->fd, &buffer, 1); // passkey input if (ui_digits_for_passkey){ if (buffer < '0' || buffer > '9') return 0; printf("%c", buffer); fflush(stdout); ui_passkey = ui_passkey * 10 + buffer - '0'; ui_digits_for_passkey--; if (ui_digits_for_passkey == 0){ printf("\nSending Passkey '%06u'\n", ui_passkey); hci_send_cmd(&hci_user_passkey_request_reply, remote, ui_passkey); } return 0; } if (ui_chars_for_pin){ printf("%c", buffer); fflush(stdout); if (buffer == '\n'){ printf("\nSending Pin '%s'\n", ui_pin); hci_send_cmd(&hci_pin_code_request_reply, remote, ui_pin_offset, ui_pin); } else { ui_pin[ui_pin_offset++] = buffer; } return 0; } switch (buffer){ case 'c': gap_connectable = 0; hci_connectable_control(0); show_usage(); break; case 'C': gap_connectable = 1; hci_connectable_control(1); show_usage(); break; case 'd': gap_discoverable = 0; hci_discoverable_control(0); show_usage(); break; case 'D': gap_discoverable = 1; hci_discoverable_control(1); show_usage(); break; case 'b': gap_bondable = 0; // gap_set_bondable_mode(0); update_auth_req(); show_usage(); break; case 'B': gap_bondable = 1; // gap_set_bondable_mode(1); update_auth_req(); show_usage(); break; case 'm': gap_mitm_protection = 0; update_auth_req(); show_usage(); break; case 'M': gap_mitm_protection = 1; update_auth_req(); show_usage(); break; case '<': gap_dedicated_bonding_mode = 0; update_auth_req(); show_usage(); break; case '>': gap_dedicated_bonding_mode = 1; update_auth_req(); show_usage(); break; case 'e': gap_io_capabilities = "IO_CAPABILITY_DISPLAY_ONLY"; hci_ssp_set_io_capability(IO_CAPABILITY_DISPLAY_ONLY); show_usage(); break; case 'f': gap_io_capabilities = "IO_CAPABILITY_DISPLAY_YES_NO"; hci_ssp_set_io_capability(IO_CAPABILITY_DISPLAY_YES_NO); show_usage(); break; case 'g': gap_io_capabilities = "IO_CAPABILITY_NO_INPUT_NO_OUTPUT"; hci_ssp_set_io_capability(IO_CAPABILITY_NO_INPUT_NO_OUTPUT); show_usage(); break; case 'h': gap_io_capabilities = "IO_CAPABILITY_KEYBOARD_ONLY"; hci_ssp_set_io_capability(IO_CAPABILITY_KEYBOARD_ONLY); show_usage(); break; case 'i': start_scan(); break; case 'j': printf("Start dedicated bonding to %s using MITM %u\n", bd_addr_to_str(remote), gap_mitm_protection); gap_dedicated_bonding(remote, gap_mitm_protection); break; case 'z': printf("Start dedicated bonding to %s using legacy pairing\n", bd_addr_to_str(remote)); gap_dedicated_bonding(remote, gap_mitm_protection); break; case 'y': printf("Disabling SSP for this session\n"); hci_send_cmd(&hci_write_simple_pairing_mode, 0); break; case 'k': printf("Start SDP query for SPP service\n"); sdp_query_rfcomm_channel_and_name_for_uuid(remote_rfcomm, 0x1101); break; case 't': printf("Terminate connection with handle 0x%04x\n", handle); hci_send_cmd(&hci_disconnect, handle, 0x13); // remote closed connection break; case 'p': printf("Creating HCI Connection to %s\n", bd_addr_to_str(remote)); hci_send_cmd(&hci_create_connection, remote, hci_usable_acl_packet_types(), 0, 0, 0, 1); break; // printf("Creating L2CAP Connection to %s, PSM SDP\n", bd_addr_to_str(remote)); // l2cap_create_channel_internal(NULL, packet_handler, remote, PSM_SDP, 100); // break; // case 'u': // printf("Creating L2CAP Connection to %s, PSM 3\n", bd_addr_to_str(remote)); // l2cap_create_channel_internal(NULL, packet_handler, remote, 3, 100); // break; case 'q': printf("Send L2CAP Data\n"); l2cap_send_internal(local_cid, (uint8_t *) "0123456789", 10); break; case 'r': printf("Send L2CAP ECHO Request\n"); l2cap_send_echo_request(handle, (uint8_t *) "Hello World!", 13); break; case 's': printf("L2CAP Channel Closed\n"); l2cap_disconnect_internal(local_cid, 0); break; case 'x': printf("Outgoing L2CAP Channels to SDP will also require SSP\n"); l2cap_require_security_level_2_for_outgoing_sdp(); break; case 'l': printf("Creating RFCOMM Channel to %s #%u\n", bd_addr_to_str(remote_rfcomm), rfcomm_channel_nr); rfcomm_create_channel_internal(NULL, remote_rfcomm, rfcomm_channel_nr); break; case 'n': printf("Send RFCOMM Data\n"); // mtu < 60 rfcomm_send_internal(rfcomm_channel_id, (uint8_t *) "012345678901234567890123456789012345678901234567890123456789", mtu); break; case 'u': printf("Sending RLS indicating framing error\n"); // mtu < 60 rfcomm_send_local_line_status(rfcomm_channel_id, 9); break; case 'v': printf("Sending RPN CMD to select 115200 baud\n"); // mtu < 60 rfcomm_send_port_configuration(rfcomm_channel_id, RPN_BAUD_115200, RPN_DATA_BITS_8, RPN_STOP_BITS_1_0, RPN_PARITY_NONE, 0); break; case 'w': printf("Sending RPN REQ to query remote port settings\n"); // mtu < 60 rfcomm_query_port_configuration(rfcomm_channel_id); break; case 'o': printf("RFCOMM Channel Closed\n"); rfcomm_disconnect_internal(rfcomm_channel_id); rfcomm_channel_id = 0; break; case '+': printf("Initiate SSP on current connection\n"); gap_request_security_level(handle, LEVEL_2); break; case '*': printf("Sending SSP User Confirmation for %s\n", bd_addr_to_str(remote)); hci_send_cmd(&hci_user_confirmation_request_reply, remote); break; case '=': printf("Deleting Link Key for %s\n", bd_addr_to_str(remote)); hci_drop_link_key_for_bd_addr(remote); break; case 'U': printf("Sending UCD data on handle 0x%04x\n", handle); send_ucd_packet(); break; case 'Q': printf("Closing HCI Connection to handle 0x%04x\n", handle); gap_disconnect(handle); break; default: show_usage(); break; } return 0; }