diff options
Diffstat (limited to 'ctrl/facemgr')
-rw-r--r-- | ctrl/facemgr/CMakeLists.txt | 19 | ||||
-rw-r--r-- | ctrl/facemgr/cmake/Modules/Packaging.cmake | 15 | ||||
-rw-r--r-- | ctrl/facemgr/config/facemgr.conf | 194 | ||||
-rw-r--r-- | ctrl/facemgr/config/facemgr.service | 24 | ||||
-rwxr-xr-x | ctrl/facemgr/config/post | 5 | ||||
-rwxr-xr-x | ctrl/facemgr/config/postinst | 3 | ||||
-rwxr-xr-x | ctrl/facemgr/config/prerm | 3 | ||||
-rwxr-xr-x | ctrl/facemgr/config/preun | 3 | ||||
-rw-r--r-- | ctrl/facemgr/examples/mobility/Makefile | 23 | ||||
-rw-r--r-- | ctrl/facemgr/examples/mobility/mobility.c | 88 | ||||
-rw-r--r-- | ctrl/facemgr/src/CMakeLists.txt | 8 | ||||
-rw-r--r-- | ctrl/facemgr/src/api.c | 96 | ||||
-rw-r--r-- | ctrl/facemgr/src/facelet.c | 6 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/android_utility/android_utility.c | 6 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c | 28 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c | 146 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h | 45 | ||||
-rw-r--r-- | ctrl/facemgr/src/main.c | 2 |
18 files changed, 652 insertions, 62 deletions
diff --git a/ctrl/facemgr/CMakeLists.txt b/ctrl/facemgr/CMakeLists.txt index 4290d9cd6..ba9de9464 100644 --- a/ctrl/facemgr/CMakeLists.txt +++ b/ctrl/facemgr/CMakeLists.txt @@ -42,8 +42,7 @@ if (NOT CMAKE_BUILD_TYPE) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) -message("IN DEBUG MODE") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") endif() set(CMAKE_MODULE_PATH @@ -59,7 +58,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) -find_package_wrapper(Config REQUIRED) +find_package_wrapper(Libconfig REQUIRED) find_package_wrapper(LibEvent REQUIRED) set(FACEMGR facemgr CACHE INTERNAL "" FORCE) @@ -95,6 +94,20 @@ add_subdirectory(src) include(Packaging) +# Install service file in linux systems +include(ServiceScript) +install_service_script( + ${CMAKE_CURRENT_SOURCE_DIR}/config/facemgr.service + COMPONENT ${FACEMGR} +) + +# Configuration file +set(FACEMGR_CONF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/config/facemgr.conf) +set(FACEMGR_CONF_FOLDER "/etc/facemgr") +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + install (FILES ${FACEMGR_CONF_FILE} DESTINATION ${FACEMGR_CONF_FOLDER} COMPONENT ${FACEMGR}) +endif() + if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) include(Packager) make_packages() diff --git a/ctrl/facemgr/cmake/Modules/Packaging.cmake b/ctrl/facemgr/cmake/Modules/Packaging.cmake index 3a7e5a85c..bb4fa42fa 100644 --- a/ctrl/facemgr/cmake/Modules/Packaging.cmake +++ b/ctrl/facemgr/cmake/Modules/Packaging.cmake @@ -25,7 +25,22 @@ set(${FACEMGR}_DEB_DEPENDENCIES CACHE STRING "Dependencies for deb/rpm package." ) +set(${HICN_LIGHT}_DEB_PACKAGE_CONTROL_EXTRA + "${CMAKE_CURRENT_SOURCE_DIR}/config/postinst;${CMAKE_CURRENT_SOURCE_DIR}/config/prerm" + CACHE STRING "Control scripts conffiles, postinst, postrm, prerm." +) + set(${FACEMGR}_RPM_DEPENDENCIES "libconfig, libevent-devel, lib${LIBHICNCTRL} >= stable_version" CACHE STRING "Dependencies for deb/rpm package." ) + +set(${HICN_LIGHT}_RPM_POST_INSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/config/post" + CACHE STRING "Install script that will be copied in the %post section" +) + +set(${HICN_LIGHT}_RPM_PRE_UNINSTALL_SCRIPT_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/config/preun" + CACHE STRING "Install script that will be copied in the %post section" +) diff --git a/ctrl/facemgr/config/facemgr.conf b/ctrl/facemgr/config/facemgr.conf new file mode 100644 index 000000000..d9c6f5fa9 --- /dev/null +++ b/ctrl/facemgr/config/facemgr.conf @@ -0,0 +1,194 @@ +# +# hICN facemgr configuration file +# + +################################################################################ +# Global settings +################################################################################ + +global = { + +# Default type for face creation +# +# Values: "auto" | "native-udp" | "native-tcp" | "overlay-udp" | "overlay-tcp" +# Default "auto" +# +#face_type = "auto"; +face_type = "overlay-udp" + +# Disable service discovery for overlay creation +# +# This is only meaningful for overlay_* face types. If service discovery is +# disabled, only manually entered overlay information will be used, if any. +# Otherwise, no face will be created. +# +# Values : true | false +# Default: false +# +#disable_discovery = true; + +# Disable IPv4 face creation +# +# Values : true | false +# Default: false +# +#disable_ipv4 = true; + +# Disable IPv6 face creation +# +# Values : true | false +# Default: false +# +#disable_ipv6 = true; + +# overlay +# +# By default, no address is specified, and local and remote ports are set to +# the standard value for hICN (9695). +# + +}; + +################################################################################ +# Per-interface rules +################################################################################ +# +# Rules allow to override the default behaviour of the face manager. +# +# The list of rules must be specified as follows (note that the last one has no +# coma at the end) : +# +# rules = ( +# { ... }, +# { ... }, +# { ... } +# ); +# +# A rule is composed of match and override attributes, and has the following +# syntax: +# +# { +# match = { +# interface_name = STRING; +# interface_type = STRING; +# }; +# override = { +# face_type = STRING; +# disable_discovery = BOOL; +# ignore = BOOL; +# tags = (STRING, STRING, STRING); +# overlay = { +# ipv4 = { +# local_port = PORT; +# remote_addr = IP_ADDRESS; +# remote_port = PORT; +# }; +# ipv6 = { +# local_port = PORT; +# remote_addr = IP_ADDRESS; +# remote_port = PORT; +# }; +# }; +# }; +# } +# +# Match attributes: +# +# Match attributes serve to identify rules and as such defining two rules with +# similar matches is not allowed. However, overlapping match definitions are +# possible, in which case only the first matching rule is considered. +# +# A match is composed of the name of an interface and/or its type (either +# attribute is optional but at least one has to be specified). +# +# * interface_name - a string representing an interface name +# +# * interface_type - the type of interface to match +# +# Values: "wired" | "wifi" | "cellular" +# +# Override attributes: +# +# Those attributes are applied when all specified match attributes correspond, +# and override general settings or default values. +# +# * face_type - type used for face creation +# +# Values: "auto" | "native_udp" | "native_tcp" | "overlay_udp" | "overlay_tcp" +# +# * disable_discovery - disable service discovery for overlay creation +# +# Values : true | false +# +# * ignore - a boolean indicating whether that interface should be ignored +# +# * TODO tags - a (possibly empty) list of tags to be associated to the created face. +# +# Values: "wired" | "wifi" | "cellular" | "trusted" +# +# * overlay +# +# An overlay specification is used to complement any information retrieved +# through service discovery (or replace it if service discovery is +# disabled). +# +# It is possible to specify values for IPv4, IPv6 or both. +# +# Note that it is not currently possible to set different settings for IPv4 and +# IPv6 but overlay specifications. +# +# +# Here are a few example of rule definitions: +# +# rules = ( +# # Ignore localhost interface +# { +# match = { +# interface_name = "lo"; +# }; +# override = { +# ignore = true; +# }; +# }, +# # Set tags for unknown tunnnel interface +# { +# match = { +# interface_name = "utun1"; +# }; +# override = { +# tags = ("WIRED", "TRUSTED"); +# }; +# }, +# # Force cellular connections to use manually specified overlay faces +# { +# match = { +# interface_type = "cellular", +# }; +# override = { +# overlay = { +# ipv4 = { +# local_port = 9695; +# remote_addr = "10.60.16.14"; +# remote_port = 9695; +# }; +# ipv6 = { +# local_port = 9695; +# remote_addr = "2001:420:44f1:10:20c:29ff:fef3:8f8f"; +# remote_port = 9695; +# }; +# }; +# }; +# } +# ); +# +#rules = ( +#); + +################################################################################ +# Logging +################################################################################ + +log: +{ + log_level = "DEBUG"; +} diff --git a/ctrl/facemgr/config/facemgr.service b/ctrl/facemgr/config/facemgr.service new file mode 100644 index 000000000..0f9e818ea --- /dev/null +++ b/ctrl/facemgr/config/facemgr.service @@ -0,0 +1,24 @@ +# Copyright (c) 2017-2019 Cisco and/or its affiliates. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[Unit] +Description=hICN face manager + +[Service] +Environment=CONFIG=/etc/facemgr/facemgr.conf +Environment=LOGFILE=/var/log/facemgr.log +ExecStart=/usr/bin/facemgr -c ${CONFIG} 1>${LOGFILE} 2>&1 +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/ctrl/facemgr/config/post b/ctrl/facemgr/config/post new file mode 100755 index 000000000..7b2fd57fe --- /dev/null +++ b/ctrl/facemgr/config/post @@ -0,0 +1,5 @@ +#!/bin/bash + +if pidof systemd; then + systemctl enable facemgr +fi diff --git a/ctrl/facemgr/config/postinst b/ctrl/facemgr/config/postinst new file mode 100755 index 000000000..4113b0eca --- /dev/null +++ b/ctrl/facemgr/config/postinst @@ -0,0 +1,3 @@ +#!/bin/bash + +systemctl enable facemgr diff --git a/ctrl/facemgr/config/prerm b/ctrl/facemgr/config/prerm new file mode 100755 index 000000000..b5c486ea5 --- /dev/null +++ b/ctrl/facemgr/config/prerm @@ -0,0 +1,3 @@ +#!/bin/bash + +systemctl disable facemgr diff --git a/ctrl/facemgr/config/preun b/ctrl/facemgr/config/preun new file mode 100755 index 000000000..b5c486ea5 --- /dev/null +++ b/ctrl/facemgr/config/preun @@ -0,0 +1,3 @@ +#!/bin/bash + +systemctl disable facemgr diff --git a/ctrl/facemgr/examples/mobility/Makefile b/ctrl/facemgr/examples/mobility/Makefile new file mode 100644 index 000000000..3b92d9d5f --- /dev/null +++ b/ctrl/facemgr/examples/mobility/Makefile @@ -0,0 +1,23 @@ +EXEC = $(shell basename $$(pwd)) +CC = gcc + +CFLAGS = -std=gnu11 -O3 -Wall -Wextra -Wpedantic -Wstrict-aliasing + +SRC = $(wildcard *.c) +OBJ = $(SRC:.c=.o) + +all: $(EXEC) + +${EXEC}: $(OBJ) + $(CC) -o $@ $^ $(LDFLAGS) + +%.o: %.c + $(CC) -o $@ -c $< $(CFLAGS) + +.PHONY: clean mrproper + +clean: + @rm -rf *.o + +mrproper: clean + @rm -rf $(EXEC) diff --git a/ctrl/facemgr/examples/mobility/mobility.c b/ctrl/facemgr/examples/mobility/mobility.c new file mode 100644 index 000000000..528951446 --- /dev/null +++ b/ctrl/facemgr/examples/mobility/mobility.c @@ -0,0 +1,88 @@ +/* + * Dummy server sending alternating bytes to all clients. + * + * This program can be used to trigger mobility events in the hICN forwarder, to + * switch from WiFi to LTE and back, at regular intervals. + * + * Test server using nc: nc -4kvul localhost 9533 + */ + +#include <arpa/inet.h> // inet_ntop +#include <errno.h> // EINTR,. .. +#include <netinet/in.h> // INET_ADDRSTRLEN, INET6_ADDRSTRLEN +#include <stdio.h> +#include <inttypes.h> + +#include <stdlib.h> +#include <sys/socket.h> +#include <sys/timerfd.h> +#include <sys/un.h> // sockaddr_un +#include <unistd.h> // fcntl +#include <fcntl.h> // fcntl + +#define MS2US(x) (x * 1000) + +/** + * \brief Main function + */ +int main(int argc, char **argv) +{ + int rc; + + if (argc != 4) { + fprintf(stderr, "Usage: %s IP PORT INTERVAL\n", argv[0]); + fprintf(stderr, "\n"); + fprintf(stderr, " IP Target hostname\n"); + fprintf(stderr, " PORT Target port\n"); + fprintf(stderr, " INTERVAL Interval between mobility events (in ms)\n"); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); + } + + int interval = atoi(argv[3]); + + int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) { + perror("socket"); + goto ERR_SOCKET; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(argv[1]); + addr.sin_port = htons(atoi(argv[2])); + + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + perror("connect"); + goto ERR_CONNECT; + } + + unsigned state = 0; + char buf[1]; + for(;;) { + usleep(MS2US(interval)); + + buf[0] = state; + rc = send(fd, buf, 1, 0); + if (rc < 0) { + if (errno == ECONNREFUSED) { + continue; + } + perror("send"); + goto ERR_SEND; + } + + state = 1 - state; + } + + close(fd); + + exit(EXIT_SUCCESS); + +ERR_SEND: +ERR_CONNECT: + close(fd); +ERR_SOCKET: + exit(EXIT_FAILURE); +} diff --git a/ctrl/facemgr/src/CMakeLists.txt b/ctrl/facemgr/src/CMakeLists.txt index 4bcad475d..cf5606e04 100644 --- a/ctrl/facemgr/src/CMakeLists.txt +++ b/ctrl/facemgr/src/CMakeLists.txt @@ -64,10 +64,12 @@ set(LIBRARIES m ${HICN_LIBRARIES} ${LIBHICNCTRL_LIBRARIES} - ${CONFIG_LIBRARY} + ${LIBCONFIG_LIBRARIES} ${LIBEVENT_LIBRARY} ) +set(FACEMGR_LIBRARY_LIST "${LIBCONFIG_LIBRARIES};${LIBEVENT_LIBRARY}" CACHE INTERNAL "FACEMGR_LIBRARY_LIST") + add_subdirectory(interfaces) @@ -106,7 +108,7 @@ if (DISABLE_SHARED_LIBRARIES) LINK_LIBRARIES ${LIBRARIES} COMPONENT ${FACEMGR} INCLUDE_DIRS ${INCLUDE_DIRS} - INSTALL_ROOT_DIR hicn + HEADER_ROOT_DIR hicn DEFINITIONS ${COMPILER_DEFINITIONS} ) else () @@ -118,7 +120,7 @@ else () LINK_LIBRARIES ${LIBRARIES} COMPONENT ${FACEMGR} INCLUDE_DIRS ${INCLUDE_DIRS} - INSTALL_ROOT_DIR hicn + HEADER_ROOT_DIR hicn DEFINITIONS ${COMPILER_DEFINITIONS} ) endif () diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c index 5d48e993f..b2e329e0a 100644 --- a/ctrl/facemgr/src/api.c +++ b/ctrl/facemgr/src/api.c @@ -21,12 +21,12 @@ #ifdef __ANDROID__ /* - * Use AndroidUtility to determine interface types + * Use FacemgrUtility to determine interface types * * NOTE: this is currently disabled as SDK APIs do not allow to determine the * type of interfaces that are DOWN */ -//#define WITH_ANDROID_UTILITY +//#define WITH_FACEMGR_UTILITY /* * Use priority controller interface @@ -34,6 +34,11 @@ #define WITH_PRIORITY_CONTROLLER /* + * Dump facelets (debug) + */ +//#define WITH_DUMP + +/* * Allow priority setting before interface is actually created */ #define WITH_DEFAULT_PRIORITIES @@ -59,9 +64,11 @@ #include "interfaces/bonjour/bonjour.h" #endif /* __linux__ */ -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY #include "interfaces/android_utility/android_utility.h" -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ + +#include "interfaces/priority_controller/priority_controller.h" #include <hicn/face.h> #include <hicn/facemgr/facelet.h> @@ -100,9 +107,9 @@ extern interface_ops_t network_framework_ops; extern interface_ops_t netlink_ops; extern interface_ops_t bonjour_ops; #endif -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY extern interface_ops_t android_utility_ops; -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER extern interface_ops_t priority_controller_ops; #endif @@ -162,9 +169,9 @@ struct facemgr_s { interface_t * hl; -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY interface_t * au; /* android_utility */ -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER interface_t * pc; @@ -538,7 +545,7 @@ int facemgr_query_bonjour(facemgr_t * facemgr, netdevice_t * netdevice) } #endif /* __linux__ */ -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY int facemgr_query_android_utility(facemgr_t * facemgr, netdevice_t netdevice) { /* Send an event to the interface */ @@ -564,7 +571,7 @@ ERR_ND: ERR_MALLOC: return -1; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ /** @@ -640,7 +647,7 @@ facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet) } netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_ANDROID_UTILITY +#ifndef WITH_FACEMGR_UTILITY /* * In addition to netdevice, netdevice_type should be present to correctly * apply rules @@ -650,7 +657,7 @@ facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet) ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice_type from facelet"); return -2; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ /* Default ignore list */ if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) { @@ -705,7 +712,7 @@ facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet) return 0; } -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY /** * \brief Complements facelet information through Android Utility interface * \return 0 if request was successful, -1 in case of error, and -2 if the @@ -741,7 +748,7 @@ facemgr_complement_facelet_au(facemgr_t * facemgr, facelet_t * facelet) facelet_set_au_done(facelet); return 0; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef __linux__ /** @@ -763,7 +770,7 @@ facemgr_complement_facelet_bj(facemgr_t * facemgr, facelet_t * facelet) } netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_ANDROID_UTILITY +#ifndef WITH_FACEMGR_UTILITY /* * In addition to netdevice, netdevice_type should be present to correctly * apply rules @@ -773,7 +780,7 @@ facemgr_complement_facelet_bj(facemgr_t * facemgr, facelet_t * facelet) ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice_type from facelet"); return -2; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ bool discovery; if (facemgr_cfg_get_discovery(facemgr->cfg, &netdevice, netdevice_type, @@ -835,7 +842,7 @@ facemgr_complement_facelet_manual(facemgr_t * facemgr, facelet_t * facelet) } netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_ANDROID_UTILITY +#ifndef WITH_FACEMGR_UTILITY /* * In addition to netdevice, netdevice_type should be present to correctly * apply rules @@ -845,7 +852,7 @@ facemgr_complement_facelet_manual(facemgr_t * facemgr, facelet_t * facelet) ERROR("[facemgr_complement_facelet_manual] Error retrieving netdevice_type from facelet"); return -2; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ int family = AF_UNSPEC; if (facelet_has_family(facelet)) { @@ -957,11 +964,11 @@ facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet) if (!facelet_has_key(facelet)) return -2; -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY rc = facemgr_complement_facelet_au(facemgr, facelet); if (rc != -2) return rc; -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #if 0 if (!facelet_has_netdevice_type(facelet)) { @@ -1008,7 +1015,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet) } netdevice_type_t netdevice_type = NETDEVICE_TYPE_UNDEFINED; -#ifndef WITH_ANDROID_UTILITY +#ifndef WITH_FACEMGR_UTILITY /* * In addition to netdevice, netdevice_type should be present to correctly * apply rules @@ -1018,7 +1025,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet) ERROR("[facemgr_assign_face_type] Error retrieving netdevice_type from facelet"); return -2; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ facemgr_face_type_t face_type = FACEMGR_FACE_TYPE_UNDEFINED; if (facemgr_cfg_get_face_type(facemgr->cfg, &netdevice, netdevice_type, &face_type) < 0) @@ -1153,9 +1160,9 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet) facelet_unset_admin_state(facelet); facelet_unset_state(facelet); facelet_unset_bj_done(facelet); -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY facelet_unset_au_done(facelet); -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ facelet_set_status(facelet, FACELET_STATUS_DELETED); #if 0 @@ -1416,9 +1423,9 @@ facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet) facelet_unset_state(new_facelet); facelet_unset_bj_done(new_facelet); facelet_clear_routes(new_facelet); -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY facelet_unset_au_done(new_facelet); -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ /* We try to apply static_facelet over facelet */ if (!facelet_match(new_facelet, static_facelet)) { @@ -1650,9 +1657,9 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet) facelet_unset_admin_state(facelet); facelet_unset_state(facelet); facelet_unset_bj_done(facelet); -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY facelet_unset_au_done(facelet); -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ facelet_unset_error(facelet); facelet_set_status(facelet, FACELET_STATUS_DELETED); #if 0 @@ -1787,7 +1794,9 @@ int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in) { bool remove_facelet = true; +#if WITH_DUMP bool dump = true; +#endif /* WITH_DUMP */ int ret = 0; int rc; assert(facelet_in); @@ -1877,7 +1886,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in) rc = facemgr_process_facelet_get(facemgr, facelet_in); if (rc == 0) remove_facelet = false; +#if WITH_DUMP dump = false; +#endif if (rc == -1) { ERROR("[facemgr_on_event] Error processing GET event"); goto ERR; @@ -1985,7 +1996,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in) //DEBUG("[facemgr_on_event] GET EXISTING %s", facelet_old_s); //DEBUG(" WITH %s", facelet_s); //ERROR("[facemgr_on_event] GET event for a face that already exists..."); +#ifdef WITH_DUMP dump = false; +#endif /* WITH_DUMP */ continue; case FACELET_EVENT_UPDATE: @@ -2066,7 +2079,7 @@ ERR: ret = -1; DUMP_CACHE: -#if 1 +#if WITH_DUMP if (dump) { DEBUG(" <CACHE>"); facelet_set_dump(facemgr->facelet_cache); @@ -2074,7 +2087,7 @@ DUMP_CACHE: DEBUG("</EVENT ret=%d>", ret); DEBUG("----------------------------------"); } -#endif +#endif /* WITH_DUMP */ free(cached_facelets); @@ -2188,13 +2201,13 @@ facemgr_bootstrap(facemgr_t * facemgr) } #endif /* __linux__ */ -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY rc = interface_register(&android_utility_ops); if (rc < 0) { ERROR("[facemgr_bootstrap] Error registering android_utility interface"); goto ERR_REGISTER; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER INFO("[facemgr_bootstrap] registering priority_controller interface"); @@ -2245,7 +2258,7 @@ facemgr_bootstrap(facemgr_t * facemgr) } #endif /* __linux__ */ -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY android_utility_cfg_t au_cfg = { .jvm = facemgr->jvm, }; @@ -2254,11 +2267,16 @@ facemgr_bootstrap(facemgr_t * facemgr) ERROR("Error creating 'Android Utility' interface\n"); goto ERR_AU_CREATE; } -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER INFO("[facemgr_bootstrap] creating priority_controller interface"); - rc = facemgr_create_interface(facemgr, "pc", "priority_controller", NULL, &facemgr->pc); + priority_controller_cfg_t pc_cfg = { +#ifdef PRIORITY_CONTROLLER_INTERNAL + .jvm = facemgr->jvm, +#endif /* PRIORITY_CONTROLLER_INTERNAL */ + }; + rc = facemgr_create_interface(facemgr, "pc", "priority_controller", &pc_cfg, &facemgr->pc); if (rc < 0) { ERROR("Error creating 'Priority Controller' interface\n"); goto ERR_PC_CREATE; @@ -2293,10 +2311,10 @@ ERR_UPDOWN_CREATE: facemgr_delete_interface(facemgr, facemgr->dummy); ERR_DUMMY_CREATE: #endif -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY facemgr_delete_interface(facemgr, facemgr->au); ERR_AU_CREATE: -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER facemgr_delete_interface(facemgr, facemgr->pc); ERR_PC_CREATE: @@ -2346,9 +2364,9 @@ void facemgr_stop(facemgr_t * facemgr) } #endif /* __linux__ */ -#ifdef WITH_ANDROID_UTILITY +#ifdef WITH_FACEMGR_UTILITY facemgr_delete_interface(facemgr, facemgr->au); -#endif /* WITH_ANDROID_UTILITY */ +#endif /* WITH_FACEMGR_UTILITY */ #ifdef WITH_PRIORITY_CONTROLLER facemgr_delete_interface(facemgr, facemgr->pc); diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c index 1958749ae..f51f5802b 100644 --- a/ctrl/facemgr/src/facelet.c +++ b/ctrl/facemgr/src/facelet.c @@ -356,8 +356,10 @@ facelet_create_from_face(face_t * face) facelet->error = 0; /* TODO Consistency check between face type and found attributes */ - if (facelet_validate_face(facelet) < 0) + if (facelet_validate_face(facelet) < 0) { + ERROR("[facelet_create_from_face] Cannot validate face"); goto ERR_FACE; + } facelet->bj_done = false; facelet->au_done = false; @@ -367,7 +369,7 @@ facelet_create_from_face(face_t * face) /* We need to get route set */ facelet->routes = route_set_create(); if (!facelet->routes) { - ERROR("[facelet_create] Cannot create route set"); + ERROR("[facelet_create_from_face] Cannot create route set"); goto ERR_ROUTE_SET; } facelet->routes_done = false; diff --git a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c b/ctrl/facemgr/src/interfaces/android_utility/android_utility.c index 55468baf8..d8e20659a 100644 --- a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c +++ b/ctrl/facemgr/src/interfaces/android_utility/android_utility.c @@ -20,15 +20,15 @@ #include <assert.h> -#include <hicn/face.h> #include <hicn/facemgr.h> +#include <hicn/ctrl/face.h> #include <hicn/util/log.h> #include "../../common.h" #include "../../interface.h" #include "android_utility.h" -#define FACEMGR_ANDROID_UTILITY_CLASS "com/cisco/hicn/forwarder/supportlibrary/AndroidUtility" +#define FACEMGR_UTILITY_CLASS "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" #define AU_INTERFACE_TYPE_UNDEFINED 0 @@ -89,7 +89,7 @@ int au_on_event(interface_t * interface, facelet_t * facelet) JNIEnv *env; JavaVM *jvm = data->cfg.jvm; (*jvm)->AttachCurrentThread(jvm, &env, NULL); - jclass cls = (*env)->FindClass(env, FACEMGR_ANDROID_UTILITY_CLASS); + jclass cls = (*env)->FindClass(env, FACEMGR_UTILITY_CLASS); jmethodID getNetworkType = (*env)->GetStaticMethodID(env, cls, "getNetworkType", "(Ljava/lang/String;)I"); jint interface_type = (*env)->CallStaticIntMethod(env, cls, getNetworkType, diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c index 508c0713b..8d3e18cdb 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c +++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c @@ -327,13 +327,12 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) switch(facelet_get_event(facelet)) { case FACELET_EVENT_CREATE: - - /* Create face */ { + /* Create face */ char buf[MAXSZ_FACELET]; facelet_snprintf(buf, MAXSZ_FACELET, facelet); DEBUG("Create facelet %s", buf); - } + hc_face.face = *face; rc = hc_face_create(data->s, &hc_face); if (rc < 0) { @@ -341,7 +340,8 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; goto ERR; } - INFO("Created face id=%d", hc_face.id); + INFO("Created face id=%d - %s", hc_face.id, buf); + } hicn_route_t ** route_array; int n = facelet_get_route_array(facelet, &route_array); @@ -413,7 +413,6 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) case FACELET_EVENT_DELETE: /* Removing a face should also remove associated routes */ - /* Create face */ hc_face.face = *face; rc = hc_face_delete(data->s, &hc_face); if (rc < 0) { @@ -421,6 +420,11 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; goto ERR; } + + char buf[MAXSZ_FACELET]; + facelet_snprintf(buf, MAXSZ_FACELET, facelet); + INFO("Deleted face id=%d", hc_face.id); + break; case FACELET_EVENT_UPDATE: @@ -457,7 +461,8 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) goto ERR; } facelet_set_admin_state_status(facelet, FACELET_ATTR_STATUS_CLEAN); - INFO("Admin state updated"); + INFO("Updated face id=%d - admin_state=%s", hc_face.id, + face_state_str(admin_state)); } #ifdef WITH_POLICY if (facelet_get_netdevice_type_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { @@ -517,7 +522,8 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) goto ERR; } facelet_set_netdevice_type_status(facelet, FACELET_ATTR_STATUS_CLEAN); - INFO("Tags updated"); + INFO("Updated face id=%d - netdevice_type=%s", hc_face.id, + netdevice_type_str(netdevice_type)); } if (facelet_get_priority_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { INFO("Updating priority..."); @@ -549,7 +555,8 @@ int hl_on_event(interface_t * interface, facelet_t * facelet) goto ERR; } facelet_set_priority_status(facelet, FACELET_ATTR_STATUS_CLEAN); - INFO("Priority updated"); + + INFO("Updated face id=%d - priority=%d", hc_face.id, priority); } #endif /* WITH_POLICY */ break; @@ -642,6 +649,11 @@ int hl_callback(interface_t * interface, int fd, void * unused) /* We can ignore faces on localhost */ facelet_t * facelet = facelet_create_from_face(&f->face); + if (!facelet) { + ERROR("[hl_callback] Could not create facelet... skipping"); + continue; + } + foreach_route(r, data->polled_routes) { if (r->face_id != f->id) continue; diff --git a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c index 76538185f..67edc5e39 100644 --- a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c +++ b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -27,19 +27,110 @@ #include <hicn/facemgr.h> +#include "priority_controller.h" #include "../../common.h" #include "../../interface.h" #define PC_DEFAULT_PORT 9533 typedef struct { + priority_controller_cfg_t cfg; int fd; +#ifdef PRIORITY_CONTROLLER_INTERNAL + unsigned state; + JNIEnv * env; + jclass cls; + jmethodID mid; +#endif /* PRIORITY_CONTROLLER_INTERNAL */ } pc_data_t; +#ifdef PRIORITY_CONTROLLER_INTERNAL +#include <jni.h> + +#define ERR_STR_JAVA "Java VM parameters are required in the interface configuration." + +#define PREFER_CELLULAR 0 +#define PREFER_WIFI 1 +#define PREFER_BOTH 2 + +#define INTERVAL_MS 500 + +const char * prefer_str[] = { "Cellular", "WiFi", "both" }; + +jclass find_class_global(JNIEnv* env, const char *name){ + jclass c = (*env)->FindClass(env, name); + jclass c_global = 0; + if (c){ + c_global = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + } + return c_global; +} + + +int priority_controller_tick(interface_t * interface, int fd, void * unused) +{ + pc_data_t * data = (pc_data_t*)interface->data; + unsigned new_state = PREFER_BOTH; + + jint rssi = (*data->env)->CallStaticIntMethod(data->env, data->cls, data->mid); + DEBUG("[priority_controller_tick] rssi=%d\n", rssi); + if (rssi > -67) { + new_state = PREFER_WIFI; + +#if 0 + } else if ((rssi < -67) && (rssi > -70)) { + new_state = PREFER_BOTH; +#endif + + } else { /* rssi < -70 */ + new_state = PREFER_CELLULAR; + } + + if (new_state == data->state) + return 0; + + ERROR("[priority_controller_tick] Setting priority to %s", prefer_str[new_state]); + + /* XXX Factor this */ + + facelet_t * facelet_w = facelet_create(); + facelet_t * facelet_c = facelet_create(); + facelet_set_netdevice_type(facelet_w, NETDEVICE_TYPE_WIFI); + facelet_set_netdevice_type(facelet_c, NETDEVICE_TYPE_CELLULAR); + facelet_set_attr_clean(facelet_w); + facelet_set_attr_clean(facelet_c); + + switch(new_state) { + case PREFER_CELLULAR: + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 10); + break; + case PREFER_WIFI: + facelet_set_priority(facelet_w, 10); + facelet_set_priority(facelet_c, 0); + break; + case PREFER_BOTH: + facelet_set_priority(facelet_w, 0); + facelet_set_priority(facelet_c, 0); + break; + } + + facelet_set_event(facelet_w, FACELET_EVENT_UPDATE); + facelet_set_event(facelet_c, FACELET_EVENT_UPDATE); + + interface_raise_event(interface, facelet_w); + interface_raise_event(interface, facelet_c); + + data->state = new_state; + + return 0; +} +#endif /* PRIORITY_CONTROLLER_INTERNAL */ + int priority_controller_initialize(interface_t * interface, void * cfg) { INFO("Initializing priority controller"); - struct sockaddr_in addr; pc_data_t * data = malloc(sizeof(pc_data_t)); if (!data) { @@ -49,6 +140,33 @@ int priority_controller_initialize(interface_t * interface, void * cfg) interface->data = data; + data->cfg = * (priority_controller_cfg_t *) cfg; + +#ifdef PRIORITY_CONTROLLER_INTERNAL + + if (!cfg) { + ERROR(ERR_STR_JAVA); + goto ERR_CFG; + } + + /* Retrieve RSSI information from SDK through AndroidUtility class */ + (*data->cfg.jvm)->AttachCurrentThread(data->cfg.jvm, &data->env, NULL); + data->cls = find_class_global(data->env, FACEMGR_ANDROID_UTILITY_CLASS); + if (data->cls == 0) + goto ERR_JAVA; + data->mid = (*data->env)->GetStaticMethodID(data->env, data->cls, "getWifiRSSI", "()I"); + + data->fd = interface_register_timer(interface, INTERVAL_MS, + priority_controller_tick, interface); + if (data->fd < 0) { + ERROR("[priority_controller_initialize] Could not initialize timer"); + goto ERR_FD; + } + data->state = PREFER_BOTH; + +#else /* PRIORITY_CONTROLLER_INTERNAL */ + struct sockaddr_in addr; + data->fd = socket(AF_INET, SOCK_DGRAM, 0); //data->fd = socket(AF_INET, SOCK_STREAM, 0); if (data->fd < 0) { @@ -67,18 +185,28 @@ int priority_controller_initialize(interface_t * interface, void * cfg) perror("bind error"); goto ERR_BIND; } + + DEBUG("[priority_controller_initialize] register fd"); if (interface_register_fd(interface, data->fd, NULL) < 0) { ERROR("[priority_controller_initialize] Error registering fd"); goto ERR_FD; } +#endif /* PRIORITY_CONTROLLER_INTERNAL */ + INFO("Priority controller successfully initialized"); return 0; +#ifdef PRIORITY_CONTROLLER_INTERNAL +ERR_CFG: +ERR_JAVA: +#endif /* PRIORITY_CONTROLLER_INTERNAL */ ERR_FD: +#ifndef PRIORITY_CONTROLLER_INTERNAL ERR_BIND: close(data->fd); ERR_SOCKET: +#endif /* ! PRIORITY_CONTROLLER_INTERNAL */ free(data); ERR_MALLOC: return -1; @@ -88,12 +216,21 @@ int priority_controller_finalize(interface_t * interface) { pc_data_t * data = (pc_data_t*)interface->data; - if (data->fd > 0) {close(data->fd);} +#ifdef PRIORITY_CONTROLLER_INTERNAL + DEBUG("[priority_controller_finalize] unregister timer"); + interface_unregister_timer(interface, data->fd); +#else + if (data->fd > 0) { + interface_unregister_fd(interface, data->fd); + close(data->fd); + } free(data); +#endif /* PRIORITY_CONTROLLER_INTERNAL */ return 0; } +#ifndef PRIORITY_CONTROLLER_INTERNAL int priority_controller_callback(interface_t * interface, int fd, void * unused) { pc_data_t * data = (pc_data_t*)interface->data; @@ -148,10 +285,13 @@ int priority_controller_callback(interface_t * interface, int fd, void * unused) return 0; } +#endif /* ! PRIORITY_CONTROLLER_INTERNAL */ interface_ops_t priority_controller_ops = { .type = "priority_controller", .initialize = priority_controller_initialize, .finalize = priority_controller_finalize, +#ifndef PRIORITY_CONTROLLER_INTERNAL .callback = priority_controller_callback, +#endif /* ! PRIORITY_CONTROLLER_INTERNAL */ }; diff --git a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h new file mode 100644 index 000000000..247fc3c57 --- /dev/null +++ b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file priority_controller.h + * \brief Priority Controller interface + */ + +#ifndef FACEMGR_INTERFACE_PRIORITY_CONTROLLER +#define FACEMGR_INTERFACE_PRIORITY_CONTROLLER + +#define FACEMGR_UTILITY_CLASS "com/cisco/hicn/facemgrlibrary/supportlibrary/FacemgrUtility" + +/* + * Uncomment this line to use a Priority controller interface internal to the + * face manager (only available in Android). + */ +// #define PRIORITY_CONTROLLER_INTERNAL + +#ifdef __ANDROID__ +#include <jni.h> +#endif /* __ANDROID__ */ + +typedef struct { +#ifdef __ANDROID__ +#ifdef PRIORITY_CONTROLLER_INTERNAL + JavaVM * jvm; +#endif /* PRIORITY_CONTROLLER_INTERNAL */ +#endif /* __ANDROID__ */ +} priority_controller_cfg_t; + + +#endif /* FACEMGR_INTERFACE_PRIORITY_CONTROLLER */ diff --git a/ctrl/facemgr/src/main.c b/ctrl/facemgr/src/main.c index da5e55943..344b034ae 100644 --- a/ctrl/facemgr/src/main.c +++ b/ctrl/facemgr/src/main.c @@ -186,7 +186,7 @@ MAIN_LOOP: facemgr_set_callback(facemgr, loop, (void*)loop_callback); #ifdef __ANDROID__ - facemgr_set_jvm(facemgr, NULL, NULL); // FIXME + facemgr_set_jvm(facemgr, NULL); #endif /* __ ANDROID__ */ DEBUG("Bootstrap..."); |