#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Util/Timer.h" /* Defaults */ static bdaddr_t bdaddr; static int size = 44; static int ident = 200; static int delay = 1; static int count = -1; static int timeout = 10; static int reverse = 0; static int verify = 0; /* Stats */ static int sent_pkt = 0; static int recv_pkt = 0; static float tv2fl(struct timeval tv) { return (float)(tv.tv_sec*1000.0) + (float)(tv.tv_usec/1000.0); } static void stat(int /*sig*/) { int loss = sent_pkt ? (float)((sent_pkt-recv_pkt)/(sent_pkt/100.0)) : 0; printf("%d sent, %d received, %d%% loss\n", sent_pkt, recv_pkt, loss); exit(0); } static void ping(const char* svr) { struct sigaction sa; struct sockaddr_l2 addr; socklen_t optlen; unsigned char *send_buf; unsigned char *recv_buf; char str[18]; int i, sk, lost; uint8_t id; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stat; sigaction(SIGINT, &sa, NULL); send_buf = static_cast(malloc(L2CAP_CMD_HDR_SIZE + size)); recv_buf = static_cast(malloc(L2CAP_CMD_HDR_SIZE + size)); if (!send_buf || !recv_buf) { perror("Can't allocate buffer"); exit(1); } /* Create socket */ sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); if (sk < 0) { perror("Can't create socket"); goto error; } /* Bind to local address */ memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, &bdaddr); if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't bind socket"); goto error; } /* Connect to remote device */ memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; str2ba(svr, &addr.l2_bdaddr); if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't connect"); goto error; } /* Get local address */ memset(&addr, 0, sizeof(addr)); optlen = sizeof(addr); if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { perror("Can't get local address"); goto error; } ba2str(&addr.l2_bdaddr, str); printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize send buffer */ for (i = 0; i < size; i++) send_buf[L2CAP_CMD_HDR_SIZE + i] = (i % 40) + 'A'; id = ident; while (count == -1 || count-- > 0) { struct timeval tv_send, tv_recv, tv_diff; l2cap_cmd_hdr *send_cmd = (l2cap_cmd_hdr *) send_buf; l2cap_cmd_hdr *recv_cmd = (l2cap_cmd_hdr *) recv_buf; /* Build command header */ send_cmd->ident = id; send_cmd->len = htobs(size); if (reverse) send_cmd->code = L2CAP_ECHO_RSP; else send_cmd->code = L2CAP_ECHO_REQ; gettimeofday(&tv_send, NULL); /* Send Echo Command */ if (send(sk, send_buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) { perror("Send failed"); goto error; } /* Wait for Echo Response */ lost = 0; while (1) { struct pollfd pf[1]; int err; pf[0].fd = sk; pf[0].events = POLLIN; if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); goto error; } if (!err) { lost = 1; break; } if ((err = recv(sk, recv_buf, L2CAP_CMD_HDR_SIZE + size, 0)) < 0) { perror("Recv failed"); goto error; } if (!err){ printf("Disconnected\n"); goto error; } recv_cmd->len = btohs(recv_cmd->len); /* Check for our id */ if (recv_cmd->ident != id) continue; /* Check type */ if (!reverse && recv_cmd->code == L2CAP_ECHO_RSP) break; if (recv_cmd->code == L2CAP_COMMAND_REJ) { printf("Peer doesn't support Echo packets\n"); goto error; } } sent_pkt++; if (!lost) { recv_pkt++; gettimeofday(&tv_recv, NULL); timersub(&tv_recv, &tv_send, &tv_diff); if (verify) { /* Check payload length */ if (recv_cmd->len != size) { fprintf(stderr, "Received %d bytes, expected %d\n", recv_cmd->len, size); goto error; } /* Check payload */ if (memcmp(&send_buf[L2CAP_CMD_HDR_SIZE], &recv_buf[L2CAP_CMD_HDR_SIZE], size)) { fprintf(stderr, "Response payload different.\n"); goto error; } } printf("%d bytes from %s id %d time %.2fms\n", recv_cmd->len, svr, id - ident, tv2fl(tv_diff)); if (delay) sleep(delay); } else { printf("no response from %s: id %d\n", svr, id - ident); } if (++id > 254) id = ident; } stat(0); free(send_buf); free(recv_buf); return; error: close(sk); free(send_buf); free(recv_buf); exit(1); } void print() { std::cout << "Print" << std::endl; } int main(int /*argc*/, char** /*argv[]*/) { //std::string address = "48:4B:AA:85:30:C5"; //ping(address.c_str()); //address = "d0:c5:f3:84:99:de"; //ping(address.c_str()); PresenceDetection::Util::Timer timer; std::function f_print = print; std::cout << "---" << std::endl; timer.StartContinuous(1000, f_print); timer.Stop(); timer.Wait(); std::cout << "---" << std::endl << std::endl; std::cout << "---" << std::endl; timer.StartContinuous(3000, f_print); timer.Abort(); timer.Wait(); std::cout << "---" << std::endl << std::endl; std::cout << "---" << std::endl; timer.StartContinuous(3000, f_print); sleep(1); timer.Abort(); timer.Wait(); std::cout << "---" << std::endl << std::endl; return 0; }