/* * (c) 2013 Nils Faerber, Siegen, Germany * licensed under GPLv2 */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/select.h> #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h> #include <fcntl.h> #include <bluetooth/bluetooth.h> #include <bluetooth/l2cap.h> typedef enum { CMD_NULL = 0, CMD_INVAL, CMD_QUIT, } cmd_t; // replace "markups" with appropr. chars char *parse_buffer(char *inbuf, int *cmd) { int i,o; static char outbuf[240]; memset(outbuf,0,240); *cmd = CMD_NULL; // if a line starts with a \ then it is an internal command if (inbuf[0] == '\\') { switch (inbuf[1]) { case 'q': *cmd = CMD_QUIT; break; default: *cmd = CMD_INVAL; break; } return NULL; } o=0; for (i=0; i<strlen(inbuf); i++) { if (inbuf[i] == '\\') { i++; if (inbuf[i] == 'n') outbuf[o++] = '\n'; } else outbuf[o++] = inbuf[i]; } return outbuf; } int main(int argc, char **argv) { struct sockaddr_l2 addr = { 0 }; int s, status, len, i, cmd; char buf[255]; char dest[18]; char *out; fd_set infds; fd_set efds; if (argc < 2) { fprintf(stderr, "usage: %s <bt_addr>\n", argv[0]); exit(2); } strncpy(dest, argv[1], 18); // allocate a socket s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); // set the connection parameters (who to connect to) addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(0x1001); str2ba( dest, &addr.l2_bdaddr ); // connect to server status = connect(s, (struct sockaddr *)&addr, sizeof(addr)); // send a message if ( status != 0 ) { perror("open socket"); close(s); return -1; } fprintf(stderr, "connected\n"); if (fcntl(0, F_SETFL, O_NONBLOCK) != 0) perror("stdin nonblock"); if (fcntl(s, F_SETFL, O_NONBLOCK) != 0) perror("socket nonblock"); while (1) { FD_ZERO(&infds); FD_SET(s, &infds); FD_SET(0, &infds); FD_ZERO(&efds); FD_SET(s, &efds); status = select(s+1, &infds, NULL, &efds, NULL); // fprintf(stderr, "select = %d\n", status); if ( status > 0) { if (FD_ISSET(0, &infds)) { len = read(0, buf, 240); if (len > 0) { // status = write(s, buf, len); out = parse_buffer(buf, &cmd); if (cmd != CMD_NULL) { if (cmd == CMD_QUIT) { close(s); exit(0); } } else { len = strlen(out); status = write(s, out, len); if (status < 0) perror("write"); fsync(s); } } } else if (FD_ISSET(s, &infds)) { len = read(s, buf, 240); // fprintf(stderr, "read = %d\n", len); for (i=0; i<len; i++) fprintf(stderr, "%c", buf[i]); // fprintf(stderr, "\n"); } else if (FD_ISSET(s, &efds)) { fprintf(stderr, "e on socket\n"); } else fprintf(stderr, "hu?"); } else perror("select"); }; close(s); return 0; }