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