update
[mTask.git] / int / main.c
1 #include <netdb.h>
2 #include <netinet/in.h>
3 #include <signal.h>
4 #include <stdbool.h>
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 #include <sys/time.h>
12 #include <unistd.h>
13
14 #include "interpret.h"
15 #include "mTaskSymbols.h"
16 #include "sds.h"
17 #include "task.h"
18 #include "misc.h"
19
20 #define MAXSDS 50
21
22 #define MSG_GET_TASK 't'
23 #define MSG_DEL_TASK 'd'
24 #define MSG_SDS_SPEC 's'
25 #define MSG_SDS_UPD 'u'
26
27 struct timeval tv1;
28 int sock_fd = -1;
29 int fd = -1;
30 int port = 8123;
31
32 void killHandler(int i)
33 {
34 printf("%s caught, Bye...\n", strsignal(i));
35 exit(1);
36 }
37
38 bool input_available(int fd){
39 struct timeval tv;
40 fd_set fds;
41 tv.tv_sec = 0;
42 tv.tv_usec = 0;
43 FD_ZERO(&fds);
44 FD_SET(fd, &fds);
45 if (select(fd+1, &fds, NULL, NULL, &tv) == -1)
46 pdie("select");
47 return FD_ISSET(fd, &fds);
48 }
49
50 long millis() {
51 if (gettimeofday(&tv1, NULL) == -1)
52 pdie("gettimeofday");
53 return tv1.tv_sec*1000 + tv1.tv_usec/1000;
54 }
55
56 void read_message(int fd_in, int fd_out)
57 {
58 uint8_t c;
59 //Find next task
60
61 read(fd_in, &c, 1);
62 debug("Receiving input: %c\n", c);
63 switch(c){
64 case MSG_SDS_SPEC:
65 debug("Receiving an sds\n");
66 sds_register(fd_in);
67 break;
68 case MSG_SDS_UPD:
69 debug("Receiving an sds\n");
70 //TODO do something with the return value
71 sds_update(fd_in);
72 break;
73 case MSG_DEL_TASK:
74 debug("Receiving a delete task request\n");
75 task_delete(fd);
76 break;
77 case MSG_GET_TASK:
78 debug("Receiving a task\n");
79 c = task_register(fd_in);
80 write(fd_out, &c, 1);
81 break;
82 case '\n':
83 break;
84 case '\0':
85 debug("iTasks server shut down\n");
86 exit(EXIT_SUCCESS);
87 default:
88 debug("Unknown message: %X %X?\n", c, EOF);
89 }
90 }
91
92 void open_filedescriptors()
93 {
94 struct sockaddr_in sa;
95
96 bzero((char *) &sa, sizeof(sa));
97 sa.sin_family = AF_INET;
98 sa.sin_addr.s_addr = INADDR_ANY;
99 sa.sin_port = htons(port);
100
101 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
102 pdie("socket");
103 if(bind(sock_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
104 pdie("bind");
105 if(listen(sock_fd, 10) == -1)
106 pdie("listen");
107
108 printf("Listening on %d\n", port);
109 fflush(stdout);
110 if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
111 pdie("accept");
112 }
113
114 void usage(FILE *o, char *arg0){
115 fprintf(o,
116 "Usage: %s [opts]\n"
117 "\n"
118 "Options\n"
119 "-p PORT Custom port number, default: 8123\n"
120 , arg0);
121 }
122
123 int main(int argc, char *argv[])
124 {
125 int ct;
126
127 //Register signal handler
128 if(signal(SIGINT, killHandler) == SIG_ERR){
129 die("Couldn't register signal handler...\n");
130 }
131 if(signal(SIGTERM, killHandler) == SIG_ERR){
132 die("Couldn't register signal handler...\n");
133 }
134
135 //Command line arguments
136 int opt;
137 while((opt = getopt(argc, argv, "hp:")) != -1){
138 switch(opt){
139 case 'p':
140 port = atoi(optarg);
141 if(port < 1)
142 die("Port numbers are > 1\n");
143 break;
144 case 'h':
145 usage(stdout, argv[0]);
146 exit(EXIT_SUCCESS);
147 default:
148 usage(stderr, argv[0]);
149 exit(EXIT_FAILURE);
150 }
151
152 }
153
154 open_filedescriptors();
155 write(fd, "\n", 1);
156
157 long cyclestart;
158 struct task *curtask;
159 while(true){
160 //Check for new tasks
161 if(input_available(fd))
162 read_message(fd, fd);
163 //Run tasks
164 cyclestart = millis();
165 for(ct = 0; ct<MAXTASKS; ct++){
166 //See whether the task is even in use
167 if((curtask = task_get(ct)) == NULL){
168 // debug("Task %d not implemented\n", ct);
169 continue;
170 }
171 //See whether the task interval has passed
172 if(cyclestart-curtask->lastrun < curtask->interval){
173 // debug("Task %d not scheduled\n", ct);
174 continue;
175 }
176 #ifdef DEBUG
177 printf("Current task to run: %d\n", ct);
178 getchar();
179 #endif
180 run_task(curtask, fd);
181 }
182 debug("Waiting for 500ms\n");
183 usleep(500000);
184 debug("done waiting\n");
185 }
186 return 0;
187 }