[Add basic opensync build support]
[Description]
Add basic opensync build support
1.Add basic opensync v2.0.5 build back
2.Add opensync v3.2.x build support(v3.2.7 test ok)
3.Default disable opensync build
[Release-log]
N/A
diff --git a/recipes-common/mesh-agent/files/enabling_dhcp_lease_resync.patch b/recipes-common/mesh-agent/files/enabling_dhcp_lease_resync.patch
new file mode 100644
index 0000000..b149b34
--- /dev/null
+++ b/recipes-common/mesh-agent/files/enabling_dhcp_lease_resync.patch
@@ -0,0 +1,54 @@
+From cc64f3a69d13feda1b9f07b8f572080436d7560b Mon Sep 17 00:00:00 2001
+From: "rajakumaran.a" <rajakumaran.a@lnttechservices.com>
+Date: Thu, 2 Apr 2020 10:09:05 +0000
+Subject: [PATCH] Mesh dns lease update
+
+Signed-off-by: rajakumaran.a <rajakumaran.a@lnttechservices.com>
+Change-Id: Ib098c6d444b75d15120b2224ff46869b0e436c2f
+---
+ source/MeshAgentSsp/cosa_mesh_apis.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/source/MeshAgentSsp/cosa_mesh_apis.c b/source/MeshAgentSsp/cosa_mesh_apis.c
+index 46ed117..566cc0d 100644
+--- a/source/MeshAgentSsp/cosa_mesh_apis.c
++++ b/source/MeshAgentSsp/cosa_mesh_apis.c
+@@ -2154,7 +2154,9 @@ static void *Mesh_sysevent_handler(void *data)
+ async_id_t mesh_enable_asyncid;
+ async_id_t mesh_url_asyncid;
+ async_id_t wifi_txRate_asyncid;
+-
++#ifdef _PLATFORM_TURRIS_
++ async_id_t lease_resync_asyncid;
++#endif
+ sysevent_set_options(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_WIFI_RESET].sysStr, TUPLE_FLAG_EVENT);
+ sysevent_setnotification(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_WIFI_RESET].sysStr, &wifi_init_asyncid);
+ sysevent_set_options(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_WIFI_SSID_NAME].sysStr, TUPLE_FLAG_EVENT);
+@@ -2195,6 +2197,10 @@ static void *Mesh_sysevent_handler(void *data)
+ sysevent_set_options(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_WIFI_TXRATE].sysStr, TUPLE_FLAG_EVENT);
+ sysevent_setnotification(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_WIFI_TXRATE].sysStr, &wifi_txRate_asyncid);
+
++#ifdef _PLATFORM_TURRIS_
++ sysevent_set_options(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_DHCP_RESYNC_LEASES].sysStr, TUPLE_FLAG_EVENT);
++ sysevent_setnotification(sysevent_fd, sysevent_token, meshSyncMsgArr[MESH_DHCP_RESYNC_LEASES].sysStr, &lease_resync_asyncid);
++#endif
+
+ for (;;)
+ {
+@@ -3198,6 +3204,13 @@ static void *Mesh_sysevent_handler(void *data)
+ }
+ }
+ }
++#ifdef _PLATFORM_TURRIS_
++ else if (strcmp(name, meshSyncMsgArr[MESH_DHCP_RESYNC_LEASES].sysStr)==0)
++ {
++ //This will handle sending lease information to plume for every new connection, without restarting the MeshAgent
++ Mesh_sendDhcpLeaseSync();
++ }
++#endif
+ else
+ {
+ MeshWarning("undefined event %s \n",name);
+--
+2.24.0
+
diff --git a/recipes-common/mesh-agent/files/meshagent-enable-ovs-default.patch b/recipes-common/mesh-agent/files/meshagent-enable-ovs-default.patch
new file mode 100644
index 0000000..2fbdb31
--- /dev/null
+++ b/recipes-common/mesh-agent/files/meshagent-enable-ovs-default.patch
@@ -0,0 +1,13 @@
+diff --git a/source/MeshAgentSsp/cosa_mesh_apis.c b/source/MeshAgentSsp/cosa_mesh_apis.c
+index c100dfd..a33b37e 100644
+--- a/source/MeshAgentSsp/cosa_mesh_apis.c
++++ b/source/MeshAgentSsp/cosa_mesh_apis.c
+@@ -2497,7 +2497,7 @@ static void Mesh_SetDefaults(ANSC_HANDLE hThisObject)
+ if(Mesh_SysCfgGetStr("mesh_ovs_enable", out_val, sizeof(out_val)) != 0)
+ {
+ MeshInfo("Syscfg error, Setting OVS mode to default\n");
+- Mesh_SetOVS(false,true,true);
++ Mesh_SetOVS(true,true,true);
+ }
+ else
+ {
diff --git a/recipes-common/mesh-agent/mesh-agent.bbappend b/recipes-common/mesh-agent/mesh-agent.bbappend
new file mode 100644
index 0000000..957517c
--- /dev/null
+++ b/recipes-common/mesh-agent/mesh-agent.bbappend
@@ -0,0 +1,36 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "\
+file://enabling_dhcp_lease_resync.patch;apply=no \
+file://meshagent-enable-ovs-default.patch;apply=no \
+"
+
+DEPENDS_append_dunfell = " safec trower-base64"
+RDEPENDS_${PN}_append_dunfell = " bash"
+
+# we need to patch to code for mesh-agent
+do_turris_meshagent_patches() {
+ cd ${S}
+ if [ ! -e patch_applied ]; then
+ bbnote "Patching enabling_dhcp_lease_resync.patch"
+ patch -p1 < ${WORKDIR}/enabling_dhcp_lease_resync.patch ${S}/source/MeshAgentSsp/cosa_mesh_apis.c
+
+ bbnote "Patching meshagent-enable-ovs-default.patch"
+ patch -p1 < ${WORKDIR}/meshagent-enable-ovs-default.patch ${S}/source/MeshAgentSsp/cosa_mesh_apis.c
+
+ touch patch_applied
+ fi
+}
+addtask turris_meshagent_patches after do_unpack before do_configure
+
+do_install_append () {
+ install -D -m 0644 ${S}/systemd_units/meshAgent.service ${D}${systemd_unitdir}/system/meshAgent.service
+}
+
+FILES_${PN}_append = "${systemd_unitdir}/system/meshAgent.service"
+
+CFLAGS_append = " -D_PLATFORM_TURRIS_"
+
+LDFLAGS_append_dunfell = " -lsyscfg -lsysevent -lbreakpadwrapper -lsafec-3.5.1"
+
+LDFLAGS_remove_dunfell = "-lsafec-3.5"
diff --git a/recipes-connectivity/opensync/files/0001-add-mesh-header-file.patch b/recipes-connectivity/opensync/files/0001-add-mesh-header-file.patch
new file mode 100644
index 0000000..6b6cdef
--- /dev/null
+++ b/recipes-connectivity/opensync/files/0001-add-mesh-header-file.patch
@@ -0,0 +1,322 @@
+diff --git a/src/lib/target/inc/mesh/meshsync_msgs.h b/src/lib/target/inc/mesh/meshsync_msgs.h
+new file mode 100644
+index 0000000..03d5c6a
+--- /dev/null
++++ b/src/lib/target/inc/mesh/meshsync_msgs.h
+@@ -0,0 +1,316 @@
++/*
++ * If not stated otherwise in this file or this component's Licenses.txt file the
++ * following copyright and licenses apply:
++ *
++ * Copyright 2018 RDK Management
++ *
++ * 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.
++*/
++
++/*
++ * meshcfg.h
++ *
++ */
++
++#ifndef MESHCFG_H_
++#define MESHCFG_H_
++
++#include <sys/types.h>
++#include <inttypes.h>
++
++#define MAX_SSID_LEN 65
++#define MAX_PASS_LEN 65
++#define MAX_MODE_LEN 25
++#define MAX_SUBNET_LEN 25
++#define MAX_IP_LEN 64
++#define MAX_URL_LEN 256
++#define MAX_TXRATE_LEN 256
++#define MAX_CHANNEL_MODE_LEN 32
++#define MAX_MAC_ADDR_LEN 18
++#define MAX_HOSTNAME_LEN 256
++
++#if defined(ENABLE_MESH_SOCKETS)
++/**************************************************************************/
++/* Unix Domain Socket Name */
++/**************************************************************************/
++#define MESH_SOCKET_PATH_NAME "\0/tmp/mesh-socket-queue" // MeshAgent Server message socket
++#else
++/**************************************************************************/
++/* Posix Message Queue Names */
++/**************************************************************************/
++#define MESH_SERVER_QUEUE_NAME "/mqueue-mesh-server" // Message traffic from Mesh Application Layer to RDKB
++#define MESH_CLIENT_QUEUE_NAME "/mqueue-mesh-client" // Message traffic from RDKB to Mesh Application Layer
++#endif
++
++#define MAX_FINGERPRINT_LEN 512
++/**************************************************************************/
++/* Mesh sync message types */
++/**************************************************************************/
++typedef enum {
++ MESH_WIFI_RESET,
++ MESH_WIFI_RADIO_CHANNEL,
++ MESH_WIFI_RADIO_CHANNEL_MODE,
++ MESH_WIFI_SSID_NAME,
++ MESH_WIFI_SSID_ADVERTISE,
++ MESH_WIFI_AP_SECURITY,
++ MESH_WIFI_AP_KICK_ASSOC_DEVICE,
++ MESH_WIFI_AP_KICK_ALL_ASSOC_DEVICES,
++ MESH_WIFI_AP_ADD_ACL_DEVICE,
++ MESH_WIFI_AP_DEL_ACL_DEVICE,
++ MESH_WIFI_MAC_ADDR_CONTROL_MODE,
++ MESH_SUBNET_CHANGE,
++ MESH_URL_CHANGE,
++ MESH_WIFI_STATUS,
++ MESH_WIFI_ENABLE,
++ MESH_STATE_CHANGE,
++ MESH_WIFI_TXRATE,
++ MESH_CLIENT_CONNECT,
++ MESH_DHCP_RESYNC_LEASES,
++ MESH_DHCP_ADD_LEASE,
++ MESH_DHCP_REMOVE_LEASE,
++ MESH_DHCP_UPDATE_LEASE,
++ MESH_WIFI_RADIO_CHANNEL_BW,
++ MESH_SYNC_MSG_TOTAL
++} eMeshSyncType;
++
++/**
++ * Mesh States
++ */
++typedef enum {
++ MESH_STATE_FULL = 0,
++ MESH_STATE_MONITOR,
++ MESH_STATE_WIFI_RESET,
++ MESH_STATE_TOTAL
++} eMeshStateType;
++
++/**
++ * Mesh Status states
++ */
++typedef enum {
++ MESH_WIFI_STATUS_OFF = 0,
++ MESH_WIFI_STATUS_INIT,
++ MESH_WIFI_STATUS_MONITOR,
++ MESH_WIFI_STATUS_FULL,
++ MESH_WIFI_STATUS_TOTAL
++} eMeshWifiStatusType;
++
++/**
++ * Mesh Connected Client Interfaces
++ */
++typedef enum {
++ MESH_IFACE_NONE = 0,
++ MESH_IFACE_ETHERNET,
++ MESH_IFACE_MOCA,
++ MESH_IFACE_WIFI,
++ MESH_IFACE_OTHER,
++ MESH_IFACE_TOTAL
++} eMeshIfaceType;
++
++/**
++ * Mesh Sync Wifi Reset/Init message
++ */
++typedef struct _MeshWifiReset {
++ uint8_t reset; // boolean dummy value for structure set to true.
++} MeshWifiReset;
++
++/**
++ * Mesh Sync Wifi SSID name change message
++ */
++typedef struct _MeshWifiSSIDName {
++ uint32_t index; // index [0-15]
++ char ssid[MAX_SSID_LEN]; // SSID
++} MeshWifiSSIDName;
++
++/**
++ * Mesh Sync Wifi SSID Advertise change message
++ */
++typedef struct _MeshWifiSSIDAdvertise {
++ uint32_t index; // index [0-15]
++ uint8_t enable; // boolean enable
++} MeshWifiSSIDAdvertise;
++
++/**
++ * Mesh Sync Wifi Radio channel change
++ */
++typedef struct _MeshWifiRadioChannel {
++ uint32_t index; // Radio index
++ uint32_t channel; // Channel
++} MeshWifiRadioChannel;
++
++/**
++ * Mesh Sync Wifi Radio channel mode change
++ */
++typedef struct _MeshWifiRadioChannelMode {
++ uint32_t index; // Radio index
++ char channelMode[MAX_CHANNEL_MODE_LEN]; // ChannelMode
++ uint8_t gOnlyFlag; // Is this g only?
++ uint8_t nOnlyFlag; // Is this n only?
++ uint8_t acOnlyFlag; // Is this ac only?
++} MeshWifiRadioChannelMode;
++
++
++/**
++ * Mesh Sync Wifi configuration change message
++ */
++typedef struct _MeshWifiAPSecurity {
++ uint32_t index; // AP index [0-15]
++ char passphrase[MAX_PASS_LEN]; // AP Passphrase
++ char secMode[MAX_MODE_LEN]; // Security mode
++ char encryptMode[MAX_MODE_LEN]; // Encryption mode
++} MeshWifiAPSecurity;
++
++
++/**
++ * Mesh Sync Wifi Kick AP Associated Device based on device mac
++ */
++typedef struct _MeshWifiAPKickAssocDevice {
++ uint32_t index; // AP index [0-15]
++ char mac[MAX_MAC_ADDR_LEN]; // Mac Address
++} MeshWifiAPKickAssocDevice;
++
++/**
++ * Mesh Sync Wifi Kick All AP Associated Devices
++ */
++typedef struct _MeshWifiAPKickAllAssocDevices {
++ uint32_t index; // AP index [0-15]
++} MeshWifiAPKickAllAssocDevices;
++
++
++/**
++ * Mesh Sync Wifi AP Add Acl Device
++ */
++typedef struct _MeshWifiAPAddAclDevice {
++ uint32_t index; // AP index [0-15]
++ char mac[MAX_MAC_ADDR_LEN]; // Mac Address
++} MeshWifiAPAddAclDevice;
++
++
++/**
++ * Mesh Sync Wifi AP Delete Acl Device
++ */
++typedef struct _MeshWifiAPDelAclDevice {
++ uint32_t index; // AP index [0-15]
++ char mac[MAX_MAC_ADDR_LEN]; // Mac Address
++} MeshWifiAPDelAclDevice;
++
++/**
++ * Mesh Sync Wifi Mac Address Control Mode
++ */
++typedef struct _MeshWifiMacAddrControlMode {
++ uint32_t index; // AP index [0-15]
++ uint8_t isEnabled; // Filter Enabled bool
++ uint8_t isBlacklist; // blacklist=1; whitelist=0
++} MeshWifiMacAddrControlMode;
++
++
++/**
++ * Mesh Sync Subnet configuration change message
++ */
++typedef struct _MeshSubnetChange {
++ char gwIP[MAX_IP_LEN]; // GW IP value
++ char netmask[MAX_SUBNET_LEN]; // Subnet value
++} MeshSubnetChange;
++
++/**
++ * Mesh Sync URL configuration change message
++ */
++typedef struct _MeshUrlChange {
++ char url[MAX_URL_LEN]; // url
++} MeshUrlChange;
++
++/**
++ * Mesh Network Status message
++ */
++typedef struct _MeshWifiStatus {
++ eMeshWifiStatusType status; // Status of mesh network
++} MeshWifiStatus;
++
++/**
++ * Mesh State message
++ */
++typedef struct _MeshStateChange {
++ eMeshStateType state; // State of mesh network
++} MeshStateChange;
++
++/**
++ * Mesh WiFi TxRate
++ */
++typedef struct _MeshWifiTxRate {
++ uint32_t index; // AP index [0-15]
++ char basicRates[MAX_TXRATE_LEN]; // Basic Rates
++ char opRates [MAX_TXRATE_LEN]; // Operational Rates
++} MeshWifiTxRate;
++
++/**
++ * Mesh Client Connect
++ */
++typedef struct _MeshClientConnect {
++ eMeshIfaceType iface; // Interface
++ char mac[MAX_MAC_ADDR_LEN]; // MAC address
++ char host[MAX_HOSTNAME_LEN]; // Hostname
++ uint8_t isConnected; // true=connected; false=offline/disconnected
++} MeshClientConnect;
++
++/**
++ * DHCP lease notification
++ */
++typedef struct _MeshWifiDhcpLease {
++ char mac[MAX_MAC_ADDR_LEN];
++ char ipaddr[MAX_IP_LEN];
++ char hostname[MAX_HOSTNAME_LEN];
++ char fingerprint[MAX_FINGERPRINT_LEN];
++} MeshWifiDhcpLease;
++
++/**
++ * Channel Bandwidth change notification
++ */
++typedef struct _MeshWifiRadioChannelBw {
++ int index;
++ int bw;
++} MeshWifiRadioChannelBw;
++
++/**
++ * Mesh Sync message
++ */
++typedef struct _MeshSync {
++ eMeshSyncType msgType;
++
++ union {
++ MeshWifiReset wifiReset;
++ MeshWifiRadioChannel wifiRadioChannel;
++ MeshWifiRadioChannelMode wifiRadioChannelMode;
++ MeshWifiSSIDName wifiSSIDName;
++ MeshWifiSSIDAdvertise wifiSSIDAdvertise;
++ MeshWifiAPSecurity wifiAPSecurity;
++ MeshWifiAPKickAssocDevice wifiAPKickAssocDevice;
++ MeshWifiAPKickAllAssocDevices wifiAPKickAllAssocDevices;
++ MeshWifiAPAddAclDevice wifiAPAddAclDevice;
++ MeshWifiAPDelAclDevice wifiAPDelAclDevice;
++ MeshWifiMacAddrControlMode wifiMacAddrControlMode;
++ MeshSubnetChange subnet;
++ MeshUrlChange url;
++ MeshWifiStatus wifiStatus;
++ MeshStateChange meshState;
++ MeshWifiTxRate wifiTxRate;
++ MeshClientConnect meshConnect;
++ MeshWifiDhcpLease meshLease;
++ MeshWifiRadioChannelBw wifiRadioChannelBw;
++ } data;
++} MeshSync;
++
++typedef struct _LeaseNotify {
++ MeshWifiDhcpLease lease;
++ eMeshSyncType msgType;
++} LeaseNotify;
++
++#endif /* MESHCFG_H_ */
diff --git a/recipes-connectivity/opensync/files/999-mtk-add-vendor.patch b/recipes-connectivity/opensync/files/999-mtk-add-vendor.patch
new file mode 100644
index 0000000..2cfb4f6
--- /dev/null
+++ b/recipes-connectivity/opensync/files/999-mtk-add-vendor.patch
@@ -0,0 +1,12 @@
+diff -urN a/vendor/turris/build/vendor-arch.mk b/vendor/turris/build/vendor-arch.mk
+--- a/vendor/turris/build/vendor-arch.mk 2022-06-02 12:40:23.648854464 +0800
++++ b/vendor/turris/build/vendor-arch.mk 2022-06-02 12:41:07.232071037 +0800
+@@ -9,7 +9,7 @@
+
+ # To customize: This vendor layer supports Turris Omnia as a residential / business gateway
+ # and Turris Omnia as Extender/GW. Put your machine name here.
+-ifeq ($(RDK_MACHINE),$(filter $(RDK_MACHINE),turris turris-extender turris-bci turris_5.10))
++ifeq ($(RDK_MACHINE),$(filter $(RDK_MACHINE),filogic830 turris turris-extender turris-bci turris_5.10))
+
+ # To customize: put OEM and MODEL names here
+ RDK_OEM = turris
diff --git a/recipes-connectivity/opensync/files/999-mtk-fix-64bit-build.patch b/recipes-connectivity/opensync/files/999-mtk-fix-64bit-build.patch
new file mode 100644
index 0000000..8de0c1b
--- /dev/null
+++ b/recipes-connectivity/opensync/files/999-mtk-fix-64bit-build.patch
@@ -0,0 +1,45 @@
+diff -urN a/core/src/bm/src/bm_ieee80211.c b/core/src/bm/src/bm_ieee80211.c
+--- a/core/src/bm/src/bm_ieee80211.c 2022-06-02 13:18:30.792245507 +0800
++++ b/core/src/bm/src/bm_ieee80211.c 2022-06-02 13:19:57.178711952 +0800
+@@ -294,7 +294,7 @@
+ memset(&client->op_classes, 0, sizeof(client->op_classes));
+
+ if (len > BM_CLIENT_MAX_OP_CLASSES) {
+- LOGW("%s Size of operating classes more than expected (%d): %d",
++ LOGW("%s Size of operating classes more than expected (%zu): %d",
+ client->mac_addr, len, BM_CLIENT_MAX_OP_CLASSES);
+ client->op_classes.size = BM_CLIENT_MAX_OP_CLASSES;
+ } else {
+diff -urN a/platform/rdk/src/lib/target/src/bsal_legacy.c b/platform/rdk/src/lib/target/src/bsal_legacy.c
+--- a/platform/rdk/src/lib/target/src/bsal_legacy.c 2022-06-02 13:03:06.764635550 +0800
++++ b/platform/rdk/src/lib/target/src/bsal_legacy.c 2022-06-02 13:03:48.023904674 +0800
+@@ -1068,7 +1068,7 @@
+ memcpy(info, &client_info_cache->client, sizeof(*info));
+ }
+ #endif
+- LOGI("BSAL Client "MAC_ADDR_FMT" is connected apIndex: %d, SNR: %d, rx: %lld, tx: %lld", MAC_ADDR_UNPACK(mac_addr),
++ LOGI("BSAL Client "MAC_ADDR_FMT" is connected apIndex: %d, SNR: %d, rx: %zu, tx: %zu", MAC_ADDR_UNPACK(mac_addr),
+ apIndex, info->snr, info->rx_bytes, info->tx_bytes);
+
+ break;
+diff -urN a/platform/rdk/src/tools/band_steering_test/bs_testd/bs_testd.c b/platform/rdk/src/tools/band_steering_test/bs_testd/bs_testd.c
+--- a/platform/rdk/src/tools/band_steering_test/bs_testd/bs_testd.c 2022-06-02 13:32:26.222966518 +0800
++++ b/platform/rdk/src/tools/band_steering_test/bs_testd/bs_testd.c 2022-06-02 13:35:42.306842191 +0800
+@@ -906,7 +906,7 @@
+ }
+
+ total_bytes += bytes;
+- LOGD("total_bytes = %d\n", total_bytes);
++ LOGD("total_bytes = %zu\n", total_bytes);
+
+ if (total_bytes >= (ssize_t)sizeof(buf) && buf[sizeof(buf) - 1] != '\0')
+ {
+@@ -921,7 +921,7 @@
+ // Otherwise we're blocking (on purpose).
+ // in case of client malfunction this loop needs to be interrupted by a signal.
+ // Non-blocking variant may be implemented in the future.
+- LOGD("incomplete, bytes = %d , buf = >>%s<<\n", bytes, buf);
++ LOGD("incomplete, bytes = %zu , buf = >>%s<<\n", bytes, buf);
+ incomplete = true;
+ ptr += bytes;
+ continue;
diff --git a/recipes-connectivity/opensync/files/MeshAgentSync.patch b/recipes-connectivity/opensync/files/MeshAgentSync.patch
new file mode 100644
index 0000000..a704bb7
--- /dev/null
+++ b/recipes-connectivity/opensync/files/MeshAgentSync.patch
@@ -0,0 +1,62 @@
+diff --git a/src/lib/target/inc/target_internal.h b/src/lib/target/inc/target_internal.h
+index 1608b03..c520ad2 100644
+--- a/src/lib/target/inc/target_internal.h
++++ b/src/lib/target/inc/target_internal.h
+@@ -171,6 +171,9 @@ bool maclearn_update(maclearn_type_t type,
+ bool radio_cloud_mode_set(radio_cloud_mode_t mode);
+ radio_cloud_mode_t radio_cloud_mode_get(void);
+ bool radio_rops_vstate(struct schema_Wifi_VIF_State *vstate);
++#if defined(_PLATFORM_TURRIS_)
++bool radio_rops_vconfig(struct schema_Wifi_VIF_Config *vconfig,const char *ifname);
++#endif
+ void radio_trigger_resync(void);
+
+ void clients_connection(INT apIndex,
+diff --git a/src/lib/target/src/radio.c b/src/lib/target/src/radio.c
+index 9bedd00..b0cbe33 100644
+--- a/src/lib/target/src/radio.c
++++ b/src/lib/target/src/radio.c
+@@ -786,6 +786,20 @@ void radio_trigger_resync()
+ }
+ }
+
++#if defined(_PLATFORM_TURRIS_)
++bool radio_rops_vconfig(struct schema_Wifi_VIF_Config *vconfig , const char *ifname)
++{
++ if (!g_rops.op_vconf)
++ {
++ LOGE("%s: op_vconfig not set", __func__);
++ return false;
++ }
++
++ g_rops.op_vconf(vconfig, ifname);
++ return true;
++}
++#endif
++
+ bool radio_rops_vstate(struct schema_Wifi_VIF_State *vstate)
+ {
+ if (!g_rops.op_vstate)
+diff --git a/src/lib/target/src/vif.c b/src/lib/target/src/vif.c
+index aaecbf9..4e6b4ed 100644
+--- a/src/lib/target/src/vif.c
++++ b/src/lib/target/src/vif.c
+@@ -1071,7 +1071,17 @@ bool vif_state_update(INT ssidIndex)
+ LOGE("%s: cannot update VIF state for SSID index %d", __func__, ssidIndex);
+ return false;
+ }
++#if defined(_PLATFORM_TURRIS_)
++ /* After setting Wifi_VIF_State, updating Wifi_VIF_Config table also in order to avoid overwritting content from Wifi_VIF_Config */
+
++ struct schema_Wifi_VIF_Config vconfig;
++
++ if (vif_copy_to_config(ssidIndex, &vstate, &vconfig))
++ {
++ LOGE("%s: copying VIF state to config for SSID index %d", __func__, ssidIndex);
++ radio_rops_vconfig(&vconfig, vconfig.if_name);
++ }
++#endif
+ LOGN("Updating VIF state for SSID index %d", ssidIndex);
+ return radio_rops_vstate(&vstate);
+ }
+
diff --git a/recipes-connectivity/opensync/files/absolute-value-glibc-dunfell-fix.patch b/recipes-connectivity/opensync/files/absolute-value-glibc-dunfell-fix.patch
new file mode 100644
index 0000000..0348ebb
--- /dev/null
+++ b/recipes-connectivity/opensync/files/absolute-value-glibc-dunfell-fix.patch
@@ -0,0 +1,30 @@
+diff --git a/src/bm/src/bm_events.c b/src/bm/src/bm_events.c
+index 19bcd47..dfdf33c 100644
+--- a/src/bm/src/bm_events.c
++++ b/src/bm/src/bm_events.c
+@@ -315,14 +315,14 @@ bm_events_handle_event(bsal_event_t *event)
+ }
+
+ /* This one managed by cloud */
+- if (abs(stats->probe.last_snr - event->data.probe_req.rssi) < client->preq_snr_thr) {
++ if (abs((int32_t)(stats->probe.last_snr - event->data.probe_req.rssi)) < client->preq_snr_thr) {
+ LOGD("[%s] %s: %s skip preq report (%d %d)", bandstr, ifname, client->mac_addr,
+ stats->probe.last_snr, event->data.probe_req.rssi);
+ break;
+ }
+
+ /* This is short time probe report filtering/limitation */
+- if (abs(stats->probe.last_snr - event->data.probe_req.rssi) <= BM_CLIENT_PREQ_SNR_TH &&
++ if (abs((int32_t)(stats->probe.last_snr - event->data.probe_req.rssi)) <= BM_CLIENT_PREQ_SNR_TH &&
+ (now - last_probe) < BM_CLIENT_PREQ_TIME_TH) {
+ LOGD("[%s] %s: %s skip preq report (%d %d) short time", bandstr, ifname, client->mac_addr,
+ stats->probe.last_snr, event->data.probe_req.rssi);
+@@ -790,7 +790,7 @@ bm_events_handle_rssi_xing(bm_client_t *client, bsal_event_t *event)
+ {
+ if (event->data.rssi_change.low_xing == client->xing_low &&
+ event->data.rssi_change.high_xing == client->xing_high &&
+- (abs(event->data.rssi_change.rssi - client->xing_snr) <= BM_CLIENT_SNR_XING_DIFF)) {
++ (abs((int32_t)(event->data.rssi_change.rssi - client->xing_snr)) <= BM_CLIENT_SNR_XING_DIFF)) {
+ LOGT("%s same xing skip (%d, %d) snr %d old %d", client->mac_addr, client->xing_low, client->xing_high,
+ event->data.rssi_change.rssi, client->xing_snr);
+ return;
diff --git a/recipes-connectivity/opensync/files/disable-dry-run.patch b/recipes-connectivity/opensync/files/disable-dry-run.patch
new file mode 100644
index 0000000..a493102
--- /dev/null
+++ b/recipes-connectivity/opensync/files/disable-dry-run.patch
@@ -0,0 +1,19 @@
+commit 61e04f8186c734312e0641a198f96a59f049f666
+Author: Mateusz Bajorski <mbajorski@plume.com>
+Date: Thu Jan 30 16:46:33 2020 +0000
+
+ disable dry run
+
+diff --git a/src/cm2/unit.mk b/src/cm2/unit.mk
+index 8abe642..922e1fd 100644
+--- a/src/cm2/unit.mk
++++ b/src/cm2/unit.mk
+@@ -52,6 +52,8 @@ UNIT_LDFLAGS += -ldl
+ UNIT_LDFLAGS += -lev
+ UNIT_LDFLAGS += -lrt
+
++UNIT_CFLAGS += -DCONFIG_PLUME_CM2_DISABLE_DRYRUN_ON_GRE
++
+ ifneq ($(CONFIG_USE_KCONFIG),y)
+ # Disable dryrun on GRE by default for all platforms without KConfig
+ UNIT_CFLAGS += -DCONFIG_PLUME_CM2_DISABLE_DRYRUN_ON_GRE
diff --git a/recipes-connectivity/opensync/files/dunfell-nm-crash-fix.patch b/recipes-connectivity/opensync/files/dunfell-nm-crash-fix.patch
new file mode 100644
index 0000000..78a53b6
--- /dev/null
+++ b/recipes-connectivity/opensync/files/dunfell-nm-crash-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/src/lib/inet/src/inet_base.c b/src/lib/inet/src/inet_base.c
+index a93cefc..db66cf2 100644
+--- a/src/lib/inet/src/inet_base.c
++++ b/src/lib/inet/src/inet_base.c
+@@ -1080,7 +1080,7 @@ bool inet_base_dhcpc_option_set(inet_t *super, enum osn_dhcp_option opt, const c
+ {
+ inet_base_t *self = (void *)super;
+ bool _req;
+- const char *_value;
++ const char *_value=NULL;
+
+ if (!osn_dhcp_client_opt_get(self->in_dhcpc, opt, &_req, &_value))
+ {
diff --git a/recipes-connectivity/opensync/files/get-used-link-type.patch b/recipes-connectivity/opensync/files/get-used-link-type.patch
new file mode 100644
index 0000000..20eebf6
--- /dev/null
+++ b/recipes-connectivity/opensync/files/get-used-link-type.patch
@@ -0,0 +1,13 @@
+Index: core/src/cm2/src/cm2_ovsdb.c
+===================================================================
+--- core.orig/src/cm2/src/cm2_ovsdb.c 2020-01-27 15:10:38.435076332 +0000
++++ core/src/cm2/src/cm2_ovsdb.c 2020-01-27 15:11:01.481520930 +0000
+@@ -861,7 +861,7 @@
+ }
+
+ bool cm2_connection_get_used_link(struct schema_Connection_Manager_Uplink *uplink) {
+- return ovsdb_table_select_one(&table_Connection_Manager_Uplink, SCHEMA_COLUMN(Connection_Manager_Uplink, is_used), "true", uplink);
++ return ovsdb_table_select_one_where(&table_Connection_Manager_Uplink, ovsdb_where_simple_typed(SCHEMA_COLUMN(Connection_Manager_Uplink, is_used), "true",OCLM_BOOL), uplink);
+ }
+
+ static void cm2_connection_clear_used(void)
diff --git a/recipes-connectivity/opensync/files/opensync.service b/recipes-connectivity/opensync/files/opensync.service
new file mode 100644
index 0000000..f58393e
--- /dev/null
+++ b/recipes-connectivity/opensync/files/opensync.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=OpenSync service
+After=hostapd.service
+
+[Service]
+Type=forking
+ExecStart=/usr/opensync/scripts/managers.init start
+Restart=always
+StartLimitIntervalSec=120
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/recipes-connectivity/opensync/files/rdk-ext-support.patch b/recipes-connectivity/opensync/files/rdk-ext-support.patch
new file mode 100644
index 0000000..fc6ddf9
--- /dev/null
+++ b/recipes-connectivity/opensync/files/rdk-ext-support.patch
@@ -0,0 +1,86 @@
+diff --git a/ovsdb/inet.json b/ovsdb/inet.json
+index af2994e..4adb651 100644
+--- a/ovsdb/inet.json
++++ b/ovsdb/inet.json
+@@ -19,6 +19,32 @@
+ "if_type": "bridge",
+ "enabled": true
+ }
++ },
++ {
++ "op":"insert",
++ "table":"Wifi_Inet_Config",
++ "row": {
++ "if_name": "bhaul-sta-24",
++ "ip_assign_scheme": "dhcp",
++ "mtu": 1600,
++ "if_type": "vif",
++ "enabled" : true,
++ "network" : true,
++ "NAT": false
++ }
++ },
++ {
++ "op":"insert",
++ "table":"Wifi_Inet_Config",
++ "row": {
++ "if_name": "bhaul-sta-50",
++ "ip_assign_scheme": "dhcp",
++ "mtu": 1600,
++ "if_type": "vif",
++ "enabled" : true,
++ "network" : true,
++ "NAT": false
++ }
+ }
+ ]
+
+diff --git a/src/lib/target/src/map.c b/src/lib/target/src/map.c
+index 55af881..fa535f9 100644
+--- a/src/lib/target/src/map.c
++++ b/src/lib/target/src/map.c
+@@ -20,10 +20,12 @@ typedef struct
+
+ static ifmap_t ifmap[] = {
+ // idx cloud-ifname dev-ifname bridge gre-br vlan description
+- { 1, "wifi2", "wifi2", "brlan0", "wifi2", 0 }, // 2G Backhaul
+- { 1, "wifi3", "wifi3", "brlan0", "wifi3", 0 }, // 5G Backhaul
+- { 2, "wifi0", "wifi0", "brlan0", NULL, 0 }, // 2G User SSID
+- { 2, "wifi1", "wifi1", "brlan0", NULL, 0 }, // 5G User SSID
++ { 0, "bhaul-sta-24", "bhaul-sta-24", "br-wan", "bhaul-sta-24", 0 }, // 2G Backhaul
++ { 0, "bhaul-sta-50", "bhaul-sta-50", "br-wan", "bhaul-sta-50", 0 }, // 2G Backhaul
++ { 1, "wifi2", "wifi2", "br-home", "wifi2", 0 }, // 2G Backhaul
++ { 1, "wifi3", "wifi3", "br-home", "wifi3", 0 }, // 5G Backhaul
++ { 2, "wifi0", "wifi0", "br-home", NULL, 0 }, // 2G User SSID
++ { 2, "wifi1", "wifi1", "br-home", NULL, 0 }, // 5G User SSID
+ { 0, NULL, NULL, NULL, NULL, 0 }
+ };
+
+diff --git a/src/lib/target/src/target.c b/src/lib/target/src/target.c
+index de884b5..59c1b59 100644
+--- a/src/lib/target/src/target.c
++++ b/src/lib/target/src/target.c
+@@ -5,3 +5,23 @@ const char* target_tls_privkey_filename(void)
+ {
+ return "/usr/plume/etc/certs/client_dec.key";
+ }
++
++bool target_device_connectivity_check(const char *ifname,
++ target_connectivity_check_t *cstate,
++ target_connectivity_check_option_t opts)
++{
++ cstate->ntp_state = true;
++ cstate->link_state = true;
++ cstate->router_state = true;
++ cstate->internet_state = true;
++ return true;
++}
++
++int target_device_capabilities_get()
++{
++#if defined(CONFIG_RDK_EXTENDER)
++ return TARGET_EXTENDER_TYPE;
++#else
++ return 0;
++#endif
++}
diff --git a/recipes-connectivity/opensync/files/rdk-extender.patch b/recipes-connectivity/opensync/files/rdk-extender.patch
new file mode 100644
index 0000000..56c99ad
--- /dev/null
+++ b/recipes-connectivity/opensync/files/rdk-extender.patch
@@ -0,0 +1,563 @@
+diff --git a/kconfig/Kconfig.platform b/kconfig/Kconfig.platform
+new file mode 100644
+index 0000000..4a045b2
+--- /dev/null
++++ b/kconfig/Kconfig.platform
+@@ -0,0 +1,15 @@
++menuconfig PLATFORM_IS_RDK
++ bool "RDK"
++ help
++ Support for RDK-based platforms
++
++
++if PLATFORM_IS_RDK
++
++config RDK_EXTENDER
++ bool "RDK Extender device (EXPERIMENTAL)"
++ default n
++
++
++endif
++
+diff --git a/src/lib/osn/override.mk b/src/lib/osn/override.mk
+index bf128b7..ff210ed 100644
+--- a/src/lib/osn/override.mk
++++ b/src/lib/osn/override.mk
+@@ -33,11 +33,22 @@ UNIT_EXPORT_CFLAGS := -I$(UNIT_PATH)/inc
+ UNIT_SRC := src/osn_inet.c
+ UNIT_SRC += src/osn_types.c
+
++#if extender
++ifeq ($(CONFIG_RDK_EXTENDER),y)
++UNIT_SRC += src/osn_dnsmasq.c
++UNIT_SRC += src/osn_udhcpc.c
++UNIT_SRC += src/osn_route.c
++endif
++
+ UNIT_SRC_DIR := $(OVERRIDE_DIR)/src
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_upnpd.c
++
++ifneq ($(CONFIG_RDK_EXTENDER),y)
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_dhcpc.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_route.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_dhcps.c
++endif
++
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_dhcps6.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_odhcp6c.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/osn_inet6.c
+diff --git a/src/lib/osn/src/osn_dhcps.c b/src/lib/osn/src/osn_dhcps.c
+index d183172..f2885fd 100644
+--- a/src/lib/osn/src/osn_dhcps.c
++++ b/src/lib/osn/src/osn_dhcps.c
+@@ -284,11 +284,13 @@ static bool dhcp_server_init(osn_dhcp_server_t *self, const char *ifname)
+ return false;
+ }
+
++#ifndef CONFIG_RDK_EXTENDER
+ if (!sync_init(SYNC_MGR_NM))
+ {
+ LOGE("Cannot init sync manager for NM");
+ return false;
+ }
++#endif
+
+ /* Initialize this instance */
+ memset(self, 0 ,sizeof(*self));
+diff --git a/src/lib/osync_hal/src/inet.c b/src/lib/osync_hal/src/inet.c
+index b221667..580ff83 100644
+--- a/src/lib/osync_hal/src/inet.c
++++ b/src/lib/osync_hal/src/inet.c
+@@ -304,7 +304,11 @@ osync_hal_return_t osync_hal_inet_add_to_bridge(
+
+ memset(cmd, 0, sizeof(cmd));
+
++#ifdef CONFIG_RDK_EXTENDER
++ snprintf(cmd, sizeof(cmd), "ovs-vsctl add-port %s %s", br_name, if_name);
++#else
+ snprintf(cmd, sizeof(cmd), "brctl addif %s %s", br_name, if_name);
++#endif
+ LOGD("%s: Adding to bridge with \"%s\"", if_name, cmd);
+ rc = system(cmd);
+ if (!WIFEXITED(rc) || WEXITSTATUS(rc) != 0)
+diff --git a/src/lib/target/inc/target_internal.h b/src/lib/target/inc/target_internal.h
+index 1608b03..61f0f06 100644
+--- a/src/lib/target/inc/target_internal.h
++++ b/src/lib/target/inc/target_internal.h
+@@ -35,7 +35,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include "osync_hal.h"
+ #include "osn_dhcp.h"
+
++#if !defined(CONFIG_RDK_EXTENDER)
+ #include <mesh/meshsync_msgs.h> // needed only by sync_send_security_change()
++#endif
+
+ #ifndef __WIFI_HAL_H__
+ #include "ccsp/wifi_hal.h"
+@@ -182,12 +184,15 @@ bool sync_init(sync_mgr_t mgr);
+ bool sync_cleanup(void);
+ bool sync_send_ssid_change(INT ssid_index, const char *ssid_ifname,
+ const char *new_ssid);
++#if !defined(CONFIG_RDK_EXTENDER)
+ bool sync_send_security_change(INT ssid_index, const char *ssid_ifname,
+ MeshWifiAPSecurity *sec);
++#endif
+ bool sync_send_status(radio_cloud_mode_t mode);
+
+ bool vif_state_update(INT ssidIndex);
+ bool vif_state_get(INT ssidIndex, struct schema_Wifi_VIF_State *vstate);
++bool vif_state_sta_get(INT ssidIndex, struct schema_Wifi_VIF_State *vstate);
+ bool vif_copy_to_config(INT ssidIndex, struct schema_Wifi_VIF_State *vstate,
+ struct schema_Wifi_VIF_Config *vconf);
+ struct target_radio_ops;
+diff --git a/src/lib/target/override.mk b/src/lib/target/override.mk
+index 8c37835..369d2a5 100644
+--- a/src/lib/target/override.mk
++++ b/src/lib/target/override.mk
+@@ -44,7 +44,11 @@ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/radio.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/vif.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/stats.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/log.c
++
++ifneq ($(CONFIG_RDK_EXTENDER),y)
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/sync.c
++endif
++
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/maclearn.c
+ UNIT_SRC_TOP += $(UNIT_SRC_DIR)/bsal.c
+
+@@ -53,6 +57,8 @@ UNIT_CFLAGS += -DENABLE_MESH_SOCKETS
+
+ UNIT_DEPS := $(PLATFORM_DIR)/src/lib/devinfo
+ UNIT_DEPS += $(PLATFORM_DIR)/src/lib/osync_hal
++
++#UNIT_DEPS += src/lib/kconfig
+ UNIT_DEPS += src/lib/evsched
+ UNIT_DEPS += src/lib/schema
+ UNIT_DEPS += src/lib/const
+@@ -66,6 +72,7 @@ endif
+
+ UNIT_LDFLAGS := $(SDK_LIB_DIR) -lhal_wifi -lrt
+ UNIT_CFLAGS += -DCONTROLLER_ADDR="\"$(shell echo -n $(CONTROLLER_ADDR))\""
++UNIT_CFLAGS += -include "$(KCONFIG_WORK).h"
+
+ UNIT_EXPORT_CFLAGS := $(UNIT_CFLAGS)
+ UNIT_EXPORT_LDFLAGS := $(UNIT_LDFLAGS)
+diff --git a/src/lib/target/src/radio.c b/src/lib/target/src/radio.c
+index 9bedd00..33a2032 100644
+--- a/src/lib/target/src/radio.c
++++ b/src/lib/target/src/radio.c
+@@ -72,6 +72,7 @@ static c_item_t map_country_str[] =
+ {
+ C_ITEM_STR_STR("826", "UK"), // ISO 3166-1
+ C_ITEM_STR_STR("840", "US"),
++ C_ITEM_STR_STR("705", "SI"), // (non-standard)
+ C_ITEM_STR_STR("841", "US"), // (non-standard)
+ };
+
+@@ -620,6 +621,62 @@ bool target_radio_config_init2()
+ g_rops.op_vconf(&vconfig, rconfig.if_name);
+ g_rops.op_vstate(&vstate);
+ }
++#ifdef CONFIG_RDK_EXTENDER
++ /* CLIENT-API */
++ ret = wifi_getSTANumberOfEntries(&snum);
++ if (ret != RETURN_OK)
++ {
++ LOGE("%s: failed to get SSID count", __func__);
++ return false;
++ }
++
++ for (s = 0; s < snum; s++)
++ {
++ memset(ssid_ifname, 0, sizeof(ssid_ifname));
++ ret = wifi_getSTAName(s, ssid_ifname);
++ if (ret != RETURN_OK)
++ {
++ LOGW("%s: failed to get STA name for index %lu. Skipping.\n", __func__, s);
++ continue;
++ }
++ // Filter SSID's that we don't have mappings for
++ if (!target_unmap_ifname_exists(ssid_ifname))
++ {
++ LOGW("%s: STA %s not in map. Skipping.\n", __func__, ssid_ifname);
++ continue;
++ }
++
++ ret = wifi_getSTARadioIndex(s, &ssid_radio_idx);
++ if (ret != RETURN_OK)
++ {
++ LOGW("Cannot get radio index for SSID %lu", s);
++ continue;
++ }
++
++ if ((ULONG)ssid_radio_idx != r)
++ {
++ continue;
++ }
++
++ LOGI("Found STA index %lu: %s", s, ssid_ifname);
++ if (!vif_state_sta_get(s, &vstate))
++ {
++ LOGE("%s: cannot get vif state for STA index %lu", __func__, s);
++ continue;
++ }
++ if (!vif_copy_to_config(s, &vstate, &vconfig))
++ {
++ LOGE("%s: cannot copy VIF state to config for STA index %lu", __func__, s);
++ continue;
++ }
++ g_rops.op_vconf(&vconfig, rconfig.if_name);
++ g_rops.op_vstate(&vstate);
++
++
++ }
++
++ /* END CLIENT-API */
++#endif
+
+ }
+
+@@ -807,6 +864,9 @@ bool
+ radio_cloud_mode_set(radio_cloud_mode_t mode)
+ {
+ radio_cloud_mode = mode;
+-
++#ifdef CONFIG_RDK_EXTENDER
++ return true;
++#else
+ return sync_send_status(radio_cloud_mode);
++#endif
+ }
+diff --git a/src/lib/target/src/sync.c b/src/lib/target/src/sync.c
+index 5b4337d..b8dfc17 100644
+--- a/src/lib/target/src/sync.c
++++ b/src/lib/target/src/sync.c
+@@ -43,7 +43,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include <sys/socket.h>
+ #include <sys/un.h>
+
++#ifndef CONFIG_RDK_EXTENDER
+ #include <mesh/meshsync_msgs.h> // this file is included by vendor
++#endif
+
+ #include "os.h"
+ #include "log.h"
+@@ -146,6 +148,7 @@ static char* sync_iface_name(int iface_type)
+ return tmp;
+ }
+
++#ifndef CONFIG_RDK_EXTENDER
+ static int wiifhal_sync_iface_mltype(int iface_type)
+ {
+ c_item_t *citem;
+@@ -157,7 +160,7 @@ static int wiifhal_sync_iface_mltype(int iface_type)
+
+ return -1;
+ }
+-
++#endif
+ static void sync_process_msg(MeshSync *mp)
+ {
+ radio_cloud_mode_t cloud_mode;
+diff --git a/src/lib/target/src/target.c b/src/lib/target/src/target.c
+index ffaaf6a..ef20eda 100644
+--- a/src/lib/target/src/target.c
++++ b/src/lib/target/src/target.c
+@@ -281,12 +281,13 @@ bool target_init(target_init_opt_t opt, struct ev_loop *loop)
+ "(Failed to initialize EVSCHED)");
+ return -1;
+ }
+-
++ #ifndef CONFIG_RDK_EXTENDER
+ if (!sync_init(SYNC_MGR_WM))
+ {
+ // It reports the error
+ return false;
+ }
++ #endif
+ if (!set_deauth_and_scan_filter_flags())
+ {
+ LOGE("Failed to set csa_deauth and scan filter flags");
+@@ -296,11 +297,13 @@ bool target_init(target_init_opt_t opt, struct ev_loop *loop)
+ break;
+
+ case TARGET_INIT_MGR_CM:
++ #ifndef CONFIG_RDK_EXTENDER
+ if (!sync_init(SYNC_MGR_CM))
+ {
+ // It reports the error
+ return false;
+ }
++ #endif
+ break;
+
+ case TARGET_INIT_MGR_BM:
+@@ -323,7 +326,9 @@ bool target_close(target_init_opt_t opt, struct ev_loop *loop)
+ switch (opt)
+ {
+ case TARGET_INIT_MGR_WM:
++ #ifndef CONFIG_RDK_EXTENDER
+ sync_cleanup();
++ #endif
+ /* fall through */
+
+ case TARGET_INIT_MGR_SM:
+diff --git a/src/lib/target/src/vif.c b/src/lib/target/src/vif.c
+index aaecbf9..a987aa3 100644
+--- a/src/lib/target/src/vif.c
++++ b/src/lib/target/src/vif.c
+@@ -262,7 +262,8 @@ static bool acl_apply(
+
+ return true;
+ }
+-
++//FIXME: is this needed only for mesh something?
++#if !defined(CONFIG_RDK_EXTENDER)
+ static const char* security_conf_find_by_key(
+ const struct schema_Wifi_VIF_Config *vconf,
+ char *key)
+@@ -279,6 +280,7 @@ static const char* security_conf_find_by_key(
+
+ return NULL;
+ }
++#endif
+
+ static bool security_to_state(
+ INT ssid_index,
+@@ -449,7 +451,7 @@ static bool security_to_state(
+ vstate->security_len = n;
+ return true;
+ }
+-
++#if !defined(CONFIG_RDK_EXTENDER)
+ static bool security_to_syncmsg(
+ const struct schema_Wifi_VIF_Config *vconf,
+ MeshWifiAPSecurity *dest)
+@@ -527,7 +529,7 @@ static bool security_to_syncmsg(
+
+ return true;
+ }
+-
++#endif
+ static bool vif_is_enabled(INT ssid_index)
+ {
+ BOOL enabled = false;
+@@ -602,10 +604,177 @@ bool vif_copy_to_config(
+ STRSCPY(vconf->mac_list[i], vstate->mac_list[i]);
+ }
+ vconf->mac_list_len = vstate->mac_list_len;
++ /* CLIENT-API */
++ SCHEMA_SET_STR(vconf->parent, vstate->parent);
++ LOGT("vconf->parent = %s", vconf->parent);
++ SCHEMA_SET_INT(vconf->uapsd_enable, vstate->uapsd_enable);
++ LOGT("vconf->uapsd_enable = %d", vconf->uapsd_enable);
++
+
+ return true;
+ }
+
++#if defined(CONFIG_RDK_EXTENDER)
++/* CLIENT-API */
++
++bool vif_state_sta_get(INT ssidIndex, struct schema_Wifi_VIF_State *vstate)
++{
++ CHAR buf[WIFIHAL_MAX_BUFFER];
++ INT ret;
++ char ssid_ifname[128];
++ hw_mode_t min_hw_mode;
++ INT radio_idx;
++ char band[128];
++ BOOL gOnly, nOnly, acOnly;
++ char *str;
++ ULONG lval;
++ int n = 0;
++
++ memset(vstate, 0, sizeof(*vstate));
++ schema_Wifi_VIF_State_mark_all_present(vstate);
++ vstate->_partial_update = true;
++ vstate->associated_clients_present = false;
++ vstate->vif_config_present = false;
++ memset(ssid_ifname, 0, sizeof(ssid_ifname));
++
++ ret = wifi_getSTAName(ssidIndex, ssid_ifname);
++ if (ret != RETURN_OK)
++ {
++ LOGE("%s: cannot get sta name for index %d", __func__, ssidIndex);
++ return false;
++ }
++
++ SCHEMA_SET_STR(vstate->if_name, target_unmap_ifname(ssid_ifname));
++
++ SCHEMA_SET_STR(vstate->mode, "sta");
++ SCHEMA_SET_INT(vstate->enabled, true);
++ SCHEMA_SET_INT(vstate->uapsd_enable, false);
++ SCHEMA_SET_INT(vstate->vif_radio_idx, target_map_ifname_to_vif_radio_idx(vstate->if_name));
++
++ // mac (w/ exists)
++ memset(buf, 0, sizeof(buf));
++ ret = wifi_getSTAMAC(ssidIndex, buf);
++ if (ret != RETURN_OK)
++ {
++ LOGW("%s: Failed to get STA (mac)", ssid_ifname);
++ }
++ else
++ {
++ SCHEMA_SET_STR(vstate->mac, buf);
++ }
++
++ // mac (w/ exists)
++ memset(buf, 0, sizeof(buf));
++ ret = wifi_getSTABSSID(ssidIndex, buf);
++ if (ret != RETURN_OK)
++ {
++ LOGW("%s: Failed to get STA (parent)", ssid_ifname);
++ }
++ else
++ {
++ SCHEMA_SET_STR(vstate->parent, buf);
++ }
++
++
++ ret = wifi_getSSIDRadioIndex(ssidIndex, &radio_idx);
++ if (ret != RETURN_OK)
++ {
++ LOGE("%s: cannot get radio idx for SSID %s\n", __func__, ssid_ifname);
++ return false;
++ }
++
++
++ memset(band, 0, sizeof(band));
++ ret = wifi_getRadioOperatingFrequencyBand(radio_idx, band);
++ if (ret != RETURN_OK)
++ {
++ LOGE("%s: cannot get radio band for idx %d", __func__, radio_idx);
++ return false;
++ }
++
++
++ // min_hw_mode (w/ exists)
++ if (band[0] == '5')
++ {
++ min_hw_mode = HW_MODE_11A;
++ } else
++ {
++ min_hw_mode = HW_MODE_11B;
++ }
++ ret = wifi_getRadioStandard(radio_idx, buf, &gOnly, &nOnly, &acOnly);
++ if (ret != RETURN_OK)
++ {
++ LOGW("%s: Failed to get min_hw_mode from %d", ssid_ifname, radio_idx);
++ }
++ else
++ {
++ if (gOnly)
++ {
++ min_hw_mode = HW_MODE_11G;
++ }
++ else if (nOnly)
++ {
++ min_hw_mode = HW_MODE_11N;
++ }
++ else if (acOnly)
++ {
++ min_hw_mode = HW_MODE_11AC;
++ }
++ }
++
++ str = c_get_str_by_key(map_hw_mode, min_hw_mode);
++ if (strlen(str) == 0)
++ {
++ LOGW("%s: failed to encode min_hw_mode (%d)",
++ ssid_ifname, min_hw_mode);
++ }
++ else
++ {
++ SCHEMA_SET_STR(vstate->min_hw_mode, str);
++ }
++ // channel (w/ exists)
++ ret = wifi_getRadioChannel(radio_idx, &lval);
++ if (ret != RETURN_OK)
++ {
++ LOGW("%s: Failed to get channel from radio idx %d", ssid_ifname, radio_idx);
++ }
++ else
++ {
++ SCHEMA_SET_INT(vstate->channel, lval);
++ }
++
++
++ SCHEMA_SET_STR(vstate->ssid_broadcast, "disabled");
++ SCHEMA_SET_STR(vstate->mac_list_type, "none");
++ SCHEMA_SET_INT(vstate->btm, 0);
++ SCHEMA_SET_INT(vstate->rrm, 0);
++ SCHEMA_SET_INT(vstate->wds, 0);
++ SCHEMA_SET_INT(vstate->ap_bridge, false);
++ //Wifi credentials
++ SCHEMA_SET_STR(vstate->ssid, "opensync.onboard");
++
++ strncpy(vstate->security_keys[n],
++ OVSDB_SECURITY_ENCRYPTION,
++ sizeof(vstate->security_keys[n]) - 1);
++
++ strncpy(vstate->security[n],
++ OVSDB_SECURITY_ENCRYPTION_WPA_PSK,
++ sizeof(vstate->security[n]) - 1);
++ n++;
++ strncpy(vstate->security_keys[n],
++ OVSDB_SECURITY_KEY,
++ sizeof(vstate->security_keys[n]) - 1);
++ strncpy(vstate->security[n],
++ "7eCyoqETHiJzKBBALPFP9X8mVy4dwCga",
++ sizeof(vstate->security[n]) - 1);
++
++ n++;
++ vstate->security_len = n;
++ return true;
++
++}
++#endif
++
+ bool vif_state_get(INT ssidIndex, struct schema_Wifi_VIF_State *vstate)
+ {
+ ULONG lval;
+@@ -888,7 +1055,9 @@ bool target_vif_config_set2(
+ INT ret;
+ c_item_t *citem;
+ char tmp[256];
++#if !defined(CONFIG_RDK_EXTENDER)
+ MeshWifiAPSecurity sec;
++#endif
+ const char *ssid_ifname = target_map_ifname((char *)vconf->if_name);
+
+ if (!vif_ifname_to_idx(ssid_ifname, &ssid_index))
+@@ -966,10 +1135,12 @@ bool target_vif_config_set2(
+ else
+ {
+ LOGI("%s: SSID updated to '%s'", ssid_ifname, tmp);
++ #if !defined(CONFIG_RDK_EXTENDER)
+ if (!sync_send_ssid_change(ssid_index, ssid_ifname, vconf->ssid))
+ {
+ LOGE("%s: Failed to sync SSID change to '%s'", ssid_ifname, vconf->ssid);
+ }
++ #endif
+ }
+ }
+ }
+@@ -977,6 +1148,8 @@ bool target_vif_config_set2(
+
+ if (changed->security && vconf->security_len)
+ {
++ //TODO: add proper WA
++ #if !defined(CONFIG_RDK_EXTENDER)
+ memset(&sec, 0, sizeof(sec));
+ if (!security_to_syncmsg(vconf, &sec))
+ {
+@@ -1018,6 +1191,7 @@ bool target_vif_config_set2(
+ }
+ }
+ }
++ #endif
+ }
+
+
diff --git a/recipes-connectivity/opensync/files/remove-log-dup.patch b/recipes-connectivity/opensync/files/remove-log-dup.patch
new file mode 100644
index 0000000..8890e94
--- /dev/null
+++ b/recipes-connectivity/opensync/files/remove-log-dup.patch
@@ -0,0 +1,20 @@
+Index: rdk/rootfs/common/usr/plume/scripts/managers.init
+===================================================================
+--- rdk.orig/rootfs/common/usr/plume/scripts/managers.init 2020-01-27 15:26:13.921034680 +0000
++++ rdk/rootfs/common/usr/plume/scripts/managers.init 2020-01-27 15:27:04.707089802 +0000
+@@ -133,15 +133,6 @@
+
+ echo "Starting OpenSync managers"
+ start-stop-daemon -c ${RUN_USER} -S -b -x ${PLUME_BIN_DIR}/dm
+- sleep 10
+- managers="DM WM SM CM LM BM QM OM FSM"
+- ${PLUME_OVSH} d AW_Debug
+- for m in $managers
+- do
+- ${PLUME_OVSH} i AW_Debug name:=$m log_severity:=CRIT
+- done
+- sleep 3
+- ${PLUME_OVSH} i AW_Debug name:=NM log_severity:=CRIT
+ }
+
+ plume_stop() {
diff --git a/recipes-connectivity/opensync/files/service.patch b/recipes-connectivity/opensync/files/service.patch
new file mode 100644
index 0000000..582703a
--- /dev/null
+++ b/recipes-connectivity/opensync/files/service.patch
@@ -0,0 +1,10 @@
+diff --git a/service-provider/academy/build/provider.mk b/service-provider/academy/build/provider.mk
+new file mode 100644
+index 0000000..c81cafd
+--- /dev/null
++++ b/service-provider/academy/build/provider.mk
+@@ -0,0 +1,4 @@
++VALID_IMAGE_DEPLOYMENT_PROFILES += dev-academy prod-academy
++
++CONTROLLER_ADDR="ssl:wildfire.plume.tech:443"
++PROVIDER_BACKHAUL_CREDS = bhaul-ssid:bhaul-password
diff --git a/recipes-connectivity/opensync/files/update-format-specifier-for-time_t.patch b/recipes-connectivity/opensync/files/update-format-specifier-for-time_t.patch
new file mode 100644
index 0000000..9c4bedf
--- /dev/null
+++ b/recipes-connectivity/opensync/files/update-format-specifier-for-time_t.patch
@@ -0,0 +1,22 @@
+diff --git a/src/sm/src/sm_survey_report.c b/src/sm/src/sm_survey_report.c
+index 3e464e8..c94008c 100644
+--- a/src/sm/src/sm_survey_report.c
++++ b/src/sm/src/sm_survey_report.c
+@@ -967,7 +967,7 @@ bool sm_survey_threshold_util_cb (
+ survey_ctx->threshold_record = *survey_entry;
+
+ int threshold_util = result_entry.chan_tx + result_entry.chan_self;
+- LOGD("Checking %s %s survey threshold util: %d/%d delay: %ld/%d count: %d/%d",
++ LOGD("Checking %s %s survey threshold util: %d/%d delay: %lld/%d count: %d/%d",
+ radio_get_name_from_cfg(radio_cfg_ctx),
+ radio_get_scan_name_from_type(scan_type),
+ threshold_util, request_ctx->threshold_util,
+@@ -1099,7 +1099,7 @@ bool sm_survey_stats_update (
+ scan_interval = SURVEY_MIN_SCAN_INTERVAL;
+
+ // always scan if max_delay exceeded
+- LOGI("Force processing %s %s survey delay: %ld/%d count: %d/%d",
++ LOGI("Force processing %s %s survey delay: %lld/%d count: %d/%d",
+ radio_get_name_from_cfg(radio_cfg_ctx),
+ radio_get_scan_name_from_type(scan_type),
+ survey_ctx->threshold_time_delta, request_ctx->threshold_max_delay,
diff --git a/recipes-connectivity/opensync/opensync_2.0.5.bbappend b/recipes-connectivity/opensync/opensync_2.0.5.bbappend
new file mode 100644
index 0000000..596c6ae
--- /dev/null
+++ b/recipes-connectivity/opensync/opensync_2.0.5.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+CORE_URI_remove = "${@bb.utils.contains('DISTRO_FEATURES', 'extender', 'file://0002-Use-osync_hal-in-inet_gretap.patch', '', d)}"
+
+CORE_URI_append_dunfell = " file://absolute-value-glibc-dunfell-fix.patch"
+CORE_URI_append_dunfell = " file://dunfell-nm-crash-fix.patch"
+CORE_URI_append_dunfell = " ${@bb.utils.contains('DISTRO_FEATURES', 'extender', 'file://update-format-specifier-for-time_t.patch', '', d)}"
+
+VENDOR_URI = "git://git@github.com/rdkcentral/opensync-vendor-rdk-turris.git;protocol=${CMF_GIT_PROTOCOL};branch=${CMF_GITHUB_MASTER_BRANCH};name=vendor;destsuffix=git/vendor/turris"
+VENDOR_URI += "file://service.patch;patchdir=${WORKDIR}/git/"
+VENDOR_URI += "file://opensync.service"
+
+DEPENDS_append = " rdk-logger hal-wifi-cfg80211"
+
+RDK_CFLAGS += " -D_PLATFORM_TURRIS_"
diff --git a/recipes-connectivity/opensync/opensync_3.%.bbappend b/recipes-connectivity/opensync/opensync_3.%.bbappend
new file mode 100644
index 0000000..4ab741b
--- /dev/null
+++ b/recipes-connectivity/opensync/opensync_3.%.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI_append_filogic = " file://999-mtk-add-vendor.patch;apply=no"
+SRC_URI_append_filogic = " file://999-mtk-fix-64bit-build.patch;apply=no"
+
+do_filogic_patches() {
+ cd ${S}/../
+ if [ ! -e patch_applied ]; then
+ patch -p1 < ${WORKDIR}/999-mtk-add-vendor.patch
+ patch -p1 < ${WORKDIR}/999-mtk-fix-64bit-build.patch
+ touch patch_applied
+ fi
+}
+
+addtask filogic_patches after do_patch before do_compile
diff --git a/recipes-core/images/rdk-generic-broadband-image.bbappend b/recipes-core/images/rdk-generic-broadband-image.bbappend
index c2ecfdd..7b6f187 100644
--- a/recipes-core/images/rdk-generic-broadband-image.bbappend
+++ b/recipes-core/images/rdk-generic-broadband-image.bbappend
@@ -19,6 +19,7 @@
pptp-linux \
rp-pppoe \
"
+#IMAGE_INSTALL += " opensync openvswitch mesh-agent e2fsprogs "
BB_HASH_IGNORE_MISMATCH = "1"
IMAGE_NAME[vardepsexclude] = "DATETIME"
diff --git a/recipes-networking/openvswitch/openvswitch_git.bbappend b/recipes-networking/openvswitch/openvswitch_git.bbappend
new file mode 100644
index 0000000..ccc2920
--- /dev/null
+++ b/recipes-networking/openvswitch/openvswitch_git.bbappend
@@ -0,0 +1,14 @@
+DEPENDS_remove_dunfell = "virtual/kernel bridge-utils"
+DEPENDS_append_class-target_dunfell = " virtual/kernel kernel-devsrc"
+DEPENDS_append_class-target_dunfell = " bridge-utils"
+EXTRA_OECONF += "--enable-ssl"
+
+EXTRA_OECONF_class-target_dunfell += "--with-linux=${STAGING_KERNEL_BUILDDIR} --with-linux-source=${STAGING_KERNEL_DIR} KARCH=${UBOOT_ARCH} PYTHON=python3 PYTHON3=python3 PERL=${bindir}/perl "
+
+#disable openvswitch autostart
+SYSTEMD_SERVICE_${PN}-switch = ""
+do_compile_prepend() {
+ export CROSS_COMPILE=`echo '${TARGET_PREFIX}'`
+}
+
+PACKAGECONFIG[ssl] = " "