[HICN-660] Add priority priority control example based on RSSI 22/30322/2
authorJordan Augé <jordan.auge+fdio@cisco.com>
Mon, 7 Dec 2020 10:21:24 +0000 (11:21 +0100)
committerJordan Augé <jordan.auge+fdio@cisco.com>
Mon, 7 Dec 2020 16:32:48 +0000 (17:32 +0100)
Change-Id: Idc940d600e436f39fe78cd44bc29bd696c7dc9d6
Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
ctrl/facemgr/src/api.c
ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c
ctrl/facemgr/src/interfaces/priority_controller/priority_controller.h [new file with mode: 0644]
hicn-light/src/hicn/io/hicnListener.c

index f934883..aeca057 100644 (file)
@@ -63,6 +63,8 @@
 #include "interfaces/android_utility/android_utility.h"
 #endif /* WITH_ANDROID_UTILITY */
 
+#include "interfaces/priority_controller/priority_controller.h"
+
 #include <hicn/ctrl/face.h>
 #include <hicn/facemgr/facelet.h>
 #include "common.h"
@@ -2258,7 +2260,12 @@ facemgr_bootstrap(facemgr_t * facemgr)
 
 #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;
index 7653818..9845796 100644 (file)
@@ -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:
 
 #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);
+    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("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");
@@ -49,6 +140,32 @@ 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 */
+
     data->fd = socket(AF_INET, SOCK_DGRAM, 0);
     //data->fd = socket(AF_INET, SOCK_STREAM, 0);
     if (data->fd < 0) {
@@ -72,13 +189,21 @@ int priority_controller_initialize(interface_t * interface, void * cfg)
         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 +213,18 @@ 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
+    interface_unregister_timer(interface, data->fd);
+#else
+    if (data->fd > 0)
+        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 +279,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 (file)
index 0000000..bc81b68
--- /dev/null
@@ -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_ANDROID_UTILITY_CLASS "com/cisco/hicn/forwarder/supportlibrary/AndroidUtility"
+
+/*
+ * 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 */
index bc49f4c..7d911b1 100644 (file)
@@ -228,6 +228,7 @@ ListenerOps *hicnListener_CreateInet(Forwarder *forwarder, char *symbolic,
 
   hicn->forwarder = forwarder;
   hicn->listenerName = parcMemory_StringDuplicate(symbolic, strlen(symbolic));
+  hicn->logger = logger_Acquire(forwarder_GetLogger(forwarder));
 
   hicn->conn_id = forwarder_GetNextConnectionId(forwarder);
   hicn->inetFamily = IPv4;