wifi_wire.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <errno.h>
  4. #include <sys/un.h>
  5. #include <sys/file.h>
  6. #include <sys/socket.h>
  7. #include "common.h"
  8. #include "control.h"
  9. #include "nlusctl.h"
  10. #include "wifi.h"
  11. #define PAGE 4096
  12. /* Socket init is split in two parts: socket() call is performed early so
  13. that it could be used to resolve netdev names into ifis, but connection
  14. is delayed until send_command() to avoid waking up wimon and then dropping
  15. the connection because of a local error. */
  16. void init_heap_bufs(CTX)
  17. {
  18. char* ucbuf = malloc(2048);
  19. ctx->uc.brk = ucbuf;
  20. ctx->uc.ptr = ucbuf;
  21. ctx->uc.end = ucbuf + 2048;
  22. char* rxbuf = malloc(2048);
  23. ctx->ur.buf = rxbuf;
  24. ctx->ur.mptr = rxbuf;
  25. ctx->ur.rptr = rxbuf;
  26. ctx->ur.end = rxbuf + 2048;
  27. }
  28. static int connctl(CTX, struct sockaddr_un* addr, int miss)
  29. {
  30. int fd;
  31. if(ctx->fd > 0)
  32. close(ctx->fd);
  33. if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  34. fail("socket AF_UNIX: %m\n");
  35. ctx->fd = fd;
  36. if(connect(ctx->fd, (void*)addr, sizeof(*addr)) < 0) {
  37. if(errno != -ENOENT || !miss)
  38. fail("connect %s: %m\n", addr->sun_path);
  39. else
  40. return -1;
  41. }
  42. ctx->connected = 1;
  43. return 0;
  44. }
  45. void connect_wictl(CTX)
  46. {
  47. struct sockaddr_un wictl = { .sun_family = AF_UNIX, .sun_path = WICTL };
  48. connctl(ctx, &wictl, 0);
  49. }
  50. int connect_wictl_(CTX)
  51. {
  52. struct sockaddr_un wictl = { .sun_family = AF_UNIX, .sun_path = WICTL };
  53. return connctl(ctx, &wictl, 1);
  54. }
  55. void send_command(CTX)
  56. {
  57. int fd = ctx->fd;
  58. char* txbuf = ctx->uc.brk;
  59. int txlen = ctx->uc.ptr - ctx->uc.brk;
  60. if(!ctx->connected)
  61. fail("socket is not connected\n");
  62. if(writeall(fd, txbuf, txlen) < 0)
  63. fail("write: %m\n");
  64. }
  65. struct ucmsg* recv_reply(CTX)
  66. {
  67. struct urbuf* ur = &ctx->ur;
  68. int ret, fd = ctx->fd;
  69. if((ret = uc_recv(fd, ur, 1)) < 0)
  70. return NULL;
  71. return ur->msg;
  72. }
  73. struct ucmsg* send_recv_msg(CTX)
  74. {
  75. struct ucmsg* msg;
  76. send_command(ctx);
  77. while((msg = recv_reply(ctx)))
  78. if(msg->cmd <= 0)
  79. return msg;
  80. fail("connection lost\n");
  81. }
  82. int send_recv_cmd(CTX)
  83. {
  84. struct ucmsg* msg = send_recv_msg(ctx);
  85. if(msg->cmd < 0)
  86. errno = -msg->cmd;
  87. return msg->cmd;
  88. }
  89. void send_check(CTX)
  90. {
  91. if(send_recv_cmd(ctx) < 0)
  92. fail("send: %m\n");
  93. }