Snap for 11164065 from e52af41550862775dfc3372daacf12873ce5eb8b to mainline-cellbroadcast-release

Change-Id: I0144781b3a2731ddacdb63fed6d871d54faba273
diff --git a/Android.bp b/Android.bp
index c5d672f..4769507 100644
--- a/Android.bp
+++ b/Android.bp
@@ -397,6 +397,7 @@
         "examples/platforms/simulation/uart.c",
         "examples/platforms/utils/link_metrics.cpp",
         "examples/platforms/utils/mac_frame.cpp",
+        "examples/platforms/utils/settings_ram.c",
         "examples/platforms/utils/soft_source_match_table.c",
     ],
 }
@@ -660,9 +661,11 @@
         "-DOPENTHREAD_CONFIG_MLR_ENABLE=1",
         "-DOPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1",
         "-DOPENTHREAD_CONFIG_PING_SENDER_ENABLE=1",
+        "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=0",
         "-DOPENTHREAD_EXAMPLES_SIMULATION=1",
         "-DOPENTHREAD_CONFIG_TCP_ENABLE=0",
         "-DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"examples/platforms/simulation/openthread-core-simulation-config.h\"",
+        "-DOPENTHREAD_SETTINGS_RAM=1",
         "-DPACKAGE=\"openthread\"",
         "-DPACKAGE_BUGREPORT=\"openthread-devel@googlegroups.com\"",
         "-DPACKAGE_NAME=\"OPENTHREAD\"",
@@ -994,7 +997,4 @@
     shared_libs: [
         "libcutils", // Required by src/core/instance_api.cpp
     ],
-
-    init_rc: ["src/android/ot-cli-ftd.rc"],
-    vendor: true,
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..9bafe29
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "imports": [
+    {
+      "path": "external/ot-br-posix"
+    }
+  ]
+}
diff --git a/include/openthread/link.h b/include/openthread/link.h
index d48d5d4..f4d203e 100644
--- a/include/openthread/link.h
+++ b/include/openthread/link.h
@@ -1183,6 +1183,39 @@
 otError otLinkSendEmptyData(otInstance *aInstance);
 
 /**
+ * Sets the region code.
+ *
+ * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+ *
+ * @param[in]  aInstance    The OpenThread instance structure.
+ * @param[in]  aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+ *                          and the `aRegionCode & 0xff` is the second ascii char.
+ *
+ * @retval  OT_ERROR_FAILED           Other platform specific errors.
+ * @retval  OT_ERROR_NONE             Successfully set region code.
+ * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented.
+ *
+ */
+otError otLinkSetRegion(otInstance *aInstance, uint16_t aRegionCode);
+
+/**
+ * Get the region code.
+ *
+ * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+
+ * @param[in]  aInstance    The OpenThread instance structure.
+ * @param[out] aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+ *                          and the `aRegionCode & 0xff` is the second ascii char.
+ *
+ * @retval  OT_ERROR_INVALID_ARGS     @p aRegionCode is nullptr.
+ * @retval  OT_ERROR_FAILED           Other platform specific errors.
+ * @retval  OT_ERROR_NONE             Successfully got region code.
+ * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented.
+ *
+ */
+otError otLinkGetRegion(otInstance *aInstance, uint16_t *aRegionCode);
+
+/**
  * @}
  *
  */
diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h
index d11549e..7f39d98 100644
--- a/include/openthread/platform/radio.h
+++ b/include/openthread/platform/radio.h
@@ -1186,7 +1186,8 @@
  * ISO 3166 alpha-2 code.
  *
  * @param[in]  aInstance    The OpenThread instance structure.
- * @param[in]  aRegionCode  The radio region.
+ * @param[in]  aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+ *                          and the `aRegionCode & 0xff` is the second ascii char.
  *
  * @retval  OT_ERROR_FAILED           Other platform specific errors.
  * @retval  OT_ERROR_NONE             Successfully set region code.
diff --git a/src/android/openthread-android-config.h b/src/android/openthread-android-config.h
index 2aa2915..e61482d 100644
--- a/src/android/openthread-android-config.h
+++ b/src/android/openthread-android-config.h
@@ -45,10 +45,9 @@
 #define OPENTHREAD_CONFIG_CLI_UART_RX_BUFFER_SIZE 3500
 
 /**
- * Disables the default posix infrastructure interface implementation
- * so that we can can use the Android specific implementation.
+ * Enables the default posix infrastructure interface implementation.
  */
