2 * Copyright 2020-2021 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>
38 // Silence stupid warning
40 #include "config_file/config_file.h"
42 extern "C" emulator_config *cfg;
44 #define LOGGER_TRACE 1
45 #define LOGGER_DEBUG 2
48 #define LOGGER_ERROR 5
50 #define LOGGER_SHOW LOGGER_INFO
52 #define logger_trace(...) do { if (LOGGER_TRACE >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
53 #define logger_debug(...) do { if (LOGGER_DEBUG >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
54 #define logger_info(...) do { if (LOGGER_INFO >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
55 #define logger_warn(...) do { if (LOGGER_WARN >= LOGGER_SHOW) fprintf(stdout, __VA_ARGS__); } while (0)
56 #define logger_error(...) do { if (LOGGER_ERROR >= LOGGER_SHOW) fprintf(stderr, __VA_ARGS__); } while (0)
58 // Events that are communicated via IRQ from Amiga to Raspberry.
59 #define R_EVENT_A2R_TAIL 1
60 #define R_EVENT_R2A_HEAD 2
61 #define R_EVENT_STARTED 4
63 // Events that are communicated from Raspberry to Amiga.
64 #define A_EVENT_R2A_TAIL 1
65 #define A_EVENT_A2R_HEAD 2
67 // Offset relative to communication area for queue pointers.
68 #define A2R_TAIL_OFFSET 0
69 #define R2A_HEAD_OFFSET 1
70 #define R2A_TAIL_OFFSET 2
71 #define A2R_HEAD_OFFSET 3
73 // Packets that are communicated across physical channels (A2R and R2A).
75 #define PKT_CONNECT_RESPONSE 5
80 // Valid responses for PKT_CONNECT_RESPONSE.
82 #define CONNECT_UNKNOWN_SERVICE 3
84 // Messages that are communicated between driver and client.
85 #define MSG_REGISTER_REQ 1
86 #define MSG_REGISTER_RES 2
87 #define MSG_DEREGISTER_REQ 3
88 #define MSG_DEREGISTER_RES 4
89 #define MSG_READ_MEM_REQ 5
90 #define MSG_READ_MEM_RES 6
91 #define MSG_WRITE_MEM_REQ 7
92 #define MSG_WRITE_MEM_RES 8
94 #define MSG_CONNECT_RESPONSE 10
102 static sigset_t original_sigset;
104 static pthread_t thread_id;
105 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
107 static int server_socket = -1;
109 static int epfd = -1;
110 static int irq_fds[2];
112 extern "C" unsigned int ps_read_8(unsigned int address);
113 extern "C" void ps_write_8(unsigned int address, unsigned int value);
114 extern "C" void ps_write_16(unsigned int address, unsigned int value);
116 unsigned int a314_base;
117 int a314_base_configured;
124 uint8_t r_enable; // Unused.
134 uint8_t a2r_buffer[256];
135 uint8_t r2a_buffer[256];
140 static bool a314_device_started = false;
142 static uint8_t channel_status[4];
143 static uint8_t channel_status_updated = 0;
145 static uint8_t recv_buf[256];
146 static uint8_t send_buf[256];
148 struct LogicalChannel;
149 struct ClientConnection;
151 #pragma pack(push, 1)
157 }; //} __attribute__((packed));
163 std::vector<uint8_t> data;
166 struct RegisteredService
169 ClientConnection *cc;
175 std::vector<uint8_t> data;
178 struct ClientConnection
185 MessageHeader header;
186 std::vector<uint8_t> payload;
188 std::list<MessageBuffer> message_queue;
190 std::list<LogicalChannel*> associations;
193 struct LogicalChannel
197 ClientConnection *association;
200 bool got_eos_from_ami;
201 bool got_eos_from_client;
203 std::list<PacketBuffer> packet_queue;
206 static void remove_association(LogicalChannel *ch);
207 static void clear_packet_queue(LogicalChannel *ch);
208 static void create_and_enqueue_packet(LogicalChannel *ch, uint8_t type, uint8_t *data, uint8_t length);
210 static std::list<ClientConnection> connections;
211 static std::list<RegisteredService> services;
212 static std::list<LogicalChannel> channels;
213 static std::list<LogicalChannel*> send_queue;
217 std::string service_name;
219 std::vector<std::string> arguments;
222 std::vector<OnDemandStart> on_demand_services;
224 std::string a314_config_file = "./a314/files_pi/a314d.conf";
225 std::string home_env = "HOME=./";
227 static void load_config_file(const char *filename)
229 FILE *f = fopen(filename, "rt");
235 std::vector<char *> parts;
237 while (fgets(line, 256, f) != nullptr)
240 strcpy(org_line, line);
242 bool in_quotes = false;
245 for (int i = 0; i < 256; i++)
250 parts.push_back(&line[start]);
253 else if (line[i] == '"')
257 parts.push_back(&line[start]);
258 in_quotes = !in_quotes;
261 else if (isspace(line[i]) && !in_quotes)
265 parts.push_back(&line[start]);
270 if (parts.size() >= 2)
272 on_demand_services.emplace_back();
273 auto &e = on_demand_services.back();
274 e.service_name = parts[0];
275 e.program = parts[1];
276 for (int i = 1; i < parts.size(); i++)
277 e.arguments.push_back(std::string(parts[i]));
279 else if (parts.size() != 0)
280 logger_warn("Invalid number of columns in configuration file line: %s\n", org_line);
287 if (on_demand_services.empty())
288 logger_warn("No registered services\n");
291 static int init_server_socket()
293 server_socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
294 if (server_socket == -1)
296 logger_error("Failed to create server socket\n");
300 struct sockaddr_in address;
301 address.sin_family = AF_INET;
302 address.sin_addr.s_addr = INADDR_ANY;
303 address.sin_port = htons(7110);
305 int res = bind(server_socket, (struct sockaddr *)&address, sizeof(address));
308 logger_error("Bind to localhost:7110 failed\n");
312 listen(server_socket, 16);
317 static void shutdown_server_socket()
319 if (server_socket != -1)
320 close(server_socket);
324 void create_and_send_msg(ClientConnection *cc, int type, int stream_id, uint8_t *data, int length)
328 mb.data.resize(sizeof(MessageHeader) + length);
330 MessageHeader *mh = (MessageHeader *)&mb.data[0];
332 mh->stream_id = stream_id;
335 memcpy(&mb.data[sizeof(MessageHeader)], data, length);
337 if (!cc->message_queue.empty())
339 cc->message_queue.push_back(std::move(mb));
345 int left = mb.data.size() - mb.pos;
346 uint8_t *src = &mb.data[mb.pos];
347 ssize_t r = write(cc->fd, src, left);
350 if (errno == EAGAIN || errno == EWOULDBLOCK)
352 cc->message_queue.push_back(std::move(mb));
355 else if (errno == ECONNRESET)
357 // Do not close connection here; it will get done at some other place.
362 logger_error("Write failed unexpectedly with errno = %d\n", errno);
375 static void handle_msg_register_req(ClientConnection *cc)
377 uint8_t result = MSG_FAIL;
379 std::string service_name((char *)&cc->payload[0], cc->payload.size());
381 auto it = services.begin();
382 for (; it != services.end(); it++)
383 if (it->name == service_name)
386 if (it == services.end())
388 services.emplace_back();
390 RegisteredService &srv = services.back();
392 srv.name = std::move(service_name);
394 result = MSG_SUCCESS;
397 create_and_send_msg(cc, MSG_REGISTER_RES, 0, &result, 1);
400 static void handle_msg_deregister_req(ClientConnection *cc)
402 uint8_t result = MSG_FAIL;
404 std::string service_name((char *)&cc->payload[0], cc->payload.size());
406 for (auto it = services.begin(); it != services.end(); it++)
408 if (it->name == service_name && it->cc == cc)
411 result = MSG_SUCCESS;
416 create_and_send_msg(cc, MSG_DEREGISTER_RES, 0, &result, 1);
419 uint8_t manual_read_buf[64 * SIZE_KILO];
421 static void handle_msg_read_mem_req(ClientConnection *cc)
423 uint32_t address = *(uint32_t *)&(cc->payload[0]);
424 uint32_t length = *(uint32_t *)&(cc->payload[4]);
426 if (get_mapped_item_by_address(cfg, address) != -1) {
427 int32_t index = get_mapped_item_by_address(cfg, address);
428 uint8_t *map = &cfg->map_data[index][address - cfg->map_offset[index]];
429 create_and_send_msg(cc, MSG_READ_MEM_RES, 0, map, length);
431 // No idea if this actually works.
432 for (int i = 0; i < length; i++) {
433 manual_read_buf[i] = (unsigned char)ps_read_8(address + i);
435 create_and_send_msg(cc, MSG_READ_MEM_RES, 0, manual_read_buf, length);
440 static void handle_msg_write_mem_req(ClientConnection *cc)
442 uint32_t address = *(uint32_t *)&(cc->payload[0]);
443 uint32_t length = cc->payload.size() - 4;
446 if (get_mapped_item_by_address(cfg, address) != -1) {
447 int32_t index = get_mapped_item_by_address(cfg, address);
448 uint8_t *map = &cfg->map_data[index][address - cfg->map_offset[index]];
449 memcpy(map, &(cc->payload[4]), length);
451 // No idea if this actually works.
452 for (int i = 0; i < length; i++) {
453 ps_write_8(address + i, cc->payload[4 + i]);
457 create_and_send_msg(cc, MSG_WRITE_MEM_RES, 0, nullptr, 0);
460 static LogicalChannel *get_associated_channel_by_stream_id(ClientConnection *cc, int stream_id)
462 for (auto ch : cc->associations)
464 if (ch->stream_id == stream_id)
470 static void handle_msg_connect(ClientConnection *cc)
472 // We currently don't handle that a client tries to connect to a service on the Amiga.
475 static void handle_msg_connect_response(ClientConnection *cc)
477 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
481 create_and_enqueue_packet(ch, PKT_CONNECT_RESPONSE, &cc->payload[0], cc->payload.size());
483 if (cc->payload[0] != CONNECT_OK)
484 remove_association(ch);
487 static void handle_msg_data(ClientConnection *cc)
489 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
493 create_and_enqueue_packet(ch, PKT_DATA, &cc->payload[0], cc->header.length);
496 static void handle_msg_eos(ClientConnection *cc)
498 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
499 if (!ch || ch->got_eos_from_client)
502 ch->got_eos_from_client = true;
504 create_and_enqueue_packet(ch, PKT_EOS, nullptr, 0);
506 if (ch->got_eos_from_ami)
507 remove_association(ch);
510 static void handle_msg_reset(ClientConnection *cc)
512 LogicalChannel *ch = get_associated_channel_by_stream_id(cc, cc->header.stream_id);
516 remove_association(ch);
518 clear_packet_queue(ch);
519 create_and_enqueue_packet(ch, PKT_RESET, nullptr, 0);
522 static void handle_received_message(ClientConnection *cc)
524 switch (cc->header.type)
526 case MSG_REGISTER_REQ:
527 handle_msg_register_req(cc);
529 case MSG_DEREGISTER_REQ:
530 handle_msg_deregister_req(cc);
532 case MSG_READ_MEM_REQ:
533 handle_msg_read_mem_req(cc);
535 case MSG_WRITE_MEM_REQ:
536 handle_msg_write_mem_req(cc);
539 handle_msg_connect(cc);
541 case MSG_CONNECT_RESPONSE:
542 handle_msg_connect_response(cc);
551 handle_msg_reset(cc);
554 // This is bad, probably should disconnect from client.
555 logger_warn("Received a message of unknown type from client\n");
560 static void close_and_remove_connection(ClientConnection *cc)
562 shutdown(cc->fd, SHUT_WR);
566 auto it = services.begin();
567 while (it != services.end())
570 it = services.erase(it);
577 auto it = cc->associations.begin();
578 while (it != cc->associations.end())
582 clear_packet_queue(ch);
583 create_and_enqueue_packet(ch, PKT_RESET, nullptr, 0);
585 ch->association = nullptr;
588 it = cc->associations.erase(it);
592 for (auto it = connections.begin(); it != connections.end(); it++)
596 connections.erase(it);
602 static void remove_association(LogicalChannel *ch)
604 auto &ass = ch->association->associations;
605 ass.erase(std::find(ass.begin(), ass.end(), ch));
607 ch->association = nullptr;
611 static void clear_packet_queue(LogicalChannel *ch)
613 if (!ch->packet_queue.empty())
615 ch->packet_queue.clear();
616 send_queue.erase(std::find(send_queue.begin(), send_queue.end(), ch));
620 static void create_and_enqueue_packet(LogicalChannel *ch, uint8_t type, uint8_t *data, uint8_t length)
622 if (ch->packet_queue.empty())
623 send_queue.push_back(ch);
625 ch->packet_queue.emplace_back();
627 PacketBuffer &pb = ch->packet_queue.back();
629 pb.data.resize(length);
631 memcpy(&pb.data[0], data, length);
634 static void handle_pkt_connect(int channel_id, uint8_t *data, int plen)
636 for (auto &ch : channels)
638 if (ch.channel_id == channel_id)
640 // We should handle this in some constructive way.
641 // This signals that should reset all logical channels.
642 logger_error("Received a CONNECT packet on a channel that was believed to be previously allocated\n");
647 channels.emplace_back();
649 auto &ch = channels.back();
651 ch.channel_id = channel_id;
652 ch.association = nullptr;
654 ch.got_eos_from_ami = false;
655 ch.got_eos_from_client = false;
657 std::string service_name((char *)data, plen);
659 for (auto &srv : services)
661 if (srv.name == service_name)
663 ClientConnection *cc = srv.cc;
666 ch.stream_id = cc->next_stream_id;
668 cc->next_stream_id += 2;
669 cc->associations.push_back(&ch);
671 create_and_send_msg(ch.association, MSG_CONNECT, ch.stream_id, data, plen);
676 for (auto &on_demand : on_demand_services)
678 if (on_demand.service_name == service_name)
681 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
684 logger_error("Unexpectedly not able to create socket pair.\n");
688 pid_t child = fork();
691 logger_error("Unexpectedly was not able to fork.\n");
699 // FIXE: The user should be configurable.
702 putenv((char *)home_env.c_str());
704 std::vector<std::string> args(on_demand.arguments);
705 args.push_back("-ondemand");
706 args.push_back(std::to_string(fd));
707 std::vector<const char *> args_arr;
708 for (auto &arg : args)
709 args_arr.push_back(arg.c_str());
710 args_arr.push_back(nullptr);
712 execvp(on_demand.program.c_str(), (char* const*) &args_arr[0]);
719 int status = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
722 logger_error("Unexpectedly unable to set close-on-exec flag on client socket descriptor; errno = %d\n", errno);
726 status = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
729 logger_error("Unexpectedly unable to set client socket to non blocking; errno = %d\n", errno);
734 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
736 connections.emplace_back();
738 ClientConnection &cc = connections.back();
740 cc.next_stream_id = 1;
743 struct epoll_event ev;
744 ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
746 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) != 0)
748 logger_error("epoll_ctl() failed unexpectedly with errno = %d\n", errno);
752 services.emplace_back();
754 RegisteredService &srv = services.back();
756 srv.name = std::move(service_name);
758 ch.association = &cc;
759 ch.stream_id = cc.next_stream_id;
761 cc.next_stream_id += 2;
762 cc.associations.push_back(&ch);
764 create_and_send_msg(ch.association, MSG_CONNECT, ch.stream_id, data, plen);
770 uint8_t response = CONNECT_UNKNOWN_SERVICE;
771 create_and_enqueue_packet(&ch, PKT_CONNECT_RESPONSE, &response, 1);
774 static void handle_pkt_data(int channel_id, uint8_t *data, int plen)
776 for (auto &ch : channels)
778 if (ch.channel_id == channel_id)
780 if (ch.association != nullptr && !ch.got_eos_from_ami)
781 create_and_send_msg(ch.association, MSG_DATA, ch.stream_id, data, plen);
788 static void handle_pkt_eos(int channel_id)
790 for (auto &ch : channels)
792 if (ch.channel_id == channel_id)
794 if (ch.association != nullptr && !ch.got_eos_from_ami)
796 ch.got_eos_from_ami = true;
798 create_and_send_msg(ch.association, MSG_EOS, ch.stream_id, nullptr, 0);
800 if (ch.got_eos_from_client)
801 remove_association(&ch);
808 static void handle_pkt_reset(int channel_id)
810 for (auto &ch : channels)
812 if (ch.channel_id == channel_id)
814 clear_packet_queue(&ch);
816 if (ch.association != nullptr)
818 create_and_send_msg(ch.association, MSG_RESET, ch.stream_id, nullptr, 0);
819 remove_association(&ch);
827 static void remove_channel_if_not_associated_and_empty_pq(int channel_id)
829 for (auto it = channels.begin(); it != channels.end(); it++)
831 if (it->channel_id == channel_id)
833 if (it->association == nullptr && it->packet_queue.empty())
841 static void handle_received_pkt(int ptype, int channel_id, uint8_t *data, int plen)
843 if (ptype == PKT_CONNECT)
844 handle_pkt_connect(channel_id, data, plen);
845 else if (ptype == PKT_DATA)
846 handle_pkt_data(channel_id, data, plen);
847 else if (ptype == PKT_EOS)
848 handle_pkt_eos(channel_id);
849 else if (ptype == PKT_RESET)
850 handle_pkt_reset(channel_id);
852 remove_channel_if_not_associated_and_empty_pq(channel_id);
855 static bool receive_from_a2r()
857 int head = channel_status[A2R_HEAD_OFFSET];
858 int tail = channel_status[A2R_TAIL_OFFSET];
859 int len = (tail - head) & 255;
865 memcpy(recv_buf, &ca.a2r_buffer[head], len);
869 memcpy(recv_buf, &ca.a2r_buffer[head], 256 - head);
873 memcpy(&recv_buf[len - tail], &ca.a2r_buffer[0], tail);
877 uint8_t *p = recv_buf;
878 while (p < recv_buf + len)
881 uint8_t ptype = *p++;
882 uint8_t channel_id = *p++;
883 handle_received_pkt(ptype, channel_id, p, plen);
887 channel_status[A2R_HEAD_OFFSET] = channel_status[A2R_TAIL_OFFSET];
888 channel_status_updated |= A_EVENT_A2R_HEAD;
892 static bool flush_send_queue()
894 int tail = channel_status[R2A_TAIL_OFFSET];
895 int head = channel_status[R2A_HEAD_OFFSET];
896 int len = (tail - head) & 255;
897 int left = 255 - len;
901 while (!send_queue.empty())
903 LogicalChannel *ch = send_queue.front();
904 PacketBuffer &pb = ch->packet_queue.front();
907 int plen = 3 + pb.data.size();
912 send_buf[pos++] = pb.data.size();
913 send_buf[pos++] = ptype;
914 send_buf[pos++] = ch->channel_id;
915 memcpy(&send_buf[pos], &pb.data[0], pb.data.size());
916 pos += pb.data.size();
918 ch->packet_queue.pop_front();
920 send_queue.pop_front();
922 if (!ch->packet_queue.empty())
923 send_queue.push_back(ch);
925 remove_channel_if_not_associated_and_empty_pq(ch->channel_id);
934 uint8_t *p = send_buf;
935 int at_end = 256 - tail;
936 if (at_end < to_write)
938 memcpy(&ca.r2a_buffer[tail], p, at_end);
944 memcpy(&ca.r2a_buffer[tail], p, to_write);
945 tail = (tail + to_write) & 255;
947 channel_status[R2A_TAIL_OFFSET] = tail;
948 channel_status_updated |= A_EVENT_R2A_TAIL;
952 static void read_channel_status()
954 channel_status[A2R_TAIL_OFFSET] = ca.a2r_tail;
955 channel_status[R2A_HEAD_OFFSET] = ca.r2a_head;
956 channel_status[R2A_TAIL_OFFSET] = ca.r2a_tail;
957 channel_status[A2R_HEAD_OFFSET] = ca.a2r_head;
958 channel_status_updated = 0;
961 static void write_channel_status()
963 if (channel_status_updated != 0)
965 ca.r2a_tail = channel_status[R2A_TAIL_OFFSET];
966 ca.a2r_head = channel_status[A2R_HEAD_OFFSET];
968 pthread_mutex_lock(&mutex);
969 ca.a_events |= channel_status_updated;
970 pthread_mutex_unlock(&mutex);
972 channel_status_updated = 0;
976 static void close_all_logical_channels()
980 auto it = channels.begin();
981 while (it != channels.end())
983 LogicalChannel &ch = *it;
985 if (ch.association != nullptr)
987 create_and_send_msg(ch.association, MSG_RESET, ch.stream_id, nullptr, 0);
988 remove_association(&ch);
991 it = channels.erase(it);
995 static void handle_a314_irq(uint8_t events)
1000 if (events & R_EVENT_STARTED)
1002 if (!channels.empty())
1003 logger_info("Received STARTED event while logical channels are open -- closing channels\n");
1005 close_all_logical_channels();
1006 a314_device_started = true;
1009 if (!a314_device_started)
1012 read_channel_status();
1014 bool any_rcvd = receive_from_a2r();
1015 bool any_sent = flush_send_queue();
1017 if (any_rcvd || any_sent)
1018 write_channel_status();
1021 static void handle_client_connection_event(ClientConnection *cc, struct epoll_event *ev)
1023 if (ev->events & EPOLLERR)
1025 logger_warn("Received EPOLLERR for client connection\n");
1026 close_and_remove_connection(cc);
1030 if (ev->events & EPOLLIN)
1037 if (cc->payload.empty())
1039 left = sizeof(MessageHeader) - cc->bytes_read;
1040 dst = (uint8_t *)&(cc->header) + cc->bytes_read;
1044 left = cc->header.length - cc->bytes_read;
1045 dst = &cc->payload[cc->bytes_read];
1048 ssize_t r = read(cc->fd, dst, left);
1051 if (errno == EAGAIN || errno == EWOULDBLOCK)
1054 logger_error("Read failed unexpectedly with errno = %d\n", errno);
1060 logger_info("Received End-of-File on client connection\n");
1061 close_and_remove_connection(cc);
1066 cc->bytes_read += r;
1070 if (cc->payload.empty())
1072 if (cc->header.length == 0)
1074 logger_trace("header: length=%d, stream_id=%d, type=%d\n", cc->header.length, cc->header.stream_id, cc->header.type);
1075 handle_received_message(cc);
1079 cc->payload.resize(cc->header.length);
1084 logger_trace("header: length=%d, stream_id=%d, type=%d\n", cc->header.length, cc->header.stream_id, cc->header.type);
1085 handle_received_message(cc);
1086 cc->payload.clear();
1094 if (ev->events & EPOLLOUT)
1096 while (!cc->message_queue.empty())
1098 MessageBuffer &mb = cc->message_queue.front();
1100 int left = mb.data.size() - mb.pos;
1101 uint8_t *src = &mb.data[mb.pos];
1102 ssize_t r = write(cc->fd, src, left);
1105 if (errno == EAGAIN || errno == EWOULDBLOCK)
1107 else if (errno == ECONNRESET)
1109 close_and_remove_connection(cc);
1114 logger_error("Write failed unexpectedly with errno = %d\n", errno);
1121 cc->message_queue.pop_front();
1126 static void handle_server_socket_ready()
1128 struct sockaddr_in address;
1129 int alen = sizeof(struct sockaddr_in);
1131 int fd = accept(server_socket, (struct sockaddr *)&address, (socklen_t *)&alen);
1134 logger_error("Accept failed unexpectedly with errno = %d\n", errno);
1138 int status = fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
1141 logger_error("Unexpectedly unable to set close-on-exec flag on client socket descriptor; errno = %d\n", errno);
1145 status = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
1148 logger_error("Unexpectedly unable to set client socket to non blocking; errno = %d\n", errno);
1153 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
1155 connections.emplace_back();
1157 ClientConnection &cc = connections.back();
1159 cc.next_stream_id = 1;
1162 struct epoll_event ev;
1163 ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
1165 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) != 0)
1167 logger_error("epoll_ctl() failed unexpectedly with errno = %d\n", errno);
1172 static void main_loop()
1174 bool shutting_down = false;
1179 struct epoll_event ev;
1180 int timeout = shutting_down ? 10000 : -1;
1181 int n = epoll_pwait(epfd, &ev, 1, timeout, &original_sigset);
1186 logger_info("Received SIGTERM\n");
1188 shutdown_server_socket();
1190 while (!connections.empty())
1191 close_and_remove_connection(&connections.front());
1193 if (flush_send_queue())
1194 write_channel_status();
1196 if (!channels.empty())
1197 shutting_down = true;
1203 logger_error("epoll_pwait failed with unexpected errno = %d\n", errno);
1213 logger_error("epoll_pwait returned 0 which is unexpected since no timeout was set\n");
1219 if (ev.data.fd == irq_fds[1])
1222 if (read(irq_fds[1], &events, 1) != 1)
1224 logger_error("Read from interrupt socket pair, and unexpectedly didn't return 1 byte\n");
1228 handle_a314_irq(events);
1230 else if (ev.data.fd == server_socket)
1232 logger_trace("Epoll event: server socket is ready, events = %d\n", ev.events);
1233 handle_server_socket_ready();
1237 logger_trace("Epoll event: client socket is ready, events = %d\n", ev.events);
1239 auto it = connections.begin();
1240 for (; it != connections.end(); it++)
1242 if (it->fd == ev.data.fd)
1246 if (it == connections.end())
1248 logger_error("Got notified about an event on a client connection that supposedly isn't currently open\n");
1252 ClientConnection *cc = &(*it);
1253 handle_client_connection_event(cc, &ev);
1255 if (flush_send_queue())
1256 write_channel_status();
1262 static int init_driver()
1264 if (init_server_socket() != 0)
1267 int err = socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, irq_fds);
1270 logger_error("Unable to create socket pair, errno = %d\n", errno);
1274 epfd = epoll_create1(EPOLL_CLOEXEC);
1278 struct epoll_event ev;
1279 ev.events = EPOLLIN;
1280 ev.data.fd = irq_fds[1];
1281 if (epoll_ctl(epfd, EPOLL_CTL_ADD, irq_fds[1], &ev) != 0)
1284 ev.events = EPOLLIN;
1285 ev.data.fd = server_socket;
1286 if (epoll_ctl(epfd, EPOLL_CTL_ADD, server_socket, &ev) != 0)
1292 static void shutdown_driver()
1297 shutdown_server_socket();
1300 static void *thread_start(void *arg)
1307 static void write_r_events(uint8_t events)
1309 if (write(irq_fds[0], &events, 1) != 1)
1310 logger_error("Write to interrupt socket pair did not return 1\n");
1315 load_config_file(a314_config_file.c_str());
1317 int err = init_driver();
1324 err = pthread_create(&thread_id, NULL, thread_start, NULL);
1327 logger_error("pthread_create failed with err = %d\n", err);
1334 void a314_set_mem_base_size(unsigned int base, unsigned int size)
1336 ca.mem_base = htobe32(base);
1337 ca.mem_size = htobe32(size);
1340 void a314_process_events()
1342 if (ca.a_events & ca.a_enable)
1344 ps_write_16(0xdff09c, 0x8008);
1349 unsigned int a314_read_memory_8(unsigned int address)
1351 if (address >= sizeof(ca))
1355 if (address == offsetof(ComArea, a_events))
1357 pthread_mutex_lock(&mutex);
1360 pthread_mutex_unlock(&mutex);
1364 uint8_t *p = (uint8_t *)&ca;
1371 unsigned int a314_read_memory_16(unsigned int address)
1373 if (address >= sizeof(ca))
1376 uint16_t *p = (uint16_t *)&ca;
1377 return be16toh(p[address >> 1]);
1380 unsigned int a314_read_memory_32(unsigned int address)
1382 if (address >= sizeof(ca))
1385 uint32_t *p = (uint32_t *)&ca;
1386 return be32toh(p[address >> 2]);
1389 void a314_write_memory_8(unsigned int address, unsigned int value)
1391 if (address >= sizeof(ca))
1396 case offsetof(ComArea, a_events):
1397 // a_events is not writable.
1400 case offsetof(ComArea, r_events):
1402 write_r_events((uint8_t)value);
1407 uint8_t *p = (uint8_t *)&ca;
1408 p[address] = (uint8_t)value;
1414 void a314_write_memory_16(unsigned int address, unsigned int value)
1419 void a314_write_memory_32(unsigned int address, unsigned int value)
1424 void a314_set_config_file(char *filename)
1426 printf ("[A314] Set A314 config filename to %s.\n", filename);
1427 a314_config_file = std::string(filename);