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