-#define OPENTHREAD_POSIX_CONFIG_INFRA_IF_ENABLE 0
+#define OPENTHREAD_POSIX_CONFIG_INFRA_IF_ENABLE 1
 
 /**
  * Disables the default posix TUN interface implementation
diff --git a/src/android/ot-cli-ftd.rc b/src/android/ot-cli-ftd.rc
deleted file mode 100644
index 57d2d29..0000000
--- a/src/android/ot-cli-ftd.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-# The settings data directory for simulation `ot-cli-ftd` program
-on post-fs-data
-    mkdir /data/vendor/threadnetwork 0770 root root
-    mkdir /data/vendor/threadnetwork/simulation 0770 root root
diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp
index e2c66ae..9c32917 100644
--- a/src/cli/cli.cpp
+++ b/src/cli/cli.cpp
@@ -6658,7 +6658,7 @@
  * Done
  * @endcode
  * @par api_copy
- * #otPlatRadioGetRegion
+ * #otLinkGetRegion
  */
 template <> otError Interpreter::Process<Cmd("region")>(Arg aArgs[])
 {
@@ -6667,7 +6667,7 @@
 
     if (aArgs[0].IsEmpty())
     {
-        SuccessOrExit(error = otPlatRadioGetRegion(GetInstancePtr(), &regionCode));
+        SuccessOrExit(error = otLinkGetRegion(GetInstancePtr(), &regionCode));
         OutputLine("%c%c", regionCode >> 8, regionCode & 0xff);
     }
     /**
@@ -6677,7 +6677,7 @@
      * Done
      * @endcode
      * @par api_copy
-     * #otPlatRadioSetRegion
+     * #otLinkSetRegion
      * @par
      * Changing this can affect the transmit power limit.
      */
@@ -6688,7 +6688,7 @@
 
         regionCode = static_cast<uint16_t>(static_cast<uint16_t>(aArgs[0].GetCString()[0]) << 8) +
                      static_cast<uint16_t>(aArgs[0].GetCString()[1]);
-        error = otPlatRadioSetRegion(GetInstancePtr(), regionCode);
+        error = otLinkSetRegion(GetInstancePtr(), regionCode);
     }
 
 exit:
diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp
index f342627..95ec35c 100644
--- a/src/core/api/link_api.cpp
+++ b/src/core/api/link_api.cpp
@@ -460,3 +460,24 @@
     return AsCoreType(aInstance).Get<MeshForwarder>().SendEmptyMessage();
 }
 #endif
+
+otError otLinkSetRegion(otInstance *aInstance, uint16_t aRegionCode)
+{
+    return AsCoreType(aInstance).Get<Mac::Mac>().SetRegion(aRegionCode);
+}
+
+otError otLinkGetRegion(otInstance *aInstance, uint16_t *aRegionCode)
+{
+    Error error;
+
+    if (aRegionCode == nullptr)
+    {
+        error = kErrorInvalidArgs;
+    }
+    else
+    {
+        error = AsCoreType(aInstance).Get<Mac::Mac>().GetRegion(*aRegionCode);
+    }
+
+    return error;
+}
diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp
index aa13d3a..3140851 100644
--- a/src/core/mac/mac.cpp
+++ b/src/core/mac/mac.cpp
@@ -187,7 +187,7 @@
 
     if (aScanChannels == 0)
     {
-        aScanChannels = GetSupportedChannelMask().GetMask();
+        aScanChannels = mSupportedChannelMask.GetMask();
     }
 
     mScanChannelMask.SetMask(aScanChannels);
@@ -474,7 +474,7 @@
 {
     ChannelMask newMask = aMask;
 
-    newMask.Intersect(ChannelMask(Get<Radio>().GetSupportedChannelMask()));
+    newMask.Intersect(mSupportedChannelMask);
     IgnoreError(Get<Notifier>().Update(mSupportedChannelMask, newMask, kEventSupportedChannelMaskChanged));
 }
 
@@ -2105,6 +2105,21 @@
     UpdateIdleMode();
 }
 
