aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-10-23 17:55:00 +0200
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-10-24 00:21:47 +0200
commit8e12c8e42cc9ea9d12e55a3a0d8fbcb211504c04 (patch)
tree1556919c967bd1b6ea664c1f80d6d43efb805f59 /ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
parentcf3d6ef0cbda50c9917421213a77097250f3d67b (diff)
[HICN-352] facemgr event loop enhancement; timer support & async hicn-light interface
Change-Id: I920a0eb091d826e1eb0d1f786fb0b437487f7ff7 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c')
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c224
1 files changed, 195 insertions, 29 deletions
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 <assert.h>
#include <stdbool.h>
#include <stdio.h> // snprintf
#include <time.h> // 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,
};