From a69eb10937b57a775a2e46026c6d4f7f6e6c3619 Mon Sep 17 00:00:00 2001 From: Nils Faerber Date: Mon, 25 Jul 2011 02:10:38 +0200 Subject: [PATCH] Break out code for main application and MW handling, add Bluetooth code to self connect RFCOMM --- mw_main.c | 389 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 mw_main.c diff --git a/mw_main.c b/mw_main.c new file mode 100644 index 0000000..5dae442 --- /dev/null +++ b/mw_main.c @@ -0,0 +1,389 @@ +/* + * (c) 2011 Siegen, Germany by Nils Faerber + * + * license LGPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/* +#include +#include +*/ + +#include "metawatch.h" +#include "crc16ccitt.h" + + +void bitmap_test(int mw_fd) +{ + /* a nice checker-board pattern */ + unsigned char checkbuf[24] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + }; + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 31, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 33, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 35, checkbuf, 24); + mw_write_buffer(mw_fd, MW_SCREEN_MODE_IDLE, 0, 37, checkbuf, 24); + + mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); +} + + +void bitmap_read(int mw_fd) +{ + int ffd, ret; + char rbuf[256]; + unsigned int width, height, i, x, y; + unsigned int rowlength; + unsigned char *bmapbuf; + // unsigned char mw_buf[24]; + + ffd = open("test.pbm", O_RDONLY); + if (ffd < 0) { + perror("open"); + return; + }; + ret = read(ffd, rbuf, 3); + if (rbuf[0] != 'P' || rbuf[1] != '4') { + fprintf(stderr, "not a PBM file\n"); + return; + } + memset(rbuf, 0, 256); + i = 0; + do { + ret = read(ffd, (rbuf+i), 1); + } while (!isspace(rbuf[i++])); + width = atoi(rbuf); + + memset(rbuf, 0, 256); + i = 0; + do { + ret = read(ffd, (rbuf+i), 1); + } while (!isspace(rbuf[i++])); + height = atoi(rbuf); + + rowlength = ((width / 8) + 1); + + bmapbuf = malloc(rowlength * height); + + ret = read(ffd, bmapbuf, rowlength * height); + close(ffd); + +#ifdef DEBUG + fprintf(stderr, "row length = %d bytes\n", rowlength); + fprintf(stderr, "bitmap resolution is %d x %d\n", width, height); + fprintf(stderr, "read %d of %d bytes\n", ret, rowlength * height); + fprintf(stderr, "\n"); + for (y=0; y 0) { + if (FD_ISSET(mw_fd, &mfds)) { + rcvd = read(mw_fd, msg_buf, 64); + fprintf(stderr, "read %d bytes:\n", rcvd); + if (rcvd > 0) { + dump_frame(msg_buf, rcvd); + decode_frame(mw_fd, msg_buf, rcvd); + } + }; + if (FD_ISSET(0, &mfds)) { + rcvd = read(0, (cmdline+clinep), 1); + if (rcvd > 0) { + if (cmdline[clinep] == '\r') { + printf("\n"); + cmdline[clinep--] = '\0'; + process_cmd(cmdline, clinep, mw_fd); + clinep = 0; + memset(cmdline, 0, 128); + } else { + clinep++; + if (clinep > 75) + clinep = 75; + printf("\r> %s", cmdline); + fflush(stdout); + } + } + }; + } else + break; + FD_ZERO(&mfds); + FD_SET(0, &mfds); + FD_SET(mw_fd, &mfds); + } while (rcvd > 0); + + return 0; +} + +int open_socket(bdaddr_t *bdaddr, uint8_t channel) +{ + struct sockaddr_rc addr; + int sk, opt; + int f; + + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + fprintf(stderr, "Can't create socket: %s (%d)\n", + strerror(errno), errno); + return -1; + } + +/* + f = 1; + if (setsockopt(sk, SOL_BLUETOOTH, BT_FLUSHABLE, &f, sizeof(f)) < 0) { + fprintf(stderr, "Can't set flushable: %s (%d)\n", + strerror(errno), errno); + return -1; + } +*/ + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, BDADDR_ANY); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't bind socket: %s (%d)\n", + strerror(errno), errno); + close(sk); + return -1; + } + + /* Set link mode */ + opt = 0; + opt |= RFCOMM_LM_MASTER; + opt |= RFCOMM_LM_AUTH; +/* + opt |= RFCOMM_LM_ENCRYPT; + opt |= RFCOMM_LM_SECURE; +*/ + if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + fprintf(stderr, "Can't set RFCOMM link mode: %s (%d)", + strerror(errno), errno); + close(sk); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, bdaddr); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't connect: %s (%d)\n", + strerror(errno), errno); + close(sk); + return -1; + } + + return sk; +} + +void baswap(bdaddr_t *dst, const bdaddr_t *src) +{ + register unsigned char *d = (unsigned char *) dst; + register const unsigned char *s = (const unsigned char *) src; + register int i; + + for (i = 0; i < 6; i++) + d[i] = s[5-i]; +} +int bachk(const char *str) +{ + if (!str) + return -1; + + if (strlen(str) != 17) + return -1; + + while (*str) { + if (!isxdigit(*str++)) + return -1; + + if (!isxdigit(*str++)) + return -1; + + if (*str == 0) + break; + + if (*str++ != ':') + return -1; + } + + return 0; +} + +int str2ba(const char *str, bdaddr_t *ba) +{ + bdaddr_t b; + int i; + + if (bachk(str) < 0) { + memset(ba, 0, sizeof(*ba)); + return -1; + } + + for (i = 0; i < 6; i++, str += 3) + b.b[i] = strtol(str, NULL, 16); + + baswap(ba, &b); + + return 0; +} + +int main(int argc, char **argv) +{ + int mw_fd; + bdaddr_t btaddr; + + if (argc != 2) { + fprintf(stderr, "Usage:\n\t%s \n", argv[0]); + return 1; + }; + + crc16ccitt_init(); + +#if USE_RFCOMM_FILE + mw_fd = open(argv[1], O_RDWR); + if (mw_fd < 0) { + perror("open"); + return 1; + }; +#else + if (str2ba(argv[1], &btaddr)) + return 1; + mw_fd = open_socket(&btaddr, 1); + if (mw_fd < 0) { + return 1; + }; +#endif + + menu(mw_fd); + + fsync(mw_fd); + + close(mw_fd); + + return 0; +}; + -- 2.39.2