Add menu
[metawatch.git] / metawatch.c
1 /*
2  * (c) 2011 Siegen, Germany by Nils Faerber
3  *
4  * license GPL
5  */
6 #include <stdio.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 #include <termios.h>
15
16 #include "metawatch_protocol.h"
17 #include "crc16ccitt.h"
18
19
20 void dump_frame(unsigned char *frame, int len)
21 {
22   int i;
23   for (i=0; i<len; i++)
24     fprintf(stderr, "0x%02x ", frame[i]);
25   fprintf(stderr, "\n");
26 }
27
28
29 int mw_send_packet(int mw_fd, unsigned char msg_type, unsigned char options, unsigned char *data, unsigned char len)
30 {
31   unsigned short crc;
32   unsigned char frame[64];
33   int tlen = len + 6; /* payload + 6 bytes frameing */
34   int ret;
35
36   memset(frame, 0, 64);
37   frame[0] = MW_SOF;
38   frame[1] = len + 6;
39   frame[2] = msg_type;
40   frame[3] = options;
41   memcpy(frame+4, data, len);
42   
43   crc = crc16ccitt(frame, len+4);
44   *(unsigned short *)(frame+len+4) = crc;
45
46   dump_frame(frame, tlen);
47
48   while (((ret = write(mw_fd, frame, tlen)) >= 0) && (tlen > 0))
49     tlen -= ret;
50
51   if (tlen == 0 && ret >= 0)
52     return 0;
53   else
54     return ret;
55 }
56
57 void mw_set_rtc(int mw_fd, unsigned char clk1224, unsigned char date_fmt)
58 {
59   time_t mtime;
60   struct tm mtm;
61   unsigned short year;
62   unsigned char data[32];
63   
64   mtime = time(NULL);
65   localtime_r(&mtime, &mtm);
66
67   year = mtm.tm_year + 1900;  
68   data[0] = (year & 0x0f00) >> 8;
69   data[1] = (year & 0x00ff);
70   data[2] = mtm.tm_mon + 1;
71   data[3] = mtm.tm_mday;
72   data[4] = mtm.tm_wday;
73   data[5] = mtm.tm_hour;
74   data[6] = mtm.tm_min;
75   data[7] = mtm.tm_sec;
76   data[8] = clk1224;
77   data[9] = date_fmt;
78
79   mw_send_packet(mw_fd, MW_SET_REAL_TIME_CLOCK, 0, data, 10);
80 }
81
82
83 void process_cmd(char *cmdline, int clinep, int mw_fd)
84 {
85   fprintf(stderr, "command: '%s'\n", cmdline);
86
87   if (strncmp(cmdline, "quit", 4) == 0) {
88     close(mw_fd);
89     exit(0);
90   }
91
92   if (strncmp(cmdline, "srtc", 4) == 0) {
93     fprintf(stderr, "Setting RTC from system time...");
94     mw_set_rtc(mw_fd, MW_RTC_CLOCK_24HR, MW_RTC_DATE_DDMM);
95     fprintf(stderr, "OK\n");
96   }
97 }
98
99 int menu(int mw_fd)
100 {
101   fd_set mfds;
102   struct termios tconfd;
103   char cmdline[128];
104   unsigned char msg_buf[64];
105   unsigned char clinep = 0;
106   int rcvd;
107
108   tcgetattr(0, &tconfd);
109   cfmakeraw(&tconfd);
110   tconfd.c_oflag |= ONLCR | OPOST;
111   tconfd.c_lflag |= ISIG;
112   tcsetattr(0, TCSANOW, &tconfd);
113   FD_ZERO(&mfds);
114   FD_SET(0, &mfds);
115   FD_SET(mw_fd, &mfds);
116
117   memset(cmdline, 0, 128);
118
119   do {
120       rcvd = 0;
121       if (select(mw_fd+1, &mfds, NULL, NULL, NULL) > 0) {
122         if (FD_ISSET(mw_fd, &mfds)) {
123           rcvd = read(mw_fd, msg_buf, 64);
124           printf("read %d bytes:\n", rcvd);
125           if (rcvd > 0) {
126             dump_frame(msg_buf, rcvd);
127             // decode_message(mw_fd, msg_buf, rcvd);
128           }
129         };
130         if (FD_ISSET(0, &mfds)) {
131           rcvd = read(0, (cmdline+clinep), 1);
132           if (rcvd > 0) {
133             if (cmdline[clinep] == '\r') {
134               printf("\n");
135               cmdline[clinep--] = '\0';
136               process_cmd(cmdline, clinep, mw_fd);
137               clinep = 0;
138               memset(cmdline, 0, 128);
139             } else {
140               clinep++;
141               if (clinep > 75)
142                 clinep = 75;
143               printf("\r> %s", cmdline);
144               fflush(stdout);
145             }
146           }
147         };
148       } else
149         break;
150       FD_ZERO(&mfds);
151       FD_SET(0, &mfds);
152       FD_SET(mw_fd, &mfds);
153   } while (rcvd > 0);
154
155   return 0;
156 }
157
158 int main(int argc, char **argv)
159 {
160   int mw_fd;
161
162   if (argc != 2) {
163     fprintf(stderr, "Usage:\n\t%s <devicename>\n", argv[0]);
164     return 1;
165   };
166   
167   crc16ccitt_init();
168
169   mw_fd = open(argv[1], O_RDWR);
170   if (mw_fd < 0) {
171     perror("open");
172     return 1;
173   };
174
175   menu(mw_fd);
176
177   fsync(mw_fd);
178
179   close(mw_fd);
180
181   return 0;
182 };