Hi,

Using ICD_DBUS_API_STATISTICS_REQ, I'm able to get statistics about
established network connections.  I'd like to get network statistics
(specifically bytes sent and received) about recently terminated
network connections.

Currently, I figure out when a network connection is disconnecting by
listening for ICD_DBUS_API_STATE_SIG signals and checking if the
network connection status is ICD_STATE_DISCONNECTING.  When this
happens, I send an ICD_DBUS_API_STATISTICS_REQ to ICD2 specifying the
disconnecting network connection.  I get a reply that indicates that I
should see an ICD_DBUS_API_STATISTICS_SIG signal (one argument, value
1).  I don't see any statistics, however.

  (Cf. <http://maemo.org/api_refs/5.0/beta/icd2/group__dbus__api.html>)

To check that I'm correctly invoking ICD_DBUS_API_STATE_SIG, I changed
my code to do a stat when it sees that a connection is established
(ICD_DBUS_API_STATE_SIG signal with status equal to
ICD_STATE_CONNECTED).  ICD_DBUS_API_STATISTICS_REQ again returns 1,
but this time I indeed get statistics about the indicated connection.

What is the right way to get statistics about a closed network
connection?  Is this a bug in ICD2 (icd2 is version
0.87+fremantle9+0m5)?  If so, any suggestions for a work around?  I'd
really like to avoid aggressively polling.

Thanks,

Neal

Example code:


  DBusHandlerResult network_callback (DBusConnection *connection,
                                      DBusMessage *message,
                                      void *user_data)
  {
    if (dbus_message_is_signal (message,
                                ICD_DBUS_API_INTERFACE,
                                ICD_DBUS_API_STATE_SIG))
      {
        char *service_type = NULL;
        uint32_t service_attributes = 0;
        char *service_id = NULL;
        char *network_type = NULL;
        uint32_t network_attributes = 0;
        char *network_id = NULL;
        int network_id_len = 0;
        char *conn_error = NULL;
        int32_t status = 0;

        DBusError error;
        dbus_error_init (&error);

        if (! dbus_message_get_args (message, &error,
                                     DBUS_TYPE_STRING, &service_type,
                                     DBUS_TYPE_UINT32, &service_attributes,
                                     DBUS_TYPE_STRING, &service_id,
                                     DBUS_TYPE_STRING, &network_type,
                                     DBUS_TYPE_UINT32, &network_attributes,
                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
                                     &network_id, &network_id_len,
                                     DBUS_TYPE_STRING, &conn_error,
                                     DBUS_TYPE_UINT32, &status,
                                     DBUS_TYPE_INVALID))
          {
            debug (0, "Failed to grok "ICD_DBUS_API_STATE_SIG" reply: %s",
                   error.message);
            dbus_error_free (&error);
            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
          }

        if (status == ICD_STATE_DISCONNECTING)
          {
            DBusMessage *message = dbus_message_new_method_call
              (/* Service.  */ ICD_DBUS_API_INTERFACE,
               /* Object.  */ ICD_DBUS_API_PATH,
               /* Interface.  */ ICD_DBUS_API_INTERFACE,
               /* Method.  */ ICD_DBUS_API_STATISTICS_REQ);

            dbus_message_append_args
              (message,
               DBUS_TYPE_STRING, &service_type,
               DBUS_TYPE_UINT32, &service_attributes,
               DBUS_TYPE_STRING, &service_id,
               DBUS_TYPE_STRING, &network_type,
               DBUS_TYPE_UINT32, &network_attributes,
               DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
               &network_id, network_id_len,
               DBUS_TYPE_INVALID);

            DBusMessage *reply
              = dbus_connection_send_with_reply_and_block
              (connection, message, 60 * 1000, &error);
            if (dbus_error_is_set (&error))
              {
                debug (0, "Error sending to ICd2: %s", error.message);
                dbus_error_free (&error);
                goto stat_done;
              }

            int connected = 0;
            if (! dbus_message_get_args (reply, &error, 
                                         DBUS_TYPE_UINT32, &connected,
                                         DBUS_TYPE_INVALID))
              {
                debug (0, "Error parsing reply from ICd2: %s",
                       error.message);
                dbus_error_free (&error);
                goto stat_done;
              }
            else
              debug (0, "connected: %d", connected);

          stat_done:
            dbus_message_unref (message);
            dbus_message_unref (reply);
          }
      }
    else if (dbus_message_is_signal (message,
                                     ICD_DBUS_API_INTERFACE,
                                     ICD_DBUS_API_STATISTICS_SIG))
      {
        char *service_type = NULL;
        uint32_t service_attributes = 0;
        char *service_id = NULL;
        char *network_type = NULL;
        uint32_t network_attributes = 0;
        char *network_id = NULL;
        int network_id_len = 0;
        uint32_t time_active = 0;
        int32_t signal_strength = 0;
        uint32_t sent = 0;
        uint32_t received = 0;

        DBusError error;
        dbus_error_init (&error);
        if (! dbus_message_get_args (message, &error,
                                     DBUS_TYPE_STRING, &service_type,
                                     DBUS_TYPE_UINT32, &service_attributes,
                                     DBUS_TYPE_STRING, &service_id,
                                     DBUS_TYPE_STRING, &network_type,
                                     DBUS_TYPE_UINT32, &network_attributes,
                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
                                     &network_id, &network_id_len,
                                     DBUS_TYPE_UINT32, &time_active,
                                     DBUS_TYPE_INT32, &signal_strength,
                                     DBUS_TYPE_UINT32, &sent,
                                     DBUS_TYPE_UINT32, &received,
                                     DBUS_TYPE_INVALID))
          {
            debug (0, "Failed to grok "ICD_DBUS_API_STATISTICS_SIG" reply: %s",
                   error.message);
            dbus_error_free (&error);
          }
        else
          {
            printf ("Service: %s; %x; %s; "
                    "Network: %s; %x; %s; "
                    "active: %d; signal: %d; bytes: %d/%d",
                    service_type, service_attributes, service_id,
                    network_type, network_attributes, network_id,
                    time_active, signal_strength, sent, received);
          }
      }
  }


  DBusConnection *connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
  if (connection == NULL)
    {
      debug (0, "Failed to open connection to bus: %s", error.message);
      dbus_error_free (&error);
      return NULL;
    }

  /* Set up signal watchers.  */
  {
    char *matches[] =
      { /* For network state changes. */
        "type='signal',"
        "interface='"ICD_DBUS_API_INTERFACE"',"
        "member='"ICD_DBUS_API_STATE_SIG"',"
        "path='"ICD_DBUS_API_PATH"'",
        /* For network statistics.  */
        "type='signal',"
        "interface='"ICD_DBUS_API_INTERFACE"',"
        "member='"ICD_DBUS_API_STATISTICS_SIG"',"
        "path='"ICD_DBUS_API_PATH"'",
      };

    int i;
    for (i = 0; i < sizeof (matches) / sizeof (matches[0]); i ++)
      {
        char *match = matches[i];

        debug (2, "Adding match %s", match);
        dbus_bus_add_match (connection, match, &error);
        if (dbus_error_is_set (&error))
          {
            debug (0, "Error adding match %s: %s", match, error.message);
            dbus_error_free (&error);
          }
      }
  }

  if (! dbus_connection_add_filter (connection, network_callback, NULL, NULL))
    debug (0, "Failed to add filter: out of memory");


  while (dbus_connection_read_write_dispatch (connection, -1))
    ;
_______________________________________________
maemo-developers mailing list
maemo-developers@maemo.org
https://lists.maemo.org/mailman/listinfo/maemo-developers

Reply via email to