void control_reader(const char *path, bool pager) { unsigned char buf[BTSNOOP_MAX_PACKET_SIZE]; uint16_t pktlen; uint32_t format; struct timeval tv; btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT); if (!btsnoop_file) return; format = btsnoop_get_format(btsnoop_file); switch (format) { case BTSNOOP_FORMAT_HCI: case BTSNOOP_FORMAT_UART: case BTSNOOP_FORMAT_SIMULATOR: packet_del_filter(PACKET_FILTER_SHOW_INDEX); break; case BTSNOOP_FORMAT_MONITOR: packet_add_filter(PACKET_FILTER_SHOW_INDEX); break; } if (pager) open_pager(); switch (format) { case BTSNOOP_FORMAT_HCI: case BTSNOOP_FORMAT_UART: case BTSNOOP_FORMAT_MONITOR: while (1) { uint16_t index, opcode; if (!btsnoop_read_hci(btsnoop_file, &tv, &index, &opcode, buf, &pktlen)) break; if (opcode == 0xffff) continue; packet_monitor(&tv, NULL, index, opcode, buf, pktlen); ellisys_inject_hci(&tv, index, opcode, buf, pktlen); } break; case BTSNOOP_FORMAT_SIMULATOR: while (1) { uint16_t frequency; if (!btsnoop_read_phy(btsnoop_file, &tv, &frequency, buf, &pktlen)) break; packet_simulator(&tv, frequency, buf, pktlen); } break; } if (pager) close_pager(); btsnoop_unref(btsnoop_file); }
void analyze_trace(const char *path) { struct btsnoop *btsnoop_file; unsigned long num_packets = 0; uint32_t type; btsnoop_file = btsnoop_open(path, BTSNOOP_FLAG_PKLG_SUPPORT); if (!btsnoop_file) return; type = btsnoop_get_type(btsnoop_file); switch (type) { case BTSNOOP_TYPE_HCI: case BTSNOOP_TYPE_UART: case BTSNOOP_TYPE_MONITOR: break; default: fprintf(stderr, "Unsupported packet format\n"); goto done; } dev_list = queue_new(); if (!dev_list) { fprintf(stderr, "Failed to allocate device list\n"); goto done; } while (1) { unsigned char buf[BTSNOOP_MAX_PACKET_SIZE]; struct timeval tv; uint16_t index, opcode, pktlen; if (!btsnoop_read_hci(btsnoop_file, &tv, &index, &opcode, buf, &pktlen)) break; switch (opcode) { case BTSNOOP_OPCODE_NEW_INDEX: new_index(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_DEL_INDEX: del_index(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_COMMAND_PKT: command_pkt(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_EVENT_PKT: event_pkt(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_ACL_TX_PKT: case BTSNOOP_OPCODE_ACL_RX_PKT: acl_pkt(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_SCO_TX_PKT: case BTSNOOP_OPCODE_SCO_RX_PKT: sco_pkt(&tv, index, buf, pktlen); break; case BTSNOOP_OPCODE_OPEN_INDEX: case BTSNOOP_OPCODE_CLOSE_INDEX: break; default: fprintf(stderr, "Wrong opcode %u\n", opcode); goto done; } num_packets++; } printf("Trace contains %lu packets\n\n", num_packets); queue_destroy(dev_list, dev_destroy); done: btsnoop_unref(btsnoop_file); }