Add Connect() method to console DBUS object
Added new poller and consumer for the console DBUS data.
Note: We initially developed SocketName attribute but it is now
deprecated/removed.
The tree of default object:
$ busctl tree xyz.openbmc_project.Console.default
`-/xyz
`-/xyz/openbmc_project
`-/xyz/openbmc_project/console
`-/xyz/openbmc_project/console/default
The introspect of default console:
$ busctl introspect xyz.openbmc_project.Console.default /xyz/openbmc_project/console/default
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
org.freedesktop.DBus.Introspectable interface - - -
.Introspect method - s -
org.freedesktop.DBus.Peer interface - - -
.GetMachineId method - s -
.Ping method - - -
org.freedesktop.DBus.Properties interface - - -
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
xyz.openbmc_project.Console.Access interface - - -
.Connect method - h -
xyz.openbmc_project.console interface - - -
.setBaudRate method u x -
.baudrate property u 0 -
Tested:
Performed integration testing with bmcweb.
Change-Id: I2444b1083cf26536f43c6f6b4b0857a2921c4f78
Signed-off-by: Ninad Palsule <ninadpalsule@us.ibm.com>
diff --git a/socket-handler.c b/socket-handler.c
index a0ec53e..5f9d383 100644
--- a/socket-handler.c
+++ b/socket-handler.c
@@ -341,6 +341,81 @@
return POLLER_OK;
}
+/* Create socket pair and register one end as poller/consumer and return
+ * the other end to the caller.
+ * Return file descriptor on success and negative value on error.
+ */
+int dbus_create_socket_consumer(struct console *console)
+{
+ struct socket_handler *sh = NULL;
+ struct client *client;
+ int fds[2];
+ int i;
+ int rc = -1;
+ int n;
+
+ for (i = 0; i < console->n_handlers; i++) {
+ if (strcmp(console->handlers[i]->name, "socket") == 0) {
+ sh = to_socket_handler(console->handlers[i]);
+ break;
+ }
+ }
+
+ if (!sh) {
+ return -ENOSYS;
+ }
+
+ /* Create a socketpair */
+ rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+ if (rc < 0) {
+ warn("Failed to create socket pair");
+ return -errno;
+ }
+
+ client = malloc(sizeof(*client));
+ if (client == NULL) {
+ warnx("Failed to allocate client structure.");
+ rc = -ENOMEM;
+ goto close_fds;
+ }
+ memset(client, 0, sizeof(*client));
+
+ client->sh = sh;
+ client->fd = fds[0];
+ client->poller = console_poller_register(sh->console, &sh->handler,
+ client_poll, client_timeout,
+ client->fd, POLLIN, client);
+ client->rbc = console_ringbuffer_consumer_register(
+ sh->console, client_ringbuffer_poll, client);
+ if (client->rbc == NULL) {
+ warnx("Failed to register a consumer.\n");
+ rc = -ENOMEM;
+ goto free_client;
+ }
+
+ n = sh->n_clients++;
+
+ /*
+ * We're managing an array of pointers to aggregates, so don't warn about
+ * sizeof() on a pointer type.
+ */
+ /* NOLINTBEGIN(bugprone-sizeof-expression) */
+ sh->clients =
+ reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients));
+ /* NOLINTEND(bugprone-sizeof-expression) */
+ sh->clients[n] = client;
+
+ /* Return the second FD to caller. */
+ return fds[1];
+
+free_client:
+ free(client);
+close_fds:
+ close(fds[0]);
+ close(fds[1]);
+ return rc;
+}
+
static int socket_init(struct handler *handler, struct console *console,
struct config *config __attribute__((unused)))
{