From 8e12c8e42cc9ea9d12e55a3a0d8fbcb211504c04 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Wed, 23 Oct 2019 17:55:00 +0200 Subject: [HICN-352] facemgr event loop enhancement; timer support & async hicn-light interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I920a0eb091d826e1eb0d1f786fb0b437487f7ff7 Signed-off-by: Jordan Augé --- .../facemgr/src/interfaces/hicn_light/hicn_light.c | 224 ++++++++++++++++++--- 1 file changed, 195 insertions(+), 29 deletions(-) (limited to 'ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c') diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c index 2fdc3f7c3..1f20177c2 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c +++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c @@ -17,6 +17,7 @@ * \file interfaces/hicn_light/hicn_light.c * \brief hICN light interface */ +#include #include #include // snprintf #include // time @@ -32,34 +33,43 @@ #define DEFAULT_ROUTE_COST 0 +#define INTERVAL_MS 1000 + typedef enum { HL_STATE_UNDEFINED, + HL_STATE_CONNECTING, HL_STATE_FACES_SENT, HL_STATE_DONE, } hl_state_t; typedef struct { - hc_sock_t * s; + hc_sock_t * s; /* NULL means no active socket */ hl_state_t state; + int timer_fd; /* 0 means no active timer */ } hl_data_t; +/* Forward declarations */ +int hl_timeout(interface_t * interface, int fd, void * unused); + int hl_process_state(interface_t * interface) { hl_data_t * data = (hl_data_t *)interface->data; - hc_data_t * faces; #if 0 char buf[MAXSZ_FACE]; #endif switch(data->state) { - case HL_STATE_UNDEFINED: - if (hc_face_list(data->s, &faces) < 0) { + case HL_STATE_UNDEFINED: // FIXME + case HL_STATE_CONNECTING: // FIXME + if (hc_face_list_async(data->s) < 0) { /* Blocking call */ printf("Could not retrieve face list\n"); return -1; } + break; +#if 0 foreach_face(f, faces) { #if 0 hc_face_snprintf(buf, MAXSZ_FACE, f); @@ -67,9 +77,10 @@ int hl_process_state(interface_t * interface) #endif facelet_t * facelet = facelet_create_from_face(&f->face); facelet_set_event(facelet, FACELET_EVENT_GET); - facelet_raise_event(facelet, interface); + interface_raise_event(interface, facelet); } break; +#endif case HL_STATE_FACES_SENT: break; @@ -81,36 +92,132 @@ int hl_process_state(interface_t * interface) return 0; } -int hl_initialize(interface_t * interface, void * cfg) + +int +hl_after_connect(interface_t * interface) { - hl_data_t * data = malloc(sizeof(hl_data_t)); - if (!data) { - ERROR("[hicn_light] Out of memory!"); - goto ERR_MALLOC; + hl_data_t * data = interface->data; + // XXX cancel timer + + /* File descriptor for control socket operations */ + if (interface_register_fd(interface, hc_sock_get_fd(data->s), NULL) < 0) { + ERROR("[hc_connect] Error registering fd"); + goto ERR_FD; + } + + data->state = HL_STATE_UNDEFINED; + + hl_process_state(interface); + + return 0; + + //interface_unregister_fd(interface, hc_sock_get_fd(data->s)); +ERR_FD: + return -1; +} + +int _hl_connect(interface_t * interface); + +int +hl_connect_timeout(interface_t * interface, int fd, void * unused) +{ + int rc = _hl_connect(interface); + if (rc < 0) { + ERROR("[hl_initialize] Error during connection reattempt; next attempt in %ds", INTERVAL_MS / 1000); + return -1; } + if (interface_unregister_timer(interface, fd) < 0) { + ERROR("[hl_connect_timeout] Could not cancel timer after successful connect"); + } + + /* Connect success */ + return hl_after_connect(interface); +} + + +int +_hl_connect(interface_t * interface) +{ + hl_data_t * data = interface->data; + assert(!data->s); + data->s = hc_sock_create(); if (data->s <= 0) { - ERROR("[hicn_light] Could not create control socket"); + ERROR("[hc_connect] Could not create control socket"); goto ERR_SOCK; } if (hc_sock_connect(data->s) < 0) { - ERROR("[hicn_light] Could not connect control socket"); + ERROR("[hc_connect] Could not connect control socket"); goto ERR_CONNECT; } - data->state = HL_STATE_UNDEFINED; + return hl_after_connect(interface); + +ERR_CONNECT: + hc_sock_free(data->s); + data->s = NULL; +ERR_SOCK: + return -1; + +} + +int hl_disconnect(interface_t * interface) +{ + hl_data_t * data = (hl_data_t *) interface->data; + if (data->timer_fd > 0) + interface_unregister_timer(interface, data->timer_fd); + + if (data->s) { + interface_unregister_fd(interface, hc_sock_get_fd(data->s)); + hc_sock_free(data->s); + } + + return 0; +} + +int +hl_connect(interface_t * interface) +{ + hl_data_t * data = interface->data; + + if (_hl_connect(interface) >= 0) + return 0; + + /* Timer for managing the connection to the forwarder */ + DEBUG("Connection to forwarder failed... next retry in %ds", INTERVAL_MS / 1000); + data->timer_fd = interface_register_timer(interface, INTERVAL_MS, hl_connect_timeout, NULL); + if (data->timer_fd < 0) { + ERROR("[hc_connect] Could not initialize reattempt timer"); + return -1; + } + + return 0; +} + +int +hl_initialize(interface_t * interface, void * cfg) +{ + hl_data_t * data = malloc(sizeof(hl_data_t)); + if (!data) { + ERROR("[hicn_light] Out of memory!"); + goto ERR_MALLOC; + } + + data->s = NULL; + data->timer_fd = 0; interface->data = data; - hl_process_state(interface); + if (hl_connect(interface) < 0) { + ERROR("[hl_initialize] Error during connection to forwarder"); + goto ERR_CONNECT; + } return 0; ERR_CONNECT: - hc_sock_free(data->s); -ERR_SOCK: free(data); ERR_MALLOC: return -1; @@ -118,8 +225,12 @@ ERR_MALLOC: int hl_finalize(interface_t * interface) { - //hc_data_t * data = interface->data; - //hc_sock_close(data->s); + hl_data_t * data = (hl_data_t *) interface->data; + + hl_disconnect(interface); + + free(data); + return 0; } @@ -131,9 +242,23 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) hl_data_t * data = (hl_data_t *)interface->data; face_t * face = NULL; - if (facelet_get_face(facelet, &face) < 0) + + /* NOTE + * - One example where this fails (and it is normal) is when we delete a + * face that was not completely created, because for instance bonjour did + * not give any data + */ + if (facelet_get_face(facelet, &face) < 0) { + ERROR("Could not retrieve face from facelet"); + return -1; + } + + if (!data->s) { + /* We are not connected to the forwarder */ return -1; + } + switch(facelet_get_event(facelet)) { case FACELET_EVENT_CREATE: @@ -147,10 +272,10 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) } INFO("Created face id=%d\n", hc_face.id); -#if 0 - /* Add default route v4 */ + /* Adding default routs e*/ +#if 1 route = (hc_route_t) { - .face_id = face.id, + .face_id = hc_face.id, .family = AF_INET, .remote_addr = IPV4_ANY, .len = 0, @@ -161,12 +286,9 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) ERROR("Failed to create default hICN/IPv4 route"); goto ERR; } - INFO("Successfully created default hICN/IPv4 route."); -#endif -#if 0 route = (hc_route_t) { - .face_id = face.id, + .face_id = hc_face.id, .family = AF_INET6, .remote_addr = IPV6_ANY, .len = 0, @@ -176,9 +298,8 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) ERROR("Failed to create default hICN/IPv6 route"); goto ERR; } -#endif - /* Adding default route */ +#else route = (hc_route_t) { .face_id = hc_face.id, .family = AF_INET6, @@ -193,6 +314,8 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) ERROR("Failed to create hICN/IPv6 route"); goto ERR; } +#endif + INFO("Successfully created default route(s)."); break; @@ -212,6 +335,8 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) if (facelet_get_admin_state_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { hc_face.face = *face; hc_face_t * face_found; + + printf("hc_face_get\n"); rc = hc_face_get(data->s, &hc_face, &face_found); if (rc < 0) { ERROR("Failed to find face\n"); @@ -224,7 +349,6 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) char conn_id_or_name[SYMBOLIC_NAME_LEN]; snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); free(face_found); - printf("Face id = %d\n", face_found->id); face_state_t admin_state; if (facelet_get_admin_state(facelet, &admin_state) < 0) { @@ -233,6 +357,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) } printf("Setting admin state"); + printf("hc_connection_set_admin_state\n"); if (hc_connection_set_admin_state(data->s, conn_id_or_name, admin_state) < 0) { ERROR("Failed to update admin state"); goto ERR; @@ -247,15 +372,56 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) goto ERR; } + face_free(face); return 0; ERR: + face_free(face); return -1; } +int hl_callback(interface_t * interface, int fd, void * unused) +{ + hl_data_t * data = (hl_data_t*)interface->data; + + hc_data_t * faces; + if (hc_sock_callback(data->s, &faces) < 0){ + DEBUG("Closing socket... reconnecting..."); + if (interface_unregister_fd(interface, hc_sock_get_fd(data->s)) < 0) { + ERROR("[hl_initialize] Error registering fd"); + } + hc_sock_free(data->s); + data->s = NULL; + hl_connect(interface); + return 0; + } + + if (faces->complete) { + foreach_face(f, faces) { +#if 1 + char buf[MAXSZ_FACE]; + hc_face_snprintf(buf, MAXSZ_FACE, f); + printf("Face: %s\n", buf); +#else + facelet_t * facelet = facelet_create_from_face(&f->face); + facelet_set_event(facelet, FACELET_EVENT_GET); + interface_raise_event(interface, facelet); +#endif + } + } + hc_data_free(faces); + + /* XXX how do we know what object we get back */ + + /* We have a queue of pending data elements per active query */ + + return 0; +} + const interface_ops_t hicn_light_ops = { .type = "hicn_light", .initialize = hl_initialize, .finalize = hl_finalize, .on_event = hl_on_event, + .callback = hl_callback, }; -- cgit 1.2.3-korg