oswald/linux-bt/l2cap_client.c
2021-02-14 18:03:13 +01:00

147 lines
2.8 KiB
C

/*
* (c) 2013 Nicole 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;
}