Пример #1
0
int __conman_util_block_write(int fd, const void * const buffer, size_t len)
{
  int towrite;
  int ret;
  char *buf;

  if (len == 0)
    {
      return OK;
    }

  buf = (char *)buffer;
  towrite = len;

  do
    {
      ret = write(fd, buf + len - towrite, towrite);
      if (ret < 0)
        {
          conman_dbg("write failed %d\n", errno);
          return ERROR;
        }

      towrite -= ret;
    } while (towrite > 0);

  return OK;
}
Пример #2
0
int conman_client_get_connection_status(struct conman_client_s *client,
                                        struct conman_status_s *status)
{
  sq_queue_t qevents;
  int ret;

  if (!status)
    {
      return ERROR;
    }

  ret = conman_send_req(client->sd, CONMAN_MSG_GET_CONNECTION_STATUS,
                        NULL, 0);
  if (ret != OK)
    {
      conman_dbg("conman_send_req failed\n");
      return ERROR;
    }

  sq_init(&qevents);

  ret = conman_wait_for_response(client, false, &qevents);
  if (ret != OK)
    {
      conman_dbg("conman communication failed\n");
      ret = ERROR;
      goto out;
    }

  if (client->respval != CONMAN_RESP_OK)
    {
      ret = ERROR;
      goto out;
    }

  DEBUGASSERT(sizeof(*status) == client->payloadlen);

  memcpy(status, client->payload, sizeof(*status));
  free(client->payload);
  client->payload = NULL;

