revert back to old itasks, add sds support in bytecode
[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 '\0':
83 debug("iTasks server shut down\n");
84 exit(EXIT_SUCCESS);
85 default:
86 debug("Unknown message: %X %X?\n", c, EOF);
87 }
88 }
89
90 void open_filedescriptors()
91 {
92 struct sockaddr_in sa;
93
94 bzero((char *) &sa, sizeof(sa));
95 sa.sin_family = AF_INET;
96 sa.sin_addr.s_addr = INADDR_ANY;
97 sa.sin_port = htons(port);
98
99 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
100 pdie("socket");
101 if(bind(sock_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
102 pdie("bind\n");
103 if(listen(sock_fd, 10) == -1)
104 pdie("bind\n");
105
106 printf("Listening on %d\n", port);
107 fflush(stdout);
108 if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
109 pdie("accept");
110 }
111
112 void usage(FILE *o, char *arg0){
113 fprintf(o,
114 "Usage: %s [opts]\n"
115 "\n"
116 "Options\n"
117 "-p PORT Custom port number, default: 8123\n"
118 , arg0);
119 }
120
121 int main(int argc, char *argv[])
122 {
123 int ct;
124
125 //Register signal handler
126 if(signal(SIGINT, killHandler) == SIG_ERR){
127 die("Couldn't register signal handler...\n");
128 }
129 if(signal(SIGTERM, killHandler) == SIG_ERR){
130 die("Couldn't register signal handler...\n");
131 }
132
133 //Command line arguments
134 int opt;
135 while((opt = getopt(argc, argv, "hp:")) != -1){
136 switch(opt){
137 case 'p':
138 port = atoi(optarg);
139 if(port < 1)
140 die("Port numbers are > 1\n");
141 break;
142 case 'h':
143 usage(stdout, argv[0]);
144 exit(EXIT_SUCCESS);
145 default:
146 usage(stderr, argv[0]);
147 exit(EXIT_FAILURE);
148 }
149
150 }
151
152 open_filedescriptors();
153
154 long cyclestart;
155 struct task *curtask;
156 while(true){
157 //Check for new tasks
158 if(input_available(fd))
159 read_message(fd, fd);
160 //Run tasks
161 cyclestart = millis();
162 for(ct = 0; ct<MAXTASKS; ct++){
163 //See whether the task is even in use
164 if((curtask = task_get(ct)) == NULL){
165 // debug("Task %d not implemented\n", ct);
166 continue;
167 }
168 //See whether the task interval has passed
169 if(cyclestart-curtask->lastrun < curtask->interval){
170 // debug("Task %d not scheduled\n", ct);
171 continue;
172 }
173 #ifdef DEBUG
174 printf("Current task to run: %d\n", ct);
175 getchar();
176 #endif
177 run_task(curtask, fd);
178 }
179 debug("Waiting for 500ms\n");
180 usleep(500000);
181 debug("done waiting\n");
182 }
183 return 0;
184 }