- doc
[oweals/gnunet.git] / src / mesh / mesh_api.c
index ec5ddcf71d17fd5a8c899383acff924abd09d0ea..5fdfe612c2d43cfedbdd2ffbb8c6c99130ee492f 100644 (file)
@@ -98,6 +98,11 @@ union MeshInfoCB {
    */
   GNUNET_MESH_PeersCB peers_cb;
 
+  /**
+   * Monitor callback
+   */
+  GNUNET_MESH_PeerCB peer_cb;
+
   /**
    * Monitor callback
    */
@@ -1054,6 +1059,70 @@ process_get_peers (struct GNUNET_MESH_Handle *h,
 }
 
 
+/**
+ * Process a local peer info reply, pass info to the user.
+ *
+ * @param h Mesh handle.
+ * @param message Message itself.
+ */
+static void
+process_get_peer (struct GNUNET_MESH_Handle *h,
+                  const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_MESH_LocalInfoTunnel *msg;
+  size_t esize;
+  size_t msize;
+  unsigned int ch_n;
+  unsigned int c_n;
+  struct GNUNET_MeshHash *conns;
+  MESH_ChannelNumber *chns;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Tunnel messasge received\n");
+  if (NULL == h->info_cb.tunnel_cb)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  ignored\n");
+    return;
+  }
+
+  /* Verify message sanity */
+  msg = (struct GNUNET_MESH_LocalInfoTunnel *) message;
+  msize = ntohs (message->size);
+  esize = sizeof (struct GNUNET_MESH_LocalInfoTunnel);
+  if (esize > msize)
+  {
+    GNUNET_break_op (0);
+    h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
+    goto clean_cls;
+  }
+  ch_n = ntohl (msg->channels);
+  c_n = ntohl (msg->connections);
+  esize += ch_n * sizeof (MESH_ChannelNumber);
+  esize += c_n * sizeof (struct GNUNET_MeshHash);
+  if (msize != esize)
+  {
+    GNUNET_break_op (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "m:%u, e: %u (%u ch, %u conn)\n",
+                msize, esize, ch_n, c_n);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%u (%u ch, %u conn)\n",
+                sizeof (struct GNUNET_MESH_LocalInfoTunnel),
+                sizeof (MESH_ChannelNumber), sizeof (struct GNUNET_HashCode));
+    h->info_cb.tunnel_cb (h->info_cls, NULL, 0, 0, NULL, NULL, 0, 0);
+    goto clean_cls;
+  }
+
+  /* Call Callback with tunnel info. */
+  conns = (struct GNUNET_MeshHash *) &msg[1];
+  chns = (MESH_ChannelNumber *) &conns[c_n];
+  h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
+                        ch_n, c_n, chns, conns,
+                        ntohs (msg->estate), ntohs (msg->cstate));
+
+  clean_cls:
+  h->info_cb.tunnel_cb = NULL;
+  h->info_cls = NULL;
+}
+
+
 /**
  * Process a local reply about info on all tunnels, pass info to the user.
  *
@@ -1092,7 +1161,6 @@ process_get_tunnels (struct GNUNET_MESH_Handle *h,
 }
 
 
-
 /**
  * Process a local tunnel info reply, pass info to the user.
  *
@@ -1108,7 +1176,7 @@ process_get_tunnel (struct GNUNET_MESH_Handle *h,
   size_t msize;
   unsigned int ch_n;
   unsigned int c_n;
-  struct GNUNET_HashCode *conns;
+  struct GNUNET_MeshHash *conns;
   MESH_ChannelNumber *chns;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Get Tunnel messasge received\n");
@@ -1131,7 +1199,7 @@ process_get_tunnel (struct GNUNET_MESH_Handle *h,
   ch_n = ntohl (msg->channels);
   c_n = ntohl (msg->connections);
   esize += ch_n * sizeof (MESH_ChannelNumber);
-  esize += c_n * sizeof (struct GNUNET_HashCode);
+  esize += c_n * sizeof (struct GNUNET_MeshHash);
   if (msize != esize)
   {
     GNUNET_break_op (0);
@@ -1145,7 +1213,7 @@ process_get_tunnel (struct GNUNET_MESH_Handle *h,
   }
 
   /* Call Callback with tunnel info. */
-  conns = (struct GNUNET_HashCode *) &msg[1];
+  conns = (struct GNUNET_MeshHash *) &msg[1];
   chns = (MESH_ChannelNumber *) &conns[c_n];
   h->info_cb.tunnel_cb (h->info_cls, &msg->destination,
                 ch_n, c_n, chns, conns,
@@ -1156,6 +1224,7 @@ clean_cls:
   h->info_cls = NULL;
 }
 
+
 /**
  * Function to process all messages received from the service
  *
@@ -1205,6 +1274,9 @@ msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_PEERS:
     process_get_peers (h, msg);
     break;
+  case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_PEER:
+    process_get_peer (h, msg);
+    break;
   case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
     process_get_tunnels (h, msg);
     break;
@@ -1783,6 +1855,45 @@ GNUNET_MESH_get_peers_cancel (struct GNUNET_MESH_Handle *h)
 }
 
 
+/**
+ * Request information about a peer known to the running mesh peer.
+ * The callback will be called for the tunnel once.
+ * Only one info request (of any kind) can be active at once.
+ *
+ * WARNING: unstable API, likely to change in the future!
+ *
+ * @param h Handle to the mesh peer.
+ * @param id Peer whose tunnel to examine.
+ * @param callback Function to call with the requested data.
+ * @param callback_cls Closure for @c callback.
+ *
+ * @return #GNUNET_OK / #GNUNET_SYSERR
+ */
+int
+GNUNET_MESH_get_peer (struct GNUNET_MESH_Handle *h,
+                      const struct GNUNET_PeerIdentity *id,
+                      GNUNET_MESH_PeerCB callback,
+                      void *callback_cls)
+{
+  struct GNUNET_MESH_LocalInfo msg;
+
+  if (NULL != h->info_cb.peer_cb)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+
+  memset (&msg, 0, sizeof (msg));
+  msg.header.size = htons (sizeof (msg));
+  msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_PEER);
+  msg.peer = *id;
+  send_packet (h, &msg.header, NULL);
+  h->info_cb.peer_cb = callback;
+  h->info_cls = callback_cls;
+  return GNUNET_OK;
+}
+
+
 /**
  * Request information about tunnels of the running mesh peer.
  * The callback will be called for every tunnel of the service.