summaryrefslogtreecommitdiffstats
path: root/ctrl/libhicnctrl/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/libhicnctrl/src/modules')
-rw-r--r--ctrl/libhicnctrl/src/modules/hicn_light.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/ctrl/libhicnctrl/src/modules/hicn_light.c b/ctrl/libhicnctrl/src/modules/hicn_light.c
index 658043b7f..2716eefd5 100644
--- a/ctrl/libhicnctrl/src/modules/hicn_light.c
+++ b/ctrl/libhicnctrl/src/modules/hicn_light.c
@@ -593,6 +593,63 @@ NEXT:
return 0;
}
+static ssize_t hicnlight_prepare_face_delete(hc_sock_t *sock,
+ hc_request_t *request,
+ uint8_t **buffer) {
+ hc_request_t *current_request = hc_request_get_current(request);
+ hc_object_t *object = hc_request_get_object(current_request);
+ hc_data_t *data = hc_request_get_data(current_request);
+ hc_face_t *face = &object->face;
+
+ // XXX those objects are created on stack and expected to be valid across
+ // several calls. A quick fix is to make them static
+ static hc_object_t connection;
+
+ hc_request_state_t state;
+
+NEXT:
+ state = hc_request_get_state(current_request);
+ DEBUG("hicnlight_prepare_face_delete > %s", hc_request_state_str(state));
+
+ switch (state) {
+ case REQUEST_STATE_INIT:
+ _ASSERT(!data);
+
+ switch (face->type) {
+ case FACE_TYPE_HICN:
+ case FACE_TYPE_TCP:
+ case FACE_TYPE_UDP:
+ hc_request_set_state(current_request,
+ REQUEST_STATE_FACE_DELETE_CONNECTION_DELETE);
+ goto NEXT;
+ case FACE_TYPE_HICN_LISTENER:
+ case FACE_TYPE_TCP_LISTENER:
+ case FACE_TYPE_UDP_LISTENER:
+ case FACE_TYPE_UNDEFINED:
+ case FACE_TYPE_N:
+ return -99; // Not implemented
+ }
+
+ case REQUEST_STATE_FACE_DELETE_CONNECTION_DELETE:
+ if (hc_face_to_connection(face, &connection.connection, true) < 0) {
+ ERROR("[hc_face_create] Could not convert face to connection.");
+ return -1;
+ }
+ hc_request_set_state(current_request, REQUEST_STATE_COMPLETE);
+
+ return hicnlight_prepare_subrequest(sock, request, ACTION_DELETE,
+ OBJECT_TYPE_CONNECTION, &connection,
+ buffer);
+ case REQUEST_STATE_COMPLETE:
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
static ssize_t hicnlight_prepare_face_list(hc_sock_t *sock,
hc_request_t *request,
uint8_t **buffer) {
@@ -698,6 +755,8 @@ static ssize_t hicnlight_prepare_face(hc_sock_t *sock, hc_request_t *request,
switch (action) {
case ACTION_CREATE:
return hicnlight_prepare_face_create(sock, request, buffer);
+ case ACTION_DELETE:
+ return hicnlight_prepare_face_delete(sock, request, buffer);
case ACTION_LIST:
return hicnlight_prepare_face_list(sock, request, buffer);
default:
@@ -1006,6 +1065,91 @@ NEXT:
return 0;
}
+static ssize_t hicnlight_prepare_connection_delete(hc_sock_t *sock,
+ hc_request_t *request,
+ uint8_t **buffer) {
+ hc_request_t *current_request = hc_request_get_current(request);
+
+ hc_action_t action = hc_request_get_action(current_request);
+ hc_object_type_t object_type = hc_request_get_object_type(current_request);
+ hc_object_t *object = hc_request_get_object(current_request);
+
+ _ASSERT(action == ACTION_DELETE);
+ _ASSERT(object_type == OBJECT_TYPE_CONNECTION);
+
+ hc_data_t *data = hc_request_get_data(current_request);
+ hc_request_state_t state;
+
+NEXT:
+ state = hc_request_get_state(current_request);
+ DEBUG("hicnlight_prepare_connection_delete > %s",
+ hc_request_state_str(state));
+
+ switch (state) {
+ case REQUEST_STATE_INIT:
+ /* Two behaviours depending on the content of the connection id:
+ * - Valid Id : delete connection with provided ID
+ * - Invalid Id: Retrieve ID and then delete connection
+ *
+ * We assume connection has been already validated.
+ */
+ if (hc_connection_has_valid_id(&object->connection)) {
+ // Id is valid. Proceed with deleting the connection.
+ hc_request_set_state(current_request,
+ REQUEST_STATE_CONNECTION_DELETE_WITH_ID);
+ } else {
+ // Id is not valid. Try to retrieve it using the info in the connection.
+ hc_request_set_state(current_request, REQUEST_STATE_CONNECTION_GET);
+ }
+ goto NEXT;
+
+ case REQUEST_STATE_CONNECTION_DELETE_WITH_ID:
+ // We have a valid id. Let's delete the connection.
+ hc_request_reset_data(current_request);
+ hc_request_set_state(current_request, REQUEST_STATE_COMPLETE);
+ return hicnlight_prepare_generic(sock, request, buffer);
+
+ case REQUEST_STATE_CONNECTION_GET:
+ // Get the connection info from the forwarder.
+ hc_request_set_state(current_request,
+ REQUEST_STATE_CONNECTION_DELETE_AFTER_GET);
+ return hicnlight_prepare_subrequest(
+ sock, request, ACTION_GET, OBJECT_TYPE_CONNECTION, object, buffer);
+
+ case REQUEST_STATE_CONNECTION_DELETE_AFTER_GET:
+ // We got the response from the forwarder. If valid, let's take the ID and
+ // delete the connection by ID.
+ if (!data) return -1;
+
+ int rc = hc_data_get_result(data);
+ if (rc < 0) {
+ return -1;
+ }
+
+ if (hc_data_get_size(data) != 1) {
+ return -1;
+ }
+
+ _ASSERT(hc_data_get_object_type(data) == OBJECT_TYPE_CONNECTION);
+
+ object->connection.id = hc_data_get_object(data, 0)->connection.id;
+
+ hc_request_set_state(current_request,
+ REQUEST_STATE_CONNECTION_DELETE_WITH_ID);
+ goto NEXT;
+
+ case REQUEST_STATE_COMPLETE:
+ // Connection delete complete.
+ hc_data_set_complete(data);
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
static int hicnlight_recv(hc_sock_t *sock) {
hc_sock_light_data_t *s = (hc_sock_light_data_t *)sock->data;
int rc;
@@ -1120,6 +1264,16 @@ static ssize_t hicnlight_prepare(hc_sock_t *sock, hc_request_t *request,
hc_request_set(request, ACTION_CREATE, OBJECT_TYPE_SUBSCRIPTION, object);
break;
+ case ACTION_DELETE:
+ switch (object_type) {
+ case OBJECT_TYPE_CONNECTION:
+ return hicnlight_prepare_connection_delete(sock, request, buffer);
+ break;
+
+ default:
+ break;
+ }
+
default:
break;
}