aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/api.c')
-rw-r--r--ctrl/facemgr/src/api.c221
1 files changed, 138 insertions, 83 deletions
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index de0f062d3..a1507bd70 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -49,9 +49,12 @@
#define DEFAULT_PORT 9695
+#define MAX_FDS 10
+
typedef struct {
interface_t * interface;
- void * event;
+ int fds[MAX_FDS];
+ size_t num_fds;
} interface_map_data_t;
TYPEDEF_SET_H(facelet_cache, facelet_t *);
@@ -60,8 +63,6 @@ TYPEDEF_SET(facelet_cache, facelet_t *, facelet_cmp, facelet_snprintf);
TYPEDEF_MAP_H(interface_map, const char *, interface_map_data_t *);
TYPEDEF_MAP(interface_map, const char *, interface_map_data_t *, strcmp, string_snprintf, generic_snprintf);
-int int_cmp(int x, int y) { return x - y; }
-
TYPEDEF_MAP_H(bonjour_map, netdevice_t *, interface_t *);
TYPEDEF_MAP(bonjour_map, netdevice_t *, interface_t *, netdevice_cmp, generic_snprintf, generic_snprintf);
@@ -106,10 +107,9 @@ struct facemgr_s {
JavaVM *jvm;
#endif /* __ANDROID__ */
- /* Event loop support */
- void * loop;
- void * (*loop_register_fd)(void * loop, int fd, void * cb, void * cb_args);
- int (*loop_unregister_event)(void * loop, void * event);
+ /* Callback */
+ facemgr_cb_t callback;
+ void * callback_owner;
/****************************/
/* Internal data structures */
@@ -191,28 +191,42 @@ ERR_INTERFACE_MAP:
int
facemgr_finalize(facemgr_t * facemgr)
{
+ int ret = 0;
int rc;
- /* TODO Free all interfaces: pass free to map */
-
rc = interface_map_finalize(&facemgr->interface_map);
- if (rc < 0)
- goto ERR;
+ if (rc < 0) {
+ ERROR("[facemgr_finalize] Could not finalize interface_map");
+ ret = -1;
+ }
+
+ /* Free all facelets from cache */
+ facelet_t ** facelet_array;
+ int n = facelet_cache_get_array(&facemgr->facelet_cache, &facelet_array);
+ if (n < 0) {
+ ERROR("[facemgr_finalize] Could not retrieve facelets in cache");
+ } else {
+ for (unsigned i = 0; i < n; i++) {
+ facelet_t * facelet = facelet_array[i];
+ if (facelet_cache_remove(&facemgr->facelet_cache, facelet, NULL)) {
+ ERROR("[facemgr_finalize] Could not purge facelet from cache");
+ }
+ facelet_free(facelet);
+ }
+ free(facelet_array);
+ }
rc = facelet_cache_finalize(&facemgr->facelet_cache);
if (rc < 0)
- goto ERR;
+ ret = -1;
#ifdef __linux__
rc = bonjour_map_finalize(&facemgr->bonjour_map);
if (rc < 0)
- goto ERR;
+ ret = -1;
#endif /* __linux__ */
- return 0;
-
-ERR:
- return -1;
+ return ret;
}
AUTOGENERATE_CREATE_FREE(facemgr);
@@ -251,13 +265,12 @@ facemgr_create_with_config(facemgr_cfg_t * cfg)
return facemgr;
}
-int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet);
+int facemgr_callback(facemgr_t * facemgr, interface_cb_type_t type, void * data);
int
facemgr_create_interface(facemgr_t * facemgr, const char * name, const char * type, void * cfg, interface_t ** pinterface)
{
- int fd, rc;
- void * event = NULL;
+ int fd;
char rand_name[RAND_NAME_LEN+1];
interface_t * interface;
@@ -276,29 +289,23 @@ facemgr_create_interface(facemgr_t * facemgr, const char * name, const char * ty
ERROR("Error creating interface %s [%s]", name, type);
goto ERR_CREATE;
}
- interface_set_callback(interface, facemgr_on_event, facemgr);
+ interface_set_callback(interface, facemgr, facemgr_callback);
fd = interface_initialize(interface, cfg);
if (fd < 0)
goto ERR_INIT;
- if (fd != 0) {
- event = facemgr->loop_register_fd(facemgr->loop, fd, interface->ops->callback, interface);
- if (event == NULL)
- goto ERR_FD;
- }
interface_map_data_t * interface_map_data = malloc(sizeof(interface_map_data_t));
if (!interface_map_data)
goto ERR_MAP_DATA;
-
*interface_map_data = (interface_map_data_t) {
.interface = interface,
- .event = event,
+ .fds = {0},
+ .num_fds = 0,
};
- rc = interface_map_add(&facemgr->interface_map, interface->name, interface_map_data);
- if (rc < 0)
+ if (interface_map_add(&facemgr->interface_map, interface->name, interface_map_data) < 0)
goto ERR_MAP_ADD;
DEBUG("Interface %s created successfully.", name);
@@ -309,9 +316,6 @@ facemgr_create_interface(facemgr_t * facemgr, const char * name, const char * ty
ERR_MAP_ADD:
free(interface_map_data);
ERR_MAP_DATA:
- if (fd > 0)
- facemgr->loop_unregister_event(facemgr->loop, interface_map_data->event);
-ERR_FD:
interface_finalize(interface);
ERR_INIT:
interface_free(interface);
@@ -328,7 +332,7 @@ facemgr_delete_interface(facemgr_t * facemgr, interface_t * interface)
interface_map_data_t * interface_map_data = NULL;
- DEBUG("Removing interface %s\n", interface->name);
+ DEBUG("Removing interface %s", interface->name);
rc = interface_map_remove(&facemgr->interface_map, interface->name, &interface_map_data);
if (rc < 0)
return -1;
@@ -336,12 +340,14 @@ facemgr_delete_interface(facemgr_t * facemgr, interface_t * interface)
if (!interface_map_data)
return -1;
- free(interface_map_data);
-
- rc = facemgr->loop_unregister_event(facemgr->loop, interface_map_data->event);
- if (rc < 0)
- return -1;
+ for (unsigned i = 0; i < interface_map_data->num_fds; i++) {
+ int fd = interface_map_data->fds[i];
+ facemgr->callback(facemgr->callback_owner, FACEMGR_CB_TYPE_UNREGISTER_FD, &fd);
+ if (rc < 0)
+ WARN("[facemgr_delete_interface] Error unregistering fd %d for interface", fd);
+ }
+ free(interface_map_data);
interface_finalize(interface);
interface_free(interface);
@@ -445,26 +451,18 @@ facelet_cache_lookup(const facelet_cache_t * facelet_cache, facelet_t * facelet,
}
*cached_facelets = malloc(n * sizeof(facelet_t*));
- DEBUG("cache match n = %d", n);
-
int num_match = 0;
for (unsigned i = 0; i < n; i++) {
char buf[128];
facelet_snprintf(buf, 128, facelet_array[i]);
- DEBUG("- facelet_array[%d] %s", i, buf);
facelet_snprintf(buf, 128, facelet);
- DEBUG(" facelet %s", buf);
- DEBUG("match ?");
if (!facelet_match(facelet_array[i], facelet)) {
- DEBUG("no match");
continue;
}
- DEBUG("match!");
(*cached_facelets)[num_match++] = facelet_array[i];
}
free(facelet_array);
- DEBUG("return nummatch=%d", num_match);
return num_match;
}
@@ -519,24 +517,36 @@ facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet)
return -3;
}
- /* IPv4 */
- bool ipv4;
- if (facemgr_cfg_get_ipv4(facemgr->cfg, &netdevice, netdevice_type,
- &ipv4) < 0)
- return -1;
- if (!ipv4) {
- DEBUG("Ignored IPv4...");
- return -3;
- }
+ switch(family) {
+ case AF_INET:
+ {
+ bool ipv4;
+ if (facemgr_cfg_get_ipv4(facemgr->cfg, &netdevice, netdevice_type,
+ &ipv4) < 0)
+ return -1;
+ if (!ipv4) {
+ DEBUG("Ignored IPv4 facelet...");
+ return -3;
+ }
+ break;
+ }
- /* IPv6 */
- bool ipv6;
- if (facemgr_cfg_get_ipv6(facemgr->cfg, &netdevice, netdevice_type,
- &ipv6) < 0)
- return -1;
- if (!ipv6) {
- DEBUG("Ignored IPv6...");
- return -3;
+ case AF_INET6:
+ {
+ bool ipv6;
+ if (facemgr_cfg_get_ipv6(facemgr->cfg, &netdevice, netdevice_type,
+ &ipv6) < 0)
+ return -1;
+ if (!ipv6) {
+ DEBUG("Ignored IPv6 facelet...");
+ return -3;
+ }
+ break;
+ }
+
+ default:
+ DEBUG("Ignored facelet with unknown family");
+ return -2;
}
return 0;
@@ -839,6 +849,7 @@ facemgr_process_create(facemgr_t * facemgr, facelet_t * facelet)
*/
rc = facemgr_facelet_satisfy_rules(facemgr, facelet);
if (rc == -3) {
+ facelet_set_status(facelet, FACELET_STATUS_IGNORED);
/* Does not satisfy rules */
return 0;
}
@@ -884,7 +895,7 @@ facemgr_process_create(facemgr_t * facemgr, facelet_t * facelet)
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
- DEBUG("---[ FACELET CREATE : %s ] ---", facelet_s);
+ //DEBUG("---[ FACELET CREATE : %s ] ---", facelet_s);
/* Do we have enough information about the facelet ? */
if (!facelet_validate_face(facelet)) {
@@ -921,6 +932,7 @@ facemgr_process_create(facemgr_t * facemgr, facelet_t * facelet)
* \param [in] facemgr - Pointer to the face manager instance
* \param [in] facelet - Pointer to the facelet event to process
* \return 0 if everything went correctly, or -1 in case of error.
+ * -2 means we ignored the face purposedly
*/
int
facemgr_process_get(facemgr_t * facemgr, facelet_t * facelet)
@@ -931,10 +943,10 @@ facemgr_process_get(facemgr_t * facemgr, facelet_t * facelet)
if (facelet_get_netdevice(facelet, &netdevice) < 0)
return -1;
if (!IS_VALID_NETDEVICE(netdevice))
- return 0;
+ return -2;
return facelet_cache_add(&facemgr->facelet_cache, facelet);
}
- return 0;
+ return -2;
}
/**
@@ -959,7 +971,7 @@ facemgr_process_update(facemgr_t * facemgr, facelet_t * facelet)
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
- DEBUG("---[ FACELET UPDATE : %s ] ---", facelet_s);
+ //DEBUG("---[ FACELET UPDATE : %s ] ---", facelet_s);
/* Sets face type */
if (!facelet_has_face_type(facelet)) {
@@ -1013,6 +1025,7 @@ facemgr_process_update(facemgr_t * facemgr, facelet_t * facelet)
rc = facemgr_facelet_satisfy_rules(facemgr, facelet);
if (rc == -3) {
+ facelet_set_status(facelet, FACELET_STATUS_IGNORED);
/* Does not satisfy rules */
return 0;
}
@@ -1048,6 +1061,7 @@ facemgr_process_update(facemgr_t * facemgr, facelet_t * facelet)
rc = facemgr_facelet_satisfy_rules(facemgr, facelet);
if (rc == -3) {
+ facelet_set_status(facelet, FACELET_STATUS_IGNORED);
/* Does not satisfy rules */
return 0;
}
@@ -1067,6 +1081,15 @@ facemgr_process_update(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_CONFLICT:
ERROR("[facemgr_process_update] Conflict resolution (not) yet implemented");
return -1;
+
+ case FACELET_STATUS_ERROR:
+ ERROR("[facemgr_process_update] Case ERROR (not) yet implemented");
+ break;
+
+ case FACELET_STATUS_IGNORED:
+ ERROR("[facemgr_process_update] Case IGNORED (not) yet implemented");
+ break;
+
case FACELET_STATUS_N:
ERROR("[facemgr_process_update] Facelet in error");
return -1;
@@ -1117,13 +1140,15 @@ facemgr_process_delete(facemgr_t * facemgr, facelet_t * facelet)
int
facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
{
+ bool remove_facelet = true;
int ret = 0;
+ int rc;
assert(facelet_in);
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in);
- DEBUG("----------------------------------");
- DEBUG("EVENT %s\n", facelet_s);
+ //DEBUG("----------------------------------");
+ DEBUG("EVENT %s", facelet_s);
facelet_t ** cached_facelets = NULL;
int n = facelet_cache_lookup(&facemgr->facelet_cache, facelet_in, &cached_facelets);
@@ -1131,7 +1156,6 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
ERROR("[facemgr_on_event] Error during cache lookup");
goto ERR;
}
- DEBUG("num matches n=%d", n);
if (n == 0) {
/* This is a new facelet... we expect a CREATE event. */
switch(facelet_get_event(facelet_in)) {
@@ -1141,7 +1165,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
ERROR("[facemgr_on_event] Error adding facelet to cache");
return -1;
}
- DEBUG("Facelet added to cache");
+ //DEBUG("Facelet added to cache");
+
+ remove_facelet = false;
if (facemgr_process_create(facemgr, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error processing CREATE event");
@@ -1151,7 +1177,10 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
case FACELET_EVENT_GET:
/* Insert new facelet in cached */
- if (facemgr_process_get(facemgr, facelet_in) < 0) {
+ rc = facemgr_process_get(facemgr, facelet_in);
+ if (rc == 0)
+ remove_facelet = false;
+ if (rc == -1) {
ERROR("[facemgr_on_event] Error processing GET event");
goto ERR;
}
@@ -1189,7 +1218,6 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* reconciliation by sending appropriate updates to the forwarder
*/
facelet_t * facelet = cached_facelets[i];
- DEBUG("... match #%d", i);
switch(facelet_get_event(facelet_in)) {
case FACELET_EVENT_CREATE:
// This case will occur when we try to re-create existing faces,
@@ -1247,14 +1275,41 @@ ERR:
ret = -1;
DUMP_CACHE:
+#if 1
DEBUG(" <CACHE>");
facelet_cache_dump(&facemgr->facelet_cache);
DEBUG(" </CACHE>");
DEBUG("</EVENT ret=%d>", ret);
DEBUG("----------------------------------");
+#endif
+
+ if (remove_facelet)
+ facelet_free(facelet_in);
+
return ret;
}
+int facemgr_callback(facemgr_t * facemgr, interface_cb_type_t type, void * data)
+{
+ switch(type) {
+ case INTERFACE_CB_TYPE_RAISE_EVENT:
+ return facemgr_on_event(facemgr, data);
+ case INTERFACE_CB_TYPE_REGISTER_FD:
+ return facemgr->callback(facemgr->callback_owner,
+ FACEMGR_CB_TYPE_REGISTER_FD, data);
+ case INTERFACE_CB_TYPE_REGISTER_TIMER:
+ return facemgr->callback(facemgr->callback_owner,
+ FACEMGR_CB_TYPE_REGISTER_TIMER, data);
+ case INTERFACE_CB_TYPE_UNREGISTER_TIMER:
+ return facemgr->callback(facemgr->callback_owner,
+ FACEMGR_CB_TYPE_UNREGISTER_TIMER, data);
+ case INTERFACE_CB_TYPE_UNREGISTER_FD:
+ return facemgr->callback(facemgr->callback_owner,
+ FACEMGR_CB_TYPE_UNREGISTER_FD, data);
+ }
+ return -1;
+}
+
int
facemgr_bootstrap(facemgr_t * facemgr)
{
@@ -1395,15 +1450,15 @@ void facemgr_stop(facemgr_t * facemgr)
facemgr_delete_interface(facemgr, facemgr->nl);
/* Delete all bonjour interfaces */
- interface_t ** bonjour_array;// = NULL; // NOTE: would allow avoiding tests
+ interface_t ** bonjour_array = NULL;
int n = bonjour_map_get_value_array(&facemgr->bonjour_map, &bonjour_array);
- if (n > 0) {
- netdevice_t ** netdevice_array; // = NULL;
+ if (n >= 0) {
+ netdevice_t ** netdevice_array = NULL;
int m = bonjour_map_get_key_array(&facemgr->bonjour_map, &netdevice_array);
- if (m > 0) {
+ if (m >= 0) {
assert(m == n);
for (int i = 0; i < n; i++) { /* Fail silently */
- DEBUG("Deleting bonjour interface associated to %s (%p)\n",
+ DEBUG("Deleting bonjour interface associated to %s (%p)",
netdevice_array[i]->name, bonjour_array[i]);
facemgr_delete_interface(facemgr, bonjour_array[i]);
}
@@ -1435,11 +1490,11 @@ void facemgr_set_jvm(facemgr_t * facemgr, JavaVM *jvm)
}
#endif /* __ANDROID__ */
-void facemgr_set_event_loop_handler(facemgr_t * facemgr, void * loop, void * loop_register_fd, void * loop_unregister_event)
+void
+facemgr_set_callback(facemgr_t * facemgr, void * callback_owner, facemgr_cb_t callback)
{
- facemgr->loop = loop;
- facemgr->loop_register_fd = loop_register_fd;
- facemgr->loop_unregister_event = loop_unregister_event;
+ facemgr->callback = callback;
+ facemgr->callback_owner = callback_owner;
}
void facemgr_list_faces(facemgr_t * facemgr, facemgr_list_faces_cb_t cb, void * user_data)