+Error Mac::SetRegion(uint16_t aRegionCode)
+{
+    Error       error;
+    ChannelMask oldMask = mSupportedChannelMask;
+
+    SuccessOrExit(error = Get<Radio>().SetRegion(aRegionCode));
+    mSupportedChannelMask.SetMask(Get<Radio>().GetSupportedChannelMask());
+    IgnoreError(Get<Notifier>().Update(oldMask, mSupportedChannelMask, kEventSupportedChannelMaskChanged));
+
+exit:
+    return error;
+}
+
+Error Mac::GetRegion(uint16_t &aRegionCode) const { return Get<Radio>().GetRegion(aRegionCode); }
+
 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
 const uint32_t *Mac::GetDirectRetrySuccessHistogram(uint8_t &aNumberOfEntries)
 {
diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp
index e14d436..1b2ae6c 100644
--- a/src/core/mac/mac.hpp
+++ b/src/core/mac/mac.hpp
@@ -720,6 +720,36 @@
     bool IsRadioFilterEnabled(void) const { return mLinks.GetSubMac().IsRadioFilterEnabled(); }
 #endif
 
+    /**
+     * Sets the region code.
+     *
+     * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+     *
+     * @param[in]  aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+     *                          and the `aRegionCode & 0xff` is the second ascii char.
+     *
+     * @retval  kErrorFailed          Other platform specific errors.
+     * @retval  kErrorNone            Successfully set region code.
+     * @retval  kErrorNotImplemented  The feature is not implemented.
+     *
+     */
+    Error SetRegion(uint16_t aRegionCode);
+
+    /**
+     * Get the region code.
+     *
+     * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+     *
+     * @param[out] aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+     *                          and the `aRegionCode & 0xff` is the second ascii char.
+     *
+     * @retval  kErrorFailed          Other platform specific errors.
+     * @retval  kErrorNone            Successfully set region code.
+     * @retval  kErrorNotImplemented  The feature is not implemented.
+     *
+     */
+    Error GetRegion(uint16_t &aRegionCode) const;
+
 private:
     static constexpr uint16_t kMaxCcaSampleCount = OPENTHREAD_CONFIG_CCA_FAILURE_RATE_AVERAGING_WINDOW;
 
diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp
index 043f88c..e236fcc 100644
--- a/src/core/meshcop/dataset_manager.cpp
+++ b/src/core/meshcop/dataset_manager.cpp
@@ -312,15 +312,18 @@
     OT_UNUSED_VARIABLE(aMessageInfo);
 
     Error   error;
-    uint8_t state;
+    uint8_t state = StateTlv::kPending;
 
     SuccessOrExit(error = aError);
     VerifyOrExit(Tlv::Find<StateTlv>(*aMessage, state) == kErrorNone && state != StateTlv::kPending,
                  error = kErrorParse);
+    if (state == StateTlv::kReject)
+    {
+        error = kErrorRejected;
+    }
 
 exit:
-    LogInfo("MGMT_SET finished: %s",
-            error == kErrorNone ? StateTlv::StateToString(static_cast<StateTlv::State>(state)) : ErrorToString(error));
+    LogInfo("MGMT_SET finished: %s", error == kErrorNone ? "Accepted" : ErrorToString(error));
 
     mMgmtPending = false;
 
diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp
index a8d36a1..892e579 100644
--- a/src/core/radio/radio.hpp
+++ b/src/core/radio/radio.hpp
@@ -733,6 +733,36 @@
                 ((kChannelMin == aCslChannel) || ((kChannelMin < aCslChannel) && (aCslChannel <= kChannelMax))));
     }
 
+    /**
+     * Sets the region code.
+     *
+     * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+     *
+     * @param[in]  aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+     *                          and the `aRegionCode & 0xff` is the second ascii char.
+     *
+     * @retval  kErrorFailed          Other platform specific errors.
+     * @retval  kErrorNone            Successfully set region code.
+     * @retval  kErrorNotImplemented  The feature is not implemented.
+     *
+     */
+    Error SetRegion(uint16_t aRegionCode) { return otPlatRadioSetRegion(GetInstancePtr(), aRegionCode); }
+
+    /**
+     * Get the region code.
+     *
+     * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
+     *
+     * @param[out] aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
+     *                          and the `aRegionCode & 0xff` is the second ascii char.
+     *
+     * @retval  kErrorFailed          Other platform specific errors.
+     * @retval  kErrorNone            Successfully set region code.
+     * @retval  kErrorNotImplemented  The feature is not implemented.
+     *
+     */
+    Error GetRegion(uint16_t &aRegionCode) const { return otPlatRadioGetRegion(GetInstancePtr(), &aRegionCode); }
+
 private:
     otInstance *GetInstancePtr(void) const { return reinterpret_cast<otInstance *>(&InstanceLocator::GetInstance()); }
 
diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp
index fa67446..fb5bcda 100644
--- a/src/core/thread/mle.cpp
+++ b/src/core/thread/mle.cpp
@@ -1251,6 +1251,18 @@
     }
 #endif
 
+    if (aEvents.Contains(kEventSupportedChannelMaskChanged))
+    {
+        Mac::ChannelMask channelMask = Get<Mac::Mac>().GetSupportedChannelMask();
+
+        if (!channelMask.ContainsChannel(Get<Mac::Mac>().GetPanChannel()) && (mRole != kRoleDisabled))
+        {
+            LogWarn("Channel %u is not in the supported channel mask %s, detach the network gracefully!",
+                    Get<Mac::Mac>().GetPanChannel(), channelMask.ToString().AsCString());
+            IgnoreError(DetachGracefully(nullptr, nullptr));
+        }
+    }
+
 exit:
     return;
 }
diff --git a/tests/scripts/expect/posix-channel-mask.exp b/tests/scripts/expect/posix-channel-mask.exp
index 6e387d8..d754fea 100644
--- a/tests/scripts/expect/posix-channel-mask.exp
+++ b/tests/scripts/expect/posix-channel-mask.exp
@@ -61,4 +61,38 @@
 expect "0x1fff800"
 expect_line "Done"
 
+send "region US\n"
+expect_line "Done"
+
+send "channel supported\n"
+expect "0x7fff800"
+expect_line "Done"
+
+send "dataset init new\n"
+expect_line "Done"
+send "dataset channel 26\n"
+expect_line "Done"
+send "dataset commit active\n"
+expect_line "Done"
+
+attach "leader"
+
+send "channel\n"
+expect "26"
+expect_line "Done"
+
+send "region WW\n"
+expect_line "Done"
+
+wait_for "state" "disabled"
+expect_line "Done"
+
+send "channel supported\n"
+expect "0x3fff800"
+expect_line "Done"
+
+send "channel\n"
+expect "26"
+expect_line "Done"
+
 dispose_node 1