diff --git a/Makefile.am b/Makefile.am index f6daea991a5e4b38a25941b0de8dabbfb6f13b30..66e30832a1960ce58e419a9983bc772ad2d103ab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,12 +5,15 @@ gbridge_CFLAGS += `pkg-config --cflags libnl-3.0 libnl-genl-3.0` gbridge_CFLAGS += `pkg-config --cflags bluez` gbridge_SOURCES = main.c \ - netlink.c \ debug.c \ greybus.c \ controller.c \ protocols/svc.c +if NETLINK +gbridge_SOURCES += controllers/gb_netlink.c +endif + if TPCIP gbridge_SOURCES += controllers/tcpip.c endif diff --git a/configure.ac b/configure.ac index 3f95c11cdf27bd1f3d2c9f11b8f87216c4b3d879..a1c509e855c616e1195e2c2e20af40e2265e8751 100644 --- a/configure.ac +++ b/configure.ac @@ -53,6 +53,16 @@ AC_ARG_ENABLE([uart], esac]) AM_CONDITIONAL([UART], [test x$uart = xtrue]) +AC_ARG_ENABLE([netlink], +[ --enable-netlink Enable Netlink], +[case "${enableval}" in + yes) netlink=true ; + AC_DEFINE([NETLINK], [1], ["Netlink support"]) ;; + no) netlink=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-netlink]) ;; +esac]) +AM_CONDITIONAL([NETLINK], [test x$netlink = xtrue]) + AC_ARG_VAR([GBDIR], ["greybus sources directory"]) AS_IF([test "$GBDIR" = ""], [ AC_MSG_ERROR([Environment variable GBDIR needs to be set]) diff --git a/controller.c b/controller.c index ff75668ea5b97ce2c39dd5c0dc9ad5721d6814fe..24a8ed2de925c7893da72a87f39eecc8424b7cc2 100644 --- a/controller.c +++ b/controller.c @@ -22,7 +22,6 @@ #include <debug.h> #include <gbridge.h> -#include <netlink.h> #include <controller.h> static @@ -164,7 +163,7 @@ static void *interface_recv(void *data) continue; } - ret = netlink_send(conn->cport1_id, buffer, ret); + ret = controller_write(AP_INTF_ID, conn->cport1_id, buffer, ret); if (ret < 0) { pr_err("Failed to transmit data\n"); } @@ -299,7 +298,8 @@ void *connection_recv(void *data) pr_dump(buffer, ret); - ret = netlink_send(conn->cport1_id, buffer, ret); + ret = controller_write(conn->intf1->id, conn->cport1_id, + buffer, ret); if (ret < 0) { pr_err("Failed to transmit data\n"); } @@ -391,6 +391,9 @@ void register_controller(struct controller *controller) static void register_controllers(void) { +#ifdef NETLINK + register_controller(&netlink_controller); +#endif #ifdef HAVE_LIBBLUETOOTH register_controller(&bluetooth_controller); #endif diff --git a/controller.h b/controller.h index 14748c51f851aac1e4c57fa311226f7bf43d5344..1c1f58f5d1c8c2b600975a5a6ac64dade51438a7 100644 --- a/controller.h +++ b/controller.h @@ -80,6 +80,7 @@ struct controller { extern struct controller bluetooth_controller; extern struct controller tcpip_controller; +extern struct controller netlink_controller; void cport_pack(struct gb_operation_msg_hdr *header, uint16_t cport_id); uint16_t cport_unpack(struct gb_operation_msg_hdr *header); diff --git a/netlink.c b/controllers/gb_netlink.c similarity index 83% rename from netlink.c rename to controllers/gb_netlink.c index f8ae29cd974e1814ba009289fc79e062f67c00b3..c67de4552d5e60f5c4b94b52f42cc1ceff8c65e7 100644 --- a/netlink.c +++ b/controllers/gb_netlink.c @@ -91,7 +91,7 @@ static struct genl_ops ops = { .o_ncmds = ARRAY_SIZE(cmds), }; -int netlink_send(uint16_t hd_cport_id, void *data, size_t len) +int netlink_write(struct connection *conn, void *data, size_t len) { struct nl_data *nl_data; struct nl_msg *msg; @@ -120,7 +120,7 @@ int netlink_send(uint16_t hd_cport_id, void *data, size_t len) goto err_msg_free; } - nla_put_u32(msg, GB_NL_A_CPORT, hd_cport_id); + nla_put_u32(msg, GB_NL_A_CPORT, conn->cport1_id); nla_put_data(msg, GB_NL_A_DATA, nl_data); ret = nl_send_auto(sock, msg); if (ret < 0) @@ -172,6 +172,27 @@ static int netlink_hd_reset(void) void *nl_recv_cb(void *data) { int ret; + struct controller *ctrl = data; + + if (!interface_create(ctrl, 0, 0, 0, NULL)) { + pr_err("Failed to create AP interface\n"); + return NULL; + } + + ret = svc_register_driver(); + if (ret) { + pr_err("Failed to register SVC\n"); + return NULL; + } + + /* HACK: create a connection for SVC */ + connection_create(0, 0, 0, 0); + + ret = svc_init(); + if (ret) { + pr_err("Failed to init SVC\n"); + return NULL; + } while (1) { ret = nl_recvmsgs_default(sock); @@ -189,7 +210,7 @@ int events_cb(struct nl_msg *msg, void *arg) return genl_handle_msg(msg, arg); } -int netlink_init(void) +int netlink_init(struct controller * ctrl) { int ret; @@ -212,7 +233,7 @@ int netlink_init(void) goto error; } - return pthread_create(&nl_recv_thread, NULL, nl_recv_cb, NULL); + return pthread_create(&nl_recv_thread, NULL, nl_recv_cb, ctrl); error: nl_close(sock); @@ -221,20 +242,28 @@ int netlink_init(void) return ret; } -void netlink_loop(void) +int netlink_interface_create(struct interface *intf) { - pthread_join(nl_recv_thread, NULL); + intf->id = 0; + + return 0; } -void netlink_cancel(void) +void netlink_exit(struct controller * ctrl) { svc_watchdog_disable(); pthread_cancel(nl_recv_thread); -} + pthread_join(nl_recv_thread, NULL); -void netlink_exit(void) -{ netlink_hd_reset(); nl_close(sock); nl_socket_free(sock); } + +struct controller netlink_controller = { + .name = "netlink", + .init = netlink_init, + .exit = netlink_exit, + .write = netlink_write, + .interface_create = netlink_interface_create, +}; \ No newline at end of file diff --git a/netlink.h b/controllers/netlink.h similarity index 100% rename from netlink.h rename to controllers/netlink.h diff --git a/greybus.c b/greybus.c index 1afa19ceb820a55b284d0ae302fdf6b09c372a6f..977de0004d62703b21f47eb6efbfcf10db07f9e5 100644 --- a/greybus.c +++ b/greybus.c @@ -25,7 +25,6 @@ #include <gb_netlink.h> #include "gbridge.h" -#include "netlink.h" #include "controller.h" static TAILQ_HEAD(operation_head, operation) operations; @@ -168,7 +167,7 @@ int greybus_send_request(uint8_t intf_id, uint16_t cport_id, op->cport_id = cport_id; TAILQ_INSERT_TAIL(&operations, op, cnode); - ret = netlink_send(cport_id, op->req, len); + ret = controller_write(intf_id, cport_id, op->req, len); if (ret < 0) return ret; @@ -184,7 +183,7 @@ static int greybus_send_response(uint8_t intf_id, uint16_t cport_id, len = gb_operation_msg_size(op->resp); pr_dump(op->resp, len); - ret = netlink_send(cport_id, op->resp, len); + ret = controller_write(intf_id, cport_id, op->resp, len); if (ret < 0) return ret; diff --git a/main.c b/main.c index 51c54ae2e5e9b796b96c3d2d5eb2ee97d89ca8f6..c283a194748889286e8a25a46e7d8fae38a6aa82 100644 --- a/main.c +++ b/main.c @@ -24,9 +24,10 @@ #include <controller.h> #include "gbridge.h" -#include "netlink.h" #include "controllers/uart.h" +int run; + static void help(void) { printf("gbridge: Greybus bridge application\n" @@ -41,7 +42,7 @@ static void help(void) static void signal_handler(int sig) { - netlink_cancel(); + run = 0; } int main(int argc, char *argv[]) @@ -79,40 +80,17 @@ int main(int argc, char *argv[]) return ret; } - ret = netlink_init(); - if (ret) { - pr_err("Failed to init netlink\n"); - return ret; - } - - ret = svc_init(); - if (ret) { - pr_err("Failed to init SVC\n"); - goto err_netlink_exit; - } - if (uart) { ret = register_uart_controller(uart, baudrate); - if (ret) { - pr_err("Failed to init uart controller\n"); - goto err_netlink_exit; - } + if (ret) + return ret; } + run = 1; controllers_init(); - - netlink_loop(); - + while(run) + sleep(1); controllers_exit(); - netlink_exit(); - return 0; - - err_netlink_exit: - netlink_cancel(); - netlink_loop(); - netlink_exit(); - - return ret; }