/* * (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" #include "mw_utility.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_test2(int mw_fd) { mw_buffer *mwbuf1, *mwbuf2; unsigned char *bbuf; int len, x; mwbuf1 = mw_alloc_pbuffer(96, 66, 1); mwbuf2 = mw_alloc_pbuffer(96, 66, 1); mw_buf_clear(mwbuf1, MW_BLACK); mw_buf_clear(mwbuf2, MW_WHITE); for (x=0; x<66; x++) { //mw_buf_clear(mwbuf1, MW_BLACK); mw_buf_draw_pixel(mwbuf1, x, x, MW_WHITE); mw_dump_mw_buffer(mwbuf1); bbuf = mw_make_mw_buffer(mwbuf1, &len); mw_send_bitmap(mw_fd, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len); mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); getchar(); }; mw_free_pbuffer(mwbuf1); mw_free_pbuffer(mwbuf2); } void text_test(int mw_fd) { mw_buffer *mwbuf; unsigned char *bbuf; int len; mwbuf = mw_alloc_pbuffer(96, 66, 1); mw_buf_clear(mwbuf, MW_BLACK); mw_buf_print(mwbuf, 1, 10, "Font 0", 0, MW_WHITE, MW_BLACK); mw_buf_print(mwbuf, 1, 20, "Font 1", 1, MW_WHITE, MW_BLACK); mw_buf_print(mwbuf, 1, 30, "Font 2", 2, MW_WHITE, MW_BLACK); mw_buf_print(mwbuf, 1, 45, "Big Fat Clipping", 2, MW_BLACK, MW_WHITE); bbuf = mw_make_mw_buffer(mwbuf, &len); mw_send_bitmap(mw_fd, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len); mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); mw_free_pbuffer(mwbuf); } void line_test(int mw_fd) { mw_buffer *mwbuf; unsigned char *bbuf; int len, p; mwbuf = mw_alloc_pbuffer(96, 66, 1); mw_buf_clear(mwbuf, MW_BLACK); for (p=0; p<=96; p+=8) mw_buf_draw_line_bresenham(mwbuf, p, 0, 95-p, 65, MW_WHITE); bbuf = mw_make_mw_buffer(mwbuf, &len); mw_send_bitmap(mw_fd, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len); mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 1); mw_free_pbuffer(mwbuf); } void bitmap_read(int mw_fd) { int ffd, ret; char rbuf[256]; unsigned int width, height, i; #ifdef DEBUG unsigned int x, y; #endif 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 && intopt <=3) mdata[0] = intopt; else mdata[0] = 0; mw_send_frame(mw_fd, MW_GET_INFORMATION_STRING, 0, mdata, 1); } if (strncmp(cmdline, "gdtype", 6) == 0) { mw_send_frame(mw_fd, MW_GET_DEVICE_TYPE, 0, NULL, 0); } if (strncmp(cmdline, "rvbat", 5) == 0) { mw_send_frame(mw_fd, MW_READ_BATTERY_VOLTAGE_MSG, 0, NULL, 0); } if (strncmp(cmdline, "rlight", 6) == 0) { mw_send_frame(mw_fd, MW_READ_LIGHT_SENSOR_MSG, 0, NULL, 0); } if (strncmp(cmdline, "modecfg", 6) == 0) { mw_configure_watch_mode(mw_fd, MW_SCREEN_MODE_IDLE, 0, 4, 1); mw_update_display(mw_fd, MW_SCREEN_MODE_IDLE, 0); } if (strncmp(cmdline, "rbtcfg", 6) == 0) { intopt = cmdline[7]-0x30; mdata[0] = 0; /* idle screen */ mdata[1] = intopt; /* button index */ /* for reading the config those are unnecessary */ mdata[2] = 0; /* button press type */ mdata[3] = 0; /* callback message type */ mdata[4] = 0; /* callback message option */ mw_send_frame(mw_fd, MW_READ_BUTTON_CONFIG, 0, mdata, 5); } if (strncmp(cmdline, "svib", 4) == 0) { mw_set_vibrate_mode(mw_fd, 1, 300, 300, 5); } if (strncmp(cmdline, "tbmp", 4) == 0) { bitmap_test(mw_fd); } if (strncmp(cmdline, "t2bmp", 5) == 0) { bitmap_test2(mw_fd); } if (strncmp(cmdline, "text", 4) == 0) { text_test(mw_fd); } if (strncmp(cmdline, "tline", 5) == 0) { line_test(mw_fd); } if (strncmp(cmdline, "rbmp", 4) == 0) { bitmap_read(mw_fd); } if (strncmp(cmdline, "tnote", 5) == 0) { test_notification(mw_fd); } if (strncmp(cmdline, "tapp", 4) == 0) { test_application(mw_fd); } } int menu(int mw_fd) { fd_set mfds; struct termios tconfd, tmwfd; char cmdline[128]; unsigned char msg_buf[64]; unsigned char clinep = 0; int rcvd; tcgetattr(0, &tconfd); cfmakeraw(&tconfd); tconfd.c_oflag |= ONLCR | OPOST; tconfd.c_lflag |= ISIG; tcsetattr(0, TCSANOW, &tconfd); tcgetattr(mw_fd, &tmwfd); cfmakeraw(&tmwfd); tmwfd.c_oflag |= ONLCR | OPOST; tmwfd.c_lflag |= ISIG; tcsetattr(mw_fd, TCSANOW, &tmwfd); FD_ZERO(&mfds); FD_SET(0, &mfds); FD_SET(mw_fd, &mfds); memset(cmdline, 0, 128); do { rcvd = 0; if (select(mw_fd+1, &mfds, NULL, NULL, NULL) > 0) { if (FD_ISSET(mw_fd, &mfds)) { rcvd = read(mw_fd, msg_buf, 64); #ifdef DEBUG fprintf(stderr, "read %d bytes:\n", rcvd); #endif if (rcvd > 0) { #ifdef DEBUG dump_frame(msg_buf, rcvd); #endif 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; } else { fprintf(stderr, "connected to %s\n", argv[1]); }; #endif menu(mw_fd); fsync(mw_fd); close(mw_fd); return 0; };