  ret = OK;

out:
  handle_queued_events(client, &qevents);
  return ret;
}
Пример #3
0
int conman_client_set_connections_config(struct conman_client_s *client,
                                         const char *config)
{
  conman_dbg("%s\n", config);

  return do_command_no_payload(client, CONMAN_MSG_SET_CONNECTIONS_CONFIG,
                               config, strlen(config) + 1);
}
Пример #4
0
int __conman_cc3000_request_connection(struct conman_s *conman,
                                       enum conman_connection_type_e type)
{
  (void)conman;
  (void)type;
  conman_dbg("no WiFi configs available\n");
  return ERROR;
}
Пример #5
0
int conman_client_request_connection(struct conman_client_s *client,
                                     enum conman_connection_type_e type,
                                     uint32_t *connid)
{
  sq_queue_t qevents;
  int ret;

  ret = conman_send_req(client->sd, CONMAN_MSG_CREATE_CONNECTION, &type,
      sizeof(type));
  if (ret != OK)
    {
      conman_dbg("conman_send_req failed\n");
      return ERROR;
    }

  sq_init(&qevents);

  ret = conman_wait_for_response(client, false, &qevents);
  if (ret != OK)
    {
      conman_dbg("conman communication failed\n");
      ret = ERROR;
      goto out;
    }

  if (client->respval != CONMAN_RESP_OK)
    {
      ret = ERROR;
      goto out;
    }

  DEBUGASSERT(sizeof(*connid) == client->payloadlen);

  memcpy(connid, client->payload, sizeof(*connid));
  free(client->payload);
  client->payload = NULL;

  ret = OK;

out:
  handle_queued_events(client, &qevents);
  return ret;
}
Пример #6
0
static int do_command_no_payload(struct conman_client_s *client, uint8_t type,
                                 const void *buf, size_t buflen)
{
  sq_queue_t qevents;
  int ret;

  ret = conman_send_req(client->sd, type, buf, buflen);
  if (ret != OK)
    {
      conman_dbg("conman_send_req failed\n");
      return ERROR;
    }

  sq_init(&qevents);

  ret = conman_wait_for_response(client, false, &qevents);
  if (ret != OK)
    {
      conman_dbg("conman communication failed\n");
      ret = ERROR;
      goto out;
    }

  if (client->respval != CONMAN_RESP_OK)
    {
      ret = ERROR;
      goto out;
    }

  DEBUGASSERT(client->payload == NULL);

  ret = OK;

out:
  handle_queued_events(client, &qevents);
  return ret;
}
Пример #7
0
void __conman_send_boardcast_event(struct conman_s *conman,
                                   enum conman_msgs_ids type,
                                   const void *payload,
                                   size_t payloadlen)
{
  struct conman_sd_entry_s *client;
  struct conman_resp_hdr hdr = {};
  int send_count = 0;
  int ret;

  hdr.head.id = type;
  hdr.head.len = payloadlen;
  hdr.respval = CONMAN_RESP_EVENT;

  for (client = (struct conman_sd_entry_s *)sq_peek(&conman->server.sds);
       client != NULL;
       client = (struct conman_sd_entry_s *)sq_next(&client->entry))
    {
      if (!client->events_enabled)
        {
          continue;
        }

      ret = __conman_util_block_write(client->sd, &hdr, sizeof(hdr));
      if (ret < 0)
        {
          continue;
        }

      ret = __conman_util_block_write(client->sd, payload, hdr.head.len);
      if (ret < 0)
        {
          continue;
        }

      send_count++;
    }

  conman_dbg("send boardcast event (type=%d) to %d clients.\n",
             type, send_count);
}
Пример #8
0
int __conman_util_block_read(int fd, void *buffer, size_t len)
{
  int toread;
  int ret;
  char *buf;

  buf = (char *)buffer;
  toread = len;

  do
    {
      ret = read(fd, buf + len - toread, toread);
      if (ret < 0)
        {
          conman_dbg("read failed %d\n", errno);
          return ERROR;
        }

      toread -= ret;
    } while (toread > 0);

  return OK;
}
Пример #9
0
int conman_client_send_sms(struct conman_client_s *client,
                           const char *phonenumber, const char *message)
{
  struct conman_msg_send_sms_s sms = {};
  size_t receiverlen = strlen(phonenumber);
  size_t messagelen = strlen(message);
  struct iovec bufs[3];
  sq_queue_t qevents;
  int ret;

  sms.message_len = messagelen + 1;
  sms.receiver_len = receiverlen + 1;

  if (sms.message_len != messagelen + 1)
    {
      conman_dbg("Too long message\n");
      return ERROR;
    }

  if (sms.receiver_len != receiverlen + 1)
    {
      conman_dbg("Too long phone-number\n");
      return ERROR;
    }

  bufs[0].iov_base = &sms;
  bufs[0].iov_len = sizeof(sms);
  bufs[1].iov_base = (void *)phonenumber;
  bufs[1].iov_len = receiverlen + 1;
  bufs[2].iov_base = (void *)message;
  bufs[2].iov_len = messagelen + 1;

  ret = conman_send_reqv(client->sd, CONMAN_MSG_SEND_SMS, bufs, 3);
  if (ret != OK)
    {
      conman_dbg("conman_send_reqv failed\n");
      return ERROR;
    }

  sq_init(&qevents);

  ret = conman_wait_for_response(client, false, &qevents);
  if (ret != OK)
    {
      conman_dbg("conman communication failed\n");
      ret = ERROR;
      goto out;
    }

  DEBUGASSERT(client->payload == NULL);

  if (client->respval != CONMAN_RESP_OK)
    {
      ret = ERROR;
      goto out;
    }

  ret = OK;

out:
  handle_queued_events(client, &qevents);
  return ret;
}
Пример #10
0
int conman_client_init_events(struct conman_client_s *client,
                              conman_event_callback_fn_t event_callback,
                              void *event_priv)
{
  struct sockaddr_un myaddr;
  socklen_t addrlen;
  int ret;

  memset(client, 0, sizeof(*client));

  client->event_callback = event_callback;
  client->event_priv = event_priv;

  /* Create a new Unix domain socket */

  client->sd = socket(PF_LOCAL, SOCK_STREAM, 0);
  if (client->sd < 0)
    {
      conman_dbg("socket failed: %d\n", errno);
      return ERROR;
    }

  /* Connect the socket to the server */

  addrlen = strlen(CONFIG_CONMAN_LISTEN_SOCKET_ADDR);
  if (addrlen > UNIX_PATH_MAX - 1)
    {
      addrlen = UNIX_PATH_MAX - 1;
    }

  myaddr.sun_family = AF_LOCAL;
  strncpy(myaddr.sun_path, CONFIG_CONMAN_LISTEN_SOCKET_ADDR, addrlen);
  myaddr.sun_path[addrlen] = '\0';

  conman_dbg("Connecting to %s\n", CONFIG_CONMAN_LISTEN_SOCKET_ADDR);
  addrlen += sizeof(sa_family_t) + 1;
  ret = connect(client->sd, (struct sockaddr *)&myaddr, addrlen);
  if (ret < 0)
    {
      conman_dbg("connect failed: %d\n", errno);
      goto errout_with_socket;
    }

  conman_dbg("Connected\n");

  if (event_callback)
    {
      /* Enable events. */

      if (conman_client_enable_events(client) < 0)
        {
          conman_dbg("conman_client_enable_events failed\n");
          goto errout_with_socket;
        }
    }

  return OK;

errout_with_socket:
  close(client->sd);
  return ERROR;
}
Пример #11
0
static int conman_client_enable_events(struct conman_client_s *client)
{
  conman_dbg("\n");

  return do_command_no_payload(client, CONMAN_MSG_ENABLE_EVENTS, NULL, 0);
}
Пример #12
0
int conman_main(int argc, char **argv)
{
  struct conman_s *conman = &g_conman;
  int ubmodem_max_pfds = 0;
  int client_max_pfds = 0;
  struct pollfd *pfds;
  int ret;
  int maxfds = 0;
  int i;

  __conman_config_init(conman);

  ret = __conman_server_initialize(conman, &client_max_pfds);
  if (ret != OK)
    {
      conman_dbg("__conman_server_initialize failed");
      return EXIT_FAILURE;
    }

  maxfds += client_max_pfds; /* client fds */

  ret = __conman_ubmodem_initialize(conman, &ubmodem_max_pfds);
  if (ret != OK)
    {
      conman_dbg("__conman_ubmodem_initialize failed\n");
      return EXIT_FAILURE;
    }

  maxfds += ubmodem_max_pfds; /* modem fds */

  maxfds += __conman_cc3000_get_max_pollfds(conman); /* wifi fds */

  pfds = calloc(maxfds, sizeof(*pfds));
  if (!pfds)
    {
      conman_dbg("ubmodemd_daemon: Out-of-memory, tried to allocate %d.\n",
                 maxfds * sizeof(*pfds));

      return EXIT_FAILURE;
    }

  while (true)
    {
      int ubmodem_pos_fds, ubmodem_num_fds;
      int cc3000_pos_fds, cc3000_num_fds;
      int client_pos_fds, client_num_fds;
      int nfds;
      int timeout;

      nfds = 0;
      timeout = INT_MAX;

      /* Setup pollfd for listening socket */

      pfds[nfds].fd = conman->listensd;
      pfds[nfds].events = POLLIN;
      nfds++;

      /* Setup pollfds for clients and get timeout for timers. */

      client_pos_fds = nfds;
      __conman_server_setup_pollfds(conman, pfds, maxfds, &nfds, &timeout);
      client_num_fds = nfds - client_pos_fds;

      /* Setup pollfds for modem and get timeout for timers. */

      ubmodem_pos_fds = nfds;
      __conman_ubmodem_setup_pollfds(conman, pfds, maxfds, &nfds, &timeout);
      ubmodem_num_fds = nfds - ubmodem_pos_fds;

      /* Setup pollfds for cc3000 and get timeout for timers. */

      cc3000_pos_fds = nfds;
      __conman_cc3000_setup_pollfds(conman, pfds, maxfds, &nfds, &timeout);
      cc3000_num_fds = nfds - cc3000_pos_fds;

      ret = poll(pfds, nfds, timeout == INT_MAX ? -1 : timeout);
      if (ret < 0)
        {
          conman_dbg("poll failed %d\n", errno);
          break;
        }

      if (ret == 0)
        {
          conman_dbg("poll() timed out\n");
          __conman_ubmodem_poll_timedout(conman);
          continue;
        }

      for (i = 0; i < nfds && ret > 0; i++)
        {
          if (pfds[i].revents)
            {
              ret--;

              conman_dbg("poll index: %d, fd: %d, "
                         "events: 0x%02x, revents: 0x%02x\n",
                         i, pfds[i].fd, pfds[i].events, pfds[i].revents);
            }

          if (pfds[i].revents && pfds[i].fd == conman->listensd)
            {
              __conman_server_handle_pollin(conman, &pfds[i]);
            }
          else if (pfds[i].revents && client_num_fds > 0 &&
                   i >= client_pos_fds && i < (client_pos_fds + client_num_fds))
            {
              __conman_ctl_handle_pollin(conman, &pfds[i]);
            }
          else if (pfds[i].revents && cc3000_num_fds > 0 &&
                   i >= cc3000_pos_fds && i < (cc3000_pos_fds + cc3000_num_fds))
            {
              __conman_cc3000_handle_pollfds(conman, &pfds[i]);
            }
          else if (ubmodem_pos_fds == i && ubmodem_num_fds > 0)
            {
              int j;

              for (j = 1; j < ubmodem_num_fds; j++)
                {
                  if (pfds[i + j].revents)
                    {
                      ret--;
                    }
                }

              __conman_ubmodem_handle_pollfds(conman, &pfds[i],
                                              ubmodem_num_fds);

              i += ubmodem_num_fds - 1;
            }
        }
    }

  /* Reached only on poll() error */

  free(pfds);
  return EXIT_FAILURE;
}