2 * Copyright 2020 Niklas Ekström
3 * Based on a314d daemon for A314.
8 #include <linux/spi/spidev.h>
9 #include <linux/types.h>
11 #include <netinet/in.h>
12 #include <netinet/tcp.h>
14 #include <sys/epoll.h>
15 #include <sys/ioctl.h>
16 #include <sys/socket.h>
18 #include <sys/types.h>
40 #define LOGGER_TRACE 1
41 #define LOGGER_DEBUG 2
44 #define LOGGER_ERROR 5
46 #define LOGGER_SHOW LOGGER_INFO
48 #define logger_trace(...) do { if (LOGGER_TRACE >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
49 #define logger_debug(...) do { if (LOGGER_DEBUG >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
50 #define logger_info(...) do { if (LOGGER_INFO >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
51 #define logger_warn(...) do { if (LOGGER_WARN >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
52 #define logger_error(...) do { if (LOGGER_ERROR >= LOGGER_SHOW) fprintf(stderr, __VA_ARGS__); } while (0)
54 // Events that are communicated via IRQ from Amiga to Raspberry.
55 #define R_EVENT_A2R_TAIL 1
56 #define R_EVENT_R2A_HEAD 2
57 #define R_EVENT_STARTED 4
59 // Events that are communicated from Raspberry to Amiga.
60 #define A_EVENT_R2A_TAIL 1
61 #define A_EVENT_A2R_HEAD 2
63 // Offset relative to communication area for queue pointers.
64 #define A2R_TAIL_OFFSET 0
65 #define R2A_HEAD_OFFSET 1
66 #define R2A_TAIL_OFFSET 2
67 #define A2R_HEAD_OFFSET 3
69 // Packets that are communicated across physical channels (A2R and R2A).
71 #define PKT_CONNECT_RESPONSE 5
76 // Valid responses for PKT_CONNECT_RESPONSE.
78 #define CONNECT_UNKNOWN_SERVICE 3
80 // Messages that are communicated between driver and client.
81 #define MSG_REGISTER_REQ 1
82 #define MSG_REGISTER_RES 2
83 #define MSG_DEREGISTER_REQ 3
84 #define MSG_DEREGISTER_RES 4
85 #define MSG_READ_MEM_REQ 5
86 #define MSG_READ_MEM_RES 6
87 #define MSG_WRITE_MEM_REQ 7
88 #define MSG_WRITE_MEM_RES 8
90 #define MSG_CONNECT_RESPONSE 10
98 static sigset_t original_sigset;
100 static pthread_t thread_id;
101 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
103 static int server_socket = -1;
105 static int epfd = -1;
106 static int irq_fds[2];
108 extern "C" unsigned char fast_ram_array[];
109 extern "C" void write16(unsigned int address, unsigned int value);
111 unsigned int a314_base;
112 int a314_base_configured;
119 uint8_t r_enable; // Unused.
129 uint8_t a2r_buffer[256];
130 uint8_t r2a_buffer[256];
135 static bool a314_device_started = false;
137 static uint8_t channel_status[4];
138 static uint8_t channel_status_updated = 0;
140 static uint8_t recv_buf[256];
141 static uint8_t send_buf[256];
143 struct LogicalChannel;
144 struct ClientConnection;
146 #pragma pack(push, 1)
152 }; //} __attribute__((packed));
158 std::vector<uint8_t> data;
161 struct RegisteredService
164 ClientConnection *cc;
170 std::vector<uint8_t> data;
173 struct ClientConnection
180 MessageHeader header;
181 std::vector<uint8_t> payload;
183 std::list<MessageBuffer> message_queue;
185 std::list<LogicalChannel*> associations;
188 struct LogicalChannel
192 ClientConnection *association;
195 bool got_eos_from_ami;
196 bool got_eos_from_client;
198 std::list<PacketBuffer> packet_queue;
201 static void remove_association(LogicalChannel *ch);
202 static void clear_packet_queue(LogicalChannel *ch);
203 static void create_and_enqueue_packet(LogicalChannel *ch, uint8_t type, uint8_t *data, uint8_t length);
205 static std::list<ClientConnection> connections;
206 static std::list<RegisteredService> services;
207 static std::list<LogicalChannel> channels;
208 static std::list<LogicalChannel*> send_queue;
212 std::string service_name;
214 std::vector<std::string> arguments;
217 std::vector<OnDemandStart> on_demand_services;
219 static void load_config_file(const char *filename)
221 FILE *f = fopen(filename, "rt");
226 std::vector<char *> parts;
228 while (fgets(line, 256, f) != nullptr)
231 strcpy(org_line, line);
233 bool in_quotes = false;
236 for (int i = 0; i < 256; i++)
241 parts.push_back(&line[start]);
244 else if (line[i] == '"')
248 parts.push_back(&line[start]);
249 in_quotes = !in_quotes;
252 else if (isspace(line[i]) && !in_quotes)
256 parts.push_back(&line[start]);
261 if (parts.size() >= 2)
263 on_demand_services.emplace_back();
264 auto &e = on_demand_services.back();
265 e.service_name = parts[0];
266 e.program = parts[1];
267 for (int i = 1; i < parts.size(); i++)
268 e.arguments.push_back(std::string(parts[i]));
270 else if (parts.size() != 0)
271 logger_warn("Invalid number of columns in configuration file line: %s\n", org_line);
278 if (on_demand_services.empty())
279 logger_warn("No registered services\n");
282 static int init_server_socket()
284 server_socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
285 if (server_socket == -1)
287 logger_error("Failed to create server socket\n");
291 struct sockaddr_in address;
292 address.sin_family = AF_INET;
293 address.sin_addr.s_addr = INADDR_ANY;
294 address.sin_port = htons(7110);
296 int res = bind(server_socket, (struct sockaddr *)&address, sizeof(address));
299 logger_error("Bind to localhost:7110 failed\n");
303 listen(server_socket, 16);
308 static void shutdown_server_socket()
310 if (server_socket != -1)
311 close(server_socket);
315 void create_and_send_msg(ClientConnection *cc, int type, int stream_id, uint8_t *data, int length)
319 mb.data.resize(sizeof(MessageHeader) + length);
321 MessageHeader *mh = (MessageHeader *)&mb.data[0];
323 mh->stream_id = stream_id;
326 memcpy(&mb.data[sizeof(MessageHeader)], data, length);
328 if (!cc->message_queue.empty())
330 cc->message_queue.push_back(std::move(mb));
336 int left = mb.data.size() - mb.pos;
337 uint8_t *src = &mb.data[mb.pos];
338 ssize_t r = write(cc->fd, src, left);
341 if (errno == EAGAIN || errno == EWOULDBLOCK)
343 cc->message_queue.push_back(std::move(mb));
346 else if (errno == ECONNRESET)
348 // Do not close connection here; it will get done at some other place.
353 logger_error("Write failed unexpectedly with errno = %d\n", errno);
366 static void handle_msg_register_req(ClientConnection *cc)
368 uint8_t result = MSG_FAIL;
370 std::string service_name((char *)&cc->payload[0], cc->payload.size());
372 auto it = services.begin();
373 for (; it != services.end(); it++)
374 if (it->name == service_name)
377 if (it == services.end())
379 services.emplace_back();
381 RegisteredService &srv = services.back();
383 srv.name = std::move(service_name);
385 result = MSG_SUCCESS;
388 create_and_send_msg(cc, MSG_REGISTER_RES, 0, &result, 1);
391 static void handle_msg_deregister_req(ClientConnection *cc)
393 uint8_t result = MSG_FAIL;
395 std::string service_name((char *)&cc->payload[0], cc->payload.size());
397 for (auto it = services.begin(); it != services.end(); it++)
399 if (it->name == service_name && it->cc == cc)
402 result = MSG_SUCCESS;
407 create_and_send_msg(cc, MSG_DEREGISTER_RES, 0, &result, 1);
410 static void handle_msg_read_mem_req(ClientConnection *cc)
412 uint32_t address = *(uint32_t *)&(cc->payload[0]);
413 uint32_t length = *(uint32_t *)&(cc->payload[4]);
415 create_and_send_msg(cc, MSG_READ_MEM_RES, 0, &fast_ram_array[address], length);
418 static void handle_msg_write_mem_req(ClientConnection *cc)
420 uint32_t address = *(uint32_t *)&(cc->payload[0]);
421 uint32_t length = cc->payload.size() - 4;
423 memcpy(&fast_ram_array[address], &(cc->payload[4]), length);
425 create_and_send_msg(cc, MSG_WRITE_MEM_RES, 0, nullptr, 0);
428 static LogicalChannel *get_associated_channel_by_stream_id(ClientConnection *cc, int stream_id)
430 for (auto ch : cc->associations)
432 if (ch->stream_id == stream_id)
438 static void handle_msg_connect(ClientConnection *cc)
440 // We currently don't handle that a client tries to connect to a service on the Amiga.
443 static void handle_msg_connect_response(ClientConnection *cc)
445 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
449 create_and_enqueue_packet(ch, PKT_CONNECT_RESPONSE, &cc->payload[0], cc->payload.size());
451 if (cc->payload[0] != CONNECT_OK)
452 remove_association(ch);
455 static void handle_msg_data(ClientConnection *cc)
457 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
461 create_and_enqueue_packet(ch, PKT_DATA, &cc->payload[0], cc->header.length);
464 static void handle_msg_eos(ClientConnection *cc)
466 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
467 if (!ch || ch->got_eos_from_client)
470 ch->got_eos_from_client = true;
472 create_and_enqueue_packet(ch, PKT_EOS, nullptr, 0);
474 if (ch->got_eos_from_ami)
475 remove_association(ch);
478 static void handle_msg_reset(ClientConnection *cc)
480 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
484 remove_association(ch);
486 clear_packet_queue(ch);
487 create_and_enqueue_packet(ch, PKT_RESET, nullptr, 0);
490 static void handle_received_message(ClientConnection *cc)
492 switch (cc->header.type)
494 case MSG_REGISTER_REQ:
495 handle_msg_register_req(cc);
497 case MSG_DEREGISTER_REQ:
498 handle_msg_deregister_req(cc);
500 case MSG_READ_MEM_REQ:
501 handle_msg_read_mem_req(cc);
503 case MSG_WRITE_MEM_REQ:
504 handle_msg_write_mem_req(cc);
507 handle_msg_connect(cc);
509 case MSG_CONNECT_RESPONSE:
510 handle_msg_connect_response(cc);
519 handle_msg_reset(cc);
522 // This is bad, probably should disconnect from client.
523 logger_warn("Received a message of unknown type from client\n");
528 static void close_and_remove_connection(ClientConnection *cc)
530 shutdown(cc->fd, SHUT_WR);
534 auto it = services.begin();
535 while (it != services.end())
538 it = services.erase(it);
545 auto it = cc->associations.begin();
546 while (it != cc->associations.end())
550 clear_packet_queue(ch);
551 create_and_enqueue_packet(ch, PKT_RESET, nullptr, 0);
553 ch->association = nullptr;
556 it = cc->associations.erase(it);
560 for (auto it = connections.begin(); it != connections.end(); it++)
564 connections.erase(it);
570 static void remove_association(LogicalChannel *ch)
572 auto &ass = ch->association->associations;
573 ass.erase(std::find(ass.begin(), ass.end(), ch));
575 ch->association = nullptr;
579 static void clear_packet_queue(LogicalChannel *ch)
581 if (!ch->packet_queue.empty())
583 ch->packet_queue.clear();
584 send_queue.erase(std::find(send_queue.begin(), send_queue.end(), ch));
588 static void create_and_enqueue_packet(LogicalChannel *ch, uint8_t type, uint8_t *data, uint8_t length)
590 if (ch->packet_queue.empty())
591 send_queue.push_back(ch);
593 ch->packet_queue.emplace_back();
595 PacketBuffer &pb = ch->packet_queue.back();
597 pb.data.resize(length);
599 memcpy(&pb.data[0], data, length);
602 static void handle_pkt_connect(int channel_id, uint8_t *data, int plen)
604 for (auto &ch : channels)
606 if (ch.channel_id == channel_id)
608 // We should handle this in some constructive way.
609 // This signals that should reset all logical channels.
610 logger_error("Received a CONNECT packet on a channel that was believed to be previously allocated\n");
615 channels.emplace_back();
617 auto &ch = channels.back();
619 ch.channel_id = channel_id;
620 ch.association = nullptr;
622 ch.got_eos_from_ami = false;
623 ch.got_eos_from_client = false;
625 std::string service_name((char *)data, plen);
627 for (auto &srv : services)
629 if (srv.name == service_name)
631 ClientConnection *cc = srv.cc;
634 ch.stream_id = cc->next_stream_id;
636 cc->next_stream_id += 2;
637 cc->associations.push_back(&ch);
639 create_and_send_msg(ch.association, MSG_CONNECT, ch.stream_id, data, plen);
644 for (auto &on_demand : on_demand_services)
646 if (on_demand.service_name == service_name)
649 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
652 logger_error("Unexpectedly not able to create socket pair.\n");
656 pid_t child = fork();
659 logger_error("Unexpectedly was not able to fork.\n");
667 // FIXE: The user should be configurable.
670 putenv("HOME=/home/pi");
672 std::vector<std::string> args(on_demand.arguments);
673 args.push_back("-ondemand");
674 args.push_back(std::to_string(fd));
675 std::vector<const char *> args_arr;
676 for (auto &arg : args)
677 args_arr.push_back(arg.c_str());
678 args_arr.push_back(nullptr);
680 execvp(on_demand.program.c_str(), (char* const*) &args_arr[0]);
687 int status = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
690 logger_error("Unexpectedly unable to set close-on-exec flag on client socket descriptor; errno = %d\n", errno);
694 status = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
697 logger_error("Unexpectedly unable to set client socket to non blocking; errno = %d\n", errno);
702 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
704 connections.emplace_back();
706 ClientConnection &cc = connections.back();
708 cc.next_stream_id = 1;
711 struct epoll_event ev;
712 ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
714 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) != 0)
716 logger_error("epoll_ctl() failed unexpectedly with errno = %d\n", errno);
720 services.emplace_back();
722 RegisteredService &srv = services.back();
724 srv.name = std::move(service_name);
726 ch.association = &cc;
727 ch.stream_id = cc.next_stream_id;
729 cc.next_stream_id += 2;
730 cc.associations.push_back(&ch);
732 create_and_send_msg(ch.association, MSG_CONNECT, ch.stream_id, data, plen);
738 uint8_t response = CONNECT_UNKNOWN_SERVICE;
739 create_and_enqueue_packet(&ch, PKT_CONNECT_RESPONSE, &response, 1);
742 static void handle_pkt_data(int channel_id, uint8_t *data, int plen)
744 for (auto &ch : channels)
746 if (ch.channel_id == channel_id)
748 if (ch.association != nullptr && !ch.got_eos_from_ami)
749 create_and_send_msg(ch.association, MSG_DATA, ch.stream_id, data, plen);
756 static void handle_pkt_eos(int channel_id)
758 for (auto &ch : channels)
760 if (ch.channel_id == channel_id)
762 if (ch.association != nullptr && !ch.got_eos_from_ami)
764 ch.got_eos_from_ami = true;
766 create_and_send_msg(ch.association, MSG_EOS, ch.stream_id, nullptr, 0);
768 if (ch.got_eos_from_client)
769 remove_association(&ch);
776 static void handle_pkt_reset(int channel_id)
778 for (auto &ch : channels)
780 if (ch.channel_id == channel_id)
782 clear_packet_queue(&ch);
784 if (ch.association != nullptr)
786 create_and_send_msg(ch.association, MSG_RESET, ch.stream_id, nullptr, 0);
787 remove_association(&ch);
795 static void remove_channel_if_not_associated_and_empty_pq(int channel_id)
797 for (auto it = channels.begin(); it != channels.end(); it++)
799 if (it->channel_id == channel_id)
801 if (it->association == nullptr && it->packet_queue.empty())
809 static void handle_received_pkt(int ptype, int channel_id, uint8_t *data, int plen)
811 if (ptype == PKT_CONNECT)
812 handle_pkt_connect(channel_id, data, plen);
813 else if (ptype == PKT_DATA)
814 handle_pkt_data(channel_id, data, plen);
815 else if (ptype == PKT_EOS)
816 handle_pkt_eos(channel_id);
817 else if (ptype == PKT_RESET)
818 handle_pkt_reset(channel_id);
820 remove_channel_if_not_associated_and_empty_pq(channel_id);
823 static bool receive_from_a2r()
825 int head = channel_status[A2R_HEAD_OFFSET];
826 int tail = channel_status[A2R_TAIL_OFFSET];
827 int len = (tail - head) & 255;
833 memcpy(recv_buf, &ca.a2r_buffer[head], len);
837 memcpy(recv_buf, &ca.a2r_buffer[head], 256 - head);
841 memcpy(&recv_buf[len - tail], &ca.a2r_buffer[0], tail);
845 uint8_t *p = recv_buf;
846 while (p < recv_buf + len)
849 uint8_t ptype = *p++;
850 uint8_t channel_id = *p++;
851 handle_received_pkt(ptype, channel_id, p, plen);
855 channel_status[A2R_HEAD_OFFSET] = channel_status[A2R_TAIL_OFFSET];
856 channel_status_updated |= A_EVENT_A2R_HEAD;
860 static bool flush_send_queue()
862 int tail = channel_status[R2A_TAIL_OFFSET];
863 int head = channel_status[R2A_HEAD_OFFSET];
864 int len = (tail - head) & 255;
865 int left = 255 - len;
869 while (!send_queue.empty())
871 LogicalChannel *ch = send_queue.front();
872 PacketBuffer &pb = ch->packet_queue.front();
875 int plen = 3 + pb.data.size();
880 send_buf[pos++] = pb.data.size();
881 send_buf[pos++] = ptype;
882 send_buf[pos++] = ch->channel_id;
883 memcpy(&send_buf[pos], &pb.data[0], pb.data.size());
884 pos += pb.data.size();
886 ch->packet_queue.pop_front();
888 send_queue.pop_front();
890 if (!ch->packet_queue.empty())
891 send_queue.push_back(ch);
893 remove_channel_if_not_associated_and_empty_pq(ch->channel_id);
902 uint8_t *p = send_buf;
903 int at_end = 256 - tail;
904 if (at_end < to_write)
906 memcpy(&ca.r2a_buffer[tail], p, at_end);
912 memcpy(&ca.r2a_buffer[tail], p, to_write);
913 tail = (tail + to_write) & 255;
915 channel_status[R2A_TAIL_OFFSET] = tail;
916 channel_status_updated |= A_EVENT_R2A_TAIL;
920 static void read_channel_status()
922 channel_status[A2R_TAIL_OFFSET] = ca.a2r_tail;
923 channel_status[R2A_HEAD_OFFSET] = ca.r2a_head;
924 channel_status[R2A_TAIL_OFFSET] = ca.r2a_tail;
925 channel_status[A2R_HEAD_OFFSET] = ca.a2r_head;
926 channel_status_updated = 0;
929 static void write_channel_status()
931 if (channel_status_updated != 0)
933 ca.r2a_tail = channel_status[R2A_TAIL_OFFSET];
934 ca.a2r_head = channel_status[A2R_HEAD_OFFSET];
936 pthread_mutex_lock(&mutex);
937 ca.a_events |= channel_status_updated;
938 pthread_mutex_unlock(&mutex);
940 channel_status_updated = 0;
944 static void close_all_logical_channels()
948 auto it = channels.begin();
949 while (it != channels.end())
951 LogicalChannel &ch = *it;
953 if (ch.association != nullptr)
955 create_and_send_msg(ch.association, MSG_RESET, ch.stream_id, nullptr, 0);
956 remove_association(&ch);
959 it = channels.erase(it);
963 static void handle_a314_irq(uint8_t events)
968 if (events & R_EVENT_STARTED)
970 if (!channels.empty())
971 logger_info("Received STARTED event while logical channels are open -- closing channels\n");
973 close_all_logical_channels();
974 a314_device_started = true;
977 if (!a314_device_started)
980 read_channel_status();
982 bool any_rcvd = receive_from_a2r();
983 bool any_sent = flush_send_queue();
985 if (any_rcvd || any_sent)
986 write_channel_status();
989 static void handle_client_connection_event(ClientConnection *cc, struct epoll_event *ev)
991 if (ev->events & EPOLLERR)
993 logger_warn("Received EPOLLERR for client connection\n");
994 close_and_remove_connection(cc);
998 if (ev->events & EPOLLIN)
1005 if (cc->payload.empty())
1007 left = sizeof(MessageHeader) - cc->bytes_read;
1008 dst = (uint8_t *)&(cc->header) + cc->bytes_read;
1012 left = cc->header.length - cc->bytes_read;
1013 dst = &cc->payload[cc->bytes_read];
1016 ssize_t r = read(cc->fd, dst, left);
1019 if (errno == EAGAIN || errno == EWOULDBLOCK)
1022 logger_error("Read failed unexpectedly with errno = %d\n", errno);
1028 logger_info("Received End-of-File on client connection\n");
1029 close_and_remove_connection(cc);
1034 cc->bytes_read += r;
1038 if (cc->payload.empty())
1040 if (cc->header.length == 0)
1042 logger_trace("header: length=%d, stream_id=%d, type=%d\n", cc->header.length, cc->header.stream_id, cc->header.type);
1043 handle_received_message(cc);
1047 cc->payload.resize(cc->header.length);
1052 logger_trace("header: length=%d, stream_id=%d, type=%d\n", cc->header.length, cc->header.stream_id, cc->header.type);
1053 handle_received_message(cc);
1054 cc->payload.clear();
1062 if (ev->events & EPOLLOUT)
1064 while (!cc->message_queue.empty())
1066 MessageBuffer &mb = cc->message_queue.front();
1068 int left = mb.data.size() - mb.pos;
1069 uint8_t *src = &mb.data[mb.pos];
1070 ssize_t r = write(cc->fd, src, left);
1073 if (errno == EAGAIN || errno == EWOULDBLOCK)
1075 else if (errno == ECONNRESET)
1077 close_and_remove_connection(cc);
1082 logger_error("Write failed unexpectedly with errno = %d\n", errno);
1089 cc->message_queue.pop_front();
1094 static void handle_server_socket_ready()
1096 struct sockaddr_in address;
1097 int alen = sizeof(struct sockaddr_in);
1099 int fd = accept(server_socket, (struct sockaddr *)&address, (socklen_t *)&alen);
1102 logger_error("Accept failed unexpectedly with errno = %d\n", errno);
1106 int status = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
1109 logger_error("Unexpectedly unable to set close-on-exec flag on client socket descriptor; errno = %d\n", errno);
1113 status = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
1116 logger_error("Unexpectedly unable to set client socket to non blocking; errno = %d\n", errno);
1121 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
1123 connections.emplace_back();
1125 ClientConnection &cc = connections.back();
1127 cc.next_stream_id = 1;
1130 struct epoll_event ev;
1131 ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
1133 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) != 0)
1135 logger_error("epoll_ctl() failed unexpectedly with errno = %d\n", errno);
1140 static void main_loop()
1142 bool shutting_down = false;
1147 struct epoll_event ev;
1148 int timeout = shutting_down ? 10000 : -1;
1149 int n = epoll_pwait(epfd, &ev, 1, timeout, &original_sigset);
1154 logger_info("Received SIGTERM\n");
1156 shutdown_server_socket();
1158 while (!connections.empty())
1159 close_and_remove_connection(&connections.front());
1161 if (flush_send_queue())
1162 write_channel_status();
1164 if (!channels.empty())
1165 shutting_down = true;
1171 logger_error("epoll_pwait failed with unexpected errno = %d\n", errno);
1181 logger_error("epoll_pwait returned 0 which is unexpected since no timeout was set\n");
1187 if (ev.data.fd == irq_fds[1])
1190 if (read(irq_fds[1], &events, 1) != 1)
1192 logger_error("Read from interrupt socket pair, and unexpectedly didn't return 1 byte\n");
1196 handle_a314_irq(events);
1198 else if (ev.data.fd == server_socket)
1200 logger_trace("Epoll event: server socket is ready, events = %d\n", ev.events);
1201 handle_server_socket_ready();
1205 logger_trace("Epoll event: client socket is ready, events = %d\n", ev.events);
1207 auto it = connections.begin();
1208 for (; it != connections.end(); it++)
1210 if (it->fd == ev.data.fd)
1214 if (it == connections.end())
1216 logger_error("Got notified about an event on a client connection that supposedly isn't currently open\n");
1220 ClientConnection *cc = &(*it);
1221 handle_client_connection_event(cc, &ev);
1223 if (flush_send_queue())
1224 write_channel_status();
1230 static void sigterm_handler(int signo)
1234 static void init_sigterm()
1239 sigaddset(&ss, SIGTERM);
1240 sigprocmask(SIG_BLOCK, &ss, &original_sigset);
1242 struct sigaction sa;
1243 sa.sa_handler = sigterm_handler;
1244 sigemptyset(&sa.sa_mask);
1246 sigaction(SIGTERM, &sa, NULL);
1250 static int init_driver()
1254 if (init_server_socket() != 0)
1257 int err = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, irq_fds);
1260 logger_error("Unable to create socket pair, errno = %d\n", errno);
1264 epfd = epoll_create1(EPOLL_CLOEXEC);
1268 struct epoll_event ev;
1269 ev.events = EPOLLIN;
1270 ev.data.fd = irq_fds[1];
1271 if (epoll_ctl(epfd, EPOLL_CTL_ADD, irq_fds[1], &ev) != 0)
1274 ev.events = EPOLLIN;
1275 ev.data.fd = server_socket;
1276 if (epoll_ctl(epfd, EPOLL_CTL_ADD, server_socket, &ev) != 0)
1282 static void shutdown_driver()
1287 shutdown_server_socket();
1290 static void *thread_start(void *arg)
1297 static void write_r_events(uint8_t events)
1299 if (write(irq_fds[0], &events, 1) != 1)
1300 logger_error("Write to interrupt socket pair did not return 1\n");
1305 std::string conf_filename("/etc/opt/a314/a314d.conf");
1307 load_config_file(conf_filename.c_str());
1309 int err = init_driver();
1316 err = pthread_create(&thread_id, NULL, thread_start, NULL);
1319 logger_error("pthread_create failed with err = %d\n", err);
1326 void a314_set_mem_base_size(unsigned int base, unsigned int size)
1328 ca.mem_base = htobe32(base);
1329 ca.mem_size = htobe32(size);
1332 void a314_process_events()
1334 if (ca.a_events & ca.a_enable)
1336 write16(0xdff09c, 0x8008);
1341 unsigned int a314_read_memory_8(unsigned int address)
1343 if (address >= sizeof(ca))
1347 if (address == offsetof(ComArea, a_events))
1349 pthread_mutex_lock(&mutex);
1352 pthread_mutex_unlock(&mutex);
1356 uint8_t *p = (uint8_t *)&ca;
1363 unsigned int a314_read_memory_16(unsigned int address)
1365 if (address >= sizeof(ca))
1368 uint16_t *p = (uint16_t *)&ca;
1369 return be16toh(p[address >> 1]);
1372 unsigned int a314_read_memory_32(unsigned int address)
1374 if (address >= sizeof(ca))
1377 uint32_t *p = (uint32_t *)&ca;
1378 return be32toh(p[address >> 2]);
1381 void a314_write_memory_8(unsigned int address, unsigned int value)
1383 if (address >= sizeof(ca))
1388 case offsetof(ComArea, a_events):
1389 // a_events is not writable.
1392 case offsetof(ComArea, r_events):
1394 write_r_events((uint8_t)value);
1399 uint8_t *p = (uint8_t *)&ca;
1400 p[address] = (uint8_t)value;
1406 void a314_write_memory_16(unsigned int address, unsigned int value)
1411 void a314_write_memory_32(unsigned int address, unsigned int value)