1 /** 2 * Copyright © 2016 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <poll.h> 20 #include <stdbool.h> 21 #include <stdint.h> 22 #include <termios.h> /* for speed_t */ 23 #include <time.h> 24 #include <systemd/sd-bus.h> 25 #include <sys/time.h> 26 #include <sys/un.h> 27 28 struct console; 29 struct config; 30 31 /* Handler API. 32 * 33 * Console data handlers: these implement the functions that process 34 * data coming out of the main tty device. 35 * 36 * Handlers are registered at link time using the console_handler_register() 37 * macro. We call each handler's ->init() function at startup, and ->fini() at 38 * exit. 39 * 40 * Handlers will almost always want to register a ringbuffer consumer, which 41 * provides data coming from the tty. Use cosole_register_ringbuffer_consumer() 42 * for this. To send data to the tty, use console_data_out(). 43 * 44 * If a handler needs to monitor a separate file descriptor for events, use the 45 * poller API, through console_poller_register(). 46 */ 47 struct handler; 48 49 struct handler_type { 50 const char *name; 51 struct handler *(*init)(const struct handler_type *type, 52 struct console *console, struct config *config); 53 void (*fini)(struct handler *handler); 54 int (*baudrate)(struct handler *handler, speed_t baudrate); 55 }; 56 57 struct handler { 58 const struct handler_type *type; 59 }; 60 61 /* NOLINTBEGIN(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */ 62 #define __handler_name(n) __handler_##n 63 #define _handler_name(n) __handler_name(n) 64 65 #ifndef __clang__ 66 #define handler_type_check(h) BUILD_ASSERT_OR_ZERO((h)->init && (h)->fini) 67 #else 68 /* clang doesn't seem to be able to constify the type ops */ 69 #define handler_type_check(h) 0 70 #endif 71 72 #define console_handler_register(h) \ 73 static const __attribute__((section("handlers"))) \ 74 __attribute__((used)) struct handler_type * \ 75 _handler_name(__COUNTER__) = (h) + handler_type_check(h) 76 /* NOLINTEND(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) */ 77 78 int console_data_out(struct console *console, const uint8_t *data, size_t len); 79 80 enum poller_ret { 81 POLLER_OK = 0, 82 POLLER_REMOVE, 83 POLLER_EXIT, 84 }; 85 86 typedef char(socket_path_t)[sizeof(((struct sockaddr_un *)NULL)->sun_path)]; 87 88 typedef enum poller_ret (*poller_event_fn_t)(struct handler *handler, 89 int revents, void *data); 90 typedef enum poller_ret (*poller_timeout_fn_t)(struct handler *handler, 91 void *data); 92 93 enum tty_device { 94 TTY_DEVICE_UNDEFINED = 0, 95 TTY_DEVICE_VUART, 96 TTY_DEVICE_UART, 97 TTY_DEVICE_PTY, 98 }; 99 100 struct console_server { 101 struct { 102 const char *kname; 103 char *dev; 104 int fd; 105 enum tty_device type; 106 union { 107 struct { 108 char *sysfs_devnode; 109 int sirq; 110 uint16_t lpc_addr; 111 } vuart; 112 struct { 113 speed_t baud; 114 } uart; 115 }; 116 } tty; 117 118 // All the pollfds are stored here, 119 // so 'poll' can operate on them. 120 // The other 'pollfd*' are just pointers to this array. 121 struct pollfd *pollfds; 122 size_t capacity_pollfds; 123 124 // index into pollfds 125 size_t tty_pollfd_index; 126 127 struct console *active; 128 }; 129 130 struct console { 131 // point back to the console server 132 // which we are a member of 133 struct console_server *server; 134 135 const char *console_id; 136 137 /* Socket name starts with null character hence we need length */ 138 socket_path_t socket_name; 139 ssize_t socket_name_len; 140 141 struct ringbuffer *rb; 142 143 struct handler **handlers; 144 long n_handlers; 145 146 struct poller **pollers; 147 long n_pollers; 148 149 // index into (struct console_server)->pollfds 150 size_t dbus_pollfd_index; 151 152 struct sd_bus *bus; 153 }; 154 155 /* poller API */ 156 struct poller { 157 struct handler *handler; 158 void *data; 159 poller_event_fn_t event_fn; 160 poller_timeout_fn_t timeout_fn; 161 struct timeval timeout; 162 bool remove; 163 164 // index into (struct console_server)->pollfds 165 size_t pollfd_index; 166 }; 167 168 struct poller *console_poller_register(struct console *console, 169 struct handler *handler, 170 poller_event_fn_t poller_fn, 171 poller_timeout_fn_t timeout_fn, int fd, 172 int events, void *data); 173 174 void console_poller_unregister(struct console *console, struct poller *poller); 175 176 void console_poller_set_events(struct console *console, struct poller *poller, 177 int events); 178 179 void console_poller_set_timeout(struct console *console, struct poller *poller, 180 const struct timeval *tv); 181 182 /* ringbuffer API */ 183 184 enum ringbuffer_poll_ret { 185 RINGBUFFER_POLL_OK = 0, 186 RINGBUFFER_POLL_REMOVE, 187 }; 188 189 typedef enum ringbuffer_poll_ret (*ringbuffer_poll_fn_t)(void *data, 190 size_t force_len); 191 192 struct ringbuffer_consumer; 193 194 struct ringbuffer { 195 uint8_t *buf; 196 size_t size; 197 size_t tail; 198 struct ringbuffer_consumer **consumers; 199 int n_consumers; 200 }; 201 202 struct ringbuffer_consumer { 203 struct ringbuffer *rb; 204 ringbuffer_poll_fn_t poll_fn; 205 void *poll_data; 206 size_t pos; 207 }; 208 209 struct ringbuffer *ringbuffer_init(size_t size); 210 void ringbuffer_fini(struct ringbuffer *rb); 211 212 struct ringbuffer_consumer * 213 ringbuffer_consumer_register(struct ringbuffer *rb, 214 ringbuffer_poll_fn_t poll_fn, void *data); 215 216 void ringbuffer_consumer_unregister(struct ringbuffer_consumer *rbc); 217 218 int ringbuffer_queue(struct ringbuffer *rb, uint8_t *data, size_t len); 219 220 size_t ringbuffer_dequeue_peek(struct ringbuffer_consumer *rbc, size_t offset, 221 uint8_t **data); 222 223 int ringbuffer_dequeue_commit(struct ringbuffer_consumer *rbc, size_t len); 224 225 size_t ringbuffer_len(struct ringbuffer_consumer *rbc); 226 227 /* console wrapper around ringbuffer consumer registration */ 228 struct ringbuffer_consumer * 229 console_ringbuffer_consumer_register(struct console *console, 230 ringbuffer_poll_fn_t poll_fn, void *data); 231 232 /* Console server API */ 233 void tty_init_termios(struct console_server *server); 234 235 /* socket paths */ 236 ssize_t console_socket_path(socket_path_t path, const char *id); 237 ssize_t console_socket_path_readable(const struct sockaddr_un *addr, 238 size_t addrlen, socket_path_t path); 239 240 /* utils */ 241 int write_buf_to_fd(int fd, const uint8_t *buf, size_t len); 242 243 /* console-dbus API */ 244 int dbus_init(struct console *console, 245 struct config *config __attribute__((unused))); 246 247 /* socket-handler API */ 248 int dbus_create_socket_consumer(struct console *console); 249 250 #ifndef offsetof 251 #define offsetof(type, member) ((unsigned long)&((type *)NULL)->member) 252 #endif 253 254 #define container_of(ptr, type, member) \ 255 ((type *)((void *)((ptr)-offsetof(type, member)))) 256 257 #define BUILD_ASSERT(c) \ 258 do { \ 259 char __c[(c) ? 1 : -1] __attribute__((unused)); \ 260 } while (0) 261 262 #define BUILD_ASSERT_OR_ZERO(c) (sizeof(char[(c) ? 1 : -1]) - 1) 263 264 // returns the index of that pollfd in server->pollfds 265 // we cannot return a pointer because 'realloc' may move server->pollfds 266 ssize_t console_server_request_pollfd(struct console_server *server, int fd, 267 short int events); 268 269 int console_server_release_pollfd(struct console_server *server, 270 size_t pollfd_index); 271