updates
[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 <strings.h>
11 #include <sys/socket.h>
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <unistd.h>
15
16 #include "interpret.h"
17 #include "mTaskSymbols.h"
18 #include "sds.h"
19 #include "task.h"
20 #include "misc.h"
21
22 #define MAXSDS 50
23
24 #define MSG_GET_TASK 't'
25 #define MSG_DEL_TASK 'd'
26 #define MSG_SDS_SPEC 's'
27 #define MSG_SDS_UPD 'u'
28
29 struct timeval tv1;
30 int sock_fd = -1;
31 int fd = -1;
32 int port = 8123;
33
34 void killHandler(int i)
35 {
36 printf("%i caught, Bye...\n", i);
37 exit(1);
38 }
39
40 bool input_available(int fd){
41 struct timeval tv;
42 fd_set fds;
43 tv.tv_sec = 0;
44 tv.tv_usec = 0;
45 FD_ZERO(&fds);
46 FD_SET(fd, &fds);
47 if (select(fd+1, &fds, NULL, NULL, &tv) == -1)
48 pdie("select");
49 return FD_ISSET(fd, &fds);
50 }
51
52 long millis() {
53 if (gettimeofday(&tv1, NULL) == -1)
54 pdie("gettimeofday");
55 return tv1.tv_sec*1000 + tv1.tv_usec/1000;
56 }
57
58 void read_message(int fd_in, int fd_out)
59 {
60 uint8_t c;
61 //Find next task
62
63 read(fd_in, &c, 1);
64 debug("Receiving input: %c\n", c);
65 switch(c){
66 case MSG_SDS_SPEC:
67 debug("Receiving an sds\n");
68 sds_register(fd_in);
69 break;
70 case MSG_SDS_UPD:
71 debug("Receiving an sds\n");
72 //TODO do something with the return value
73 sds_update(fd_in);
74 break;
75 case MSG_DEL_TASK:
76 debug("Receiving a delete task request\n");
77 task_delete(fd);
78 break;
79 case MSG_GET_TASK:
80 debug("Receiving a task\n");
81 c = task_register(fd_in);
82 write(fd_out, &c, 1);
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 }
93
94 void open_filedescriptors()
95 {
96 struct sockaddr_in sa;
97
98 bzero((char *) &sa, sizeof(sa));
99 sa.sin_family = AF_INET;
100 sa.sin_addr.s_addr = INADDR_ANY;
101 sa.sin_port = htons(port);
102
103 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
104 pdie("socket");
105 if(bind(sock_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
106 pdie("bind");
107 if(listen(sock_fd, 10) == -1)
108 pdie("listen");
109
110 printf("Listening on %d\n", port);
111 fflush(stdout);
112 if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
113 pdie("accept");
114 }
115
116 void usage(FILE *o, char *arg0){
117 fprintf(o,
118 "Usage: %s [opts]\n"
119 "\n"
120 "Options\n"
121 "-p PORT Custom port number, default: 8123\n"
122 , arg0);
123 }
124
125 int main(int argc, char *argv[])
126 {
127 int ct;
128
129 //Register signal handler
130 if(signal(SIGINT, killHandler) == SIG_ERR){
131 die("Couldn't register signal handler...\n");
132 }
133 if(signal(SIGTERM, killHandler) == SIG_ERR){
134 die("Couldn't register signal handler...\n");
135 }
136
137 //Command line arguments
138 int opti = 1;
139 while(opti < argc){
140 if(strcmp(argv[opti], "-h") == 0){
141 usage(stdout, argv[0]);
142 exit(EXIT_SUCCESS);
143 } else if(strcmp(argv[opti], "-p") == 0 && opti+1<argc){
144 port = atoi(argv[++opti]);
145 if(port < 1)
146 die("Port numbers are > 1\n");
147 } else {
148 usage(stderr, argv[0]);
149 exit(EXIT_FAILURE);
150 }
151 opti++;
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 write(fd, "\n", 1);
186 }
187 return 0;
188 }