clique topology
[oweals/gnunet.git] / src / testbed / testbed_api_services.c
index ea7b50def5c62a5f1ea7c5c92512b116dcedd148..16ea060777307c7f50dd93c687648f91b730fdf1 100644 (file)
  * States for Service connect operations
  */
 enum State
-  {
-    /**
-     * Initial state
-     */
-    INIT,
-
-    /**
-     * The configuration request has been sent
-     */
-    CFG_REQUEST_QUEUED,
+{
+  /**
+   * Initial state
+   */
+  INIT,
 
-    /**
-     * connected to service
-     */
-    SERVICE_CONNECTED,
+  /**
+   * The configuration request has been sent
+   */
+  CFG_REQUEST_QUEUED,
+  
+  /**
+   * connected to service
+   */
+  SERVICE_CONNECTED
 
-    /**
-     * 
-     */
-  };
+};
 
 
 /**
@@ -79,7 +76,7 @@ struct ServiceConnectData
    * Service name
    */
   char *service_name;
-  
+
   /**
    * Closure for operation event
    */
@@ -110,11 +107,21 @@ struct ServiceConnectData
    */
   void *op_result;
 
+  /**
+   * The operation completion callback
+   */
+  GNUNET_TESTBED_ServiceConnectCompletionCallback cb;
+
+  /**
+   * The closure for operation completion callback
+   */
+  void *cb_cls;
+
   /**
    * State information
    */
   enum State state;
-  
+
 };
 
 
@@ -125,30 +132,45 @@ struct ServiceConnectData
  * @param cls ServiceConnectData
  * @param msg message received, NULL on timeout or fatal error
  */
-static void 
-configuration_receiver (void *cls,
-                        const struct GNUNET_MessageHeader *msg)
+static void
+configuration_receiver (void *cls, const struct GNUNET_MessageHeader *msg)
 {
   struct ServiceConnectData *data = cls;
-  const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *imsg;
-  struct GNUNET_TESTBED_Controller *c;  
-  struct GNUNET_TESTBED_EventInformation info;  
-  
-  imsg = (const struct GNUNET_TESTBED_PeerConfigurationInformationMessage *)
-    msg;
-  data->cfg = GNUNET_TESTBED_get_config_from_peerinfo_msg_ (imsg);
-  data->op_result = data->ca (data->cada_cls, data->cfg);
+  struct GNUNET_TESTBED_Controller *c;
+  const char *emsg;
+  struct GNUNET_TESTBED_EventInformation info;
+  uint16_t mtype;
+
+  c = data->peer->controller;
+  mtype = ntohs (msg->type);
+  emsg = NULL;
   info.type = GNUNET_TESTBED_ET_OPERATION_FINISHED;
   info.details.operation_finished.operation = data->operation;
   info.details.operation_finished.op_cls = data->op_cls;
+  if (GNUNET_MESSAGE_TYPE_TESTBED_OPERATIONFAILEVENT == mtype)
+  {
+    emsg = GNUNET_TESTBED_parse_error_string_ ((const struct
+                                                GNUNET_TESTBED_OperationFailureEventMessage
+                                                *) msg);
+    if (NULL == emsg)
+      emsg = "Unknown error";
+    info.details.operation_finished.emsg = emsg;
+    info.details.operation_finished.generic = NULL;
+    goto call_cb;
+  }  
+  data->cfg = GNUNET_TESTBED_extract_config_ (msg);
+  GNUNET_assert (NULL == data->op_result);
+  data->op_result = data->ca (data->cada_cls, data->cfg);  
   info.details.operation_finished.emsg = NULL;
-  info.details.operation_finished.pit = GNUNET_TESTBED_PIT_GENERIC;
-  info.details.operation_finished.op_result.generic = data->op_result;
-  c = data->peer->controller;
+  info.details.operation_finished.generic = data->op_result;
   data->state = SERVICE_CONNECTED;
-  if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask))
-      && (NULL != c->cc))
-      c->cc (c->cc_cls, &info);
+  
+ call_cb:
+  if ((0 != (GNUNET_TESTBED_ET_OPERATION_FINISHED & c->event_mask)) &&
+      (NULL != c->cc))
+    c->cc (c->cc_cls, &info);
+  if (NULL != data->cb)
+    data->cb (data->cb_cls, data->operation, data->op_result, emsg);
 }
 
 
@@ -157,23 +179,23 @@ configuration_receiver (void *cls,
  *
  * @param cls the closure from GNUNET_TESTBED_operation_create_()
  */
-static void 
+static void
 opstart_service_connect (void *cls)
 {
   struct ServiceConnectData *data = cls;
   struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg;
-  struct GNUNET_TESTBED_Controller *c;  
-  uint64_t op_id;  
-  
+  struct GNUNET_TESTBED_Controller *c;
+  uint64_t op_id;
+
   GNUNET_assert (NULL != data);
   GNUNET_assert (NULL != data->peer);
-  c = data->peer->controller;  
-  op_id = c->operation_counter++;  
-  msg = GNUNET_TESTBED_generate_peergetconfig_msg_ (data->peer->unique_id,
-                                                    op_id);
+  c = data->peer->controller;
+  op_id = GNUNET_TESTBED_get_next_op_id (c);
+  msg =
+      GNUNET_TESTBED_generate_peergetconfig_msg_ (data->peer->unique_id, op_id);
   data->opc =
-    GNUNET_TESTBED_forward_operation_msg_ (c, op_id, &msg->header,
-                                           &configuration_receiver, data);
+      GNUNET_TESTBED_forward_operation_msg_ (c, op_id, &msg->header,
+                                             &configuration_receiver, data);
   GNUNET_free (msg);
   data->state = CFG_REQUEST_QUEUED;
 }
@@ -185,7 +207,7 @@ opstart_service_connect (void *cls)
  *
  * @param cls the closure from GNUNET_TESTBED_operation_create_()
  */
-static void 
+static void
 oprelease_service_connect (void *cls)
 {
   struct ServiceConnectData *data = cls;
@@ -223,6 +245,8 @@ oprelease_service_connect (void *cls)
  * @param op_cls closure to pass in operation event
  * @param peer peer that runs the service
  * @param service_name name of the service to connect to
+ * @param cb the callback to call when this operation finishes
+ * @param cb_cls closure for the above callback
  * @param ca helper function to establish the connection
  * @param da helper function to close the connection
  * @param cada_cls closure for ca and da
@@ -232,6 +256,8 @@ struct GNUNET_TESTBED_Operation *
 GNUNET_TESTBED_service_connect (void *op_cls,
                                struct GNUNET_TESTBED_Peer *peer,
                                const char *service_name,
+                                GNUNET_TESTBED_ServiceConnectCompletionCallback cb,
+                                void *cb_cls,
                                GNUNET_TESTBED_ConnectAdapter ca,
                                GNUNET_TESTBED_DisconnectAdapter da,
                                void *cada_cls)
@@ -245,14 +271,18 @@ GNUNET_TESTBED_service_connect (void *op_cls,
   data->op_cls = op_cls;
   data->peer = peer;
   data->state = INIT;
-  data->operation = 
-    GNUNET_TESTBED_operation_create_ (data, &opstart_service_connect,
-                                      &oprelease_service_connect);
-  GNUNET_TESTBED_operation_queue_insert_
-    (peer->controller->opq_parallel_service_connections, data->operation);
-  GNUNET_TESTBED_operation_queue_insert_
-    (peer->controller->opq_parallel_operations, data->operation);
-  return data->operation;  
+  data->cb = cb;
+  data->cb_cls = cb_cls;
+  data->operation =
+      GNUNET_TESTBED_operation_create_ (data, &opstart_service_connect,
+                                        &oprelease_service_connect);
+  GNUNET_TESTBED_operation_queue_insert_ (peer->
+                                          controller->opq_parallel_service_connections,
+                                          data->operation);
+  GNUNET_TESTBED_operation_queue_insert_ (peer->
+                                          controller->opq_parallel_operations,
+                                          data->operation);
+  return data->operation;
 }
 
 /* end of testbed_api_services.c */