diff --git a/src/callouts.cc b/src/callouts.cc
index 12f6285fe23a16111e970dbda6d2437aa7f604b1..fc7d6c990be7d4808efd126f67a5eb78d48e5e11 100644
--- a/src/callouts.cc
+++ b/src/callouts.cc
@@ -6,26 +6,93 @@
 #include <hooks/hooks.h>
 #include <pgsql/pgsql_connection.h>
 
+#include <algorithm>
 #include <cstdlib>
 #include <string>
+#include <tuple>
 
 #include "globals.h"
 #include "logger.h"
 
+static std::tuple<int, std::string, std::string, std::string> parseOption82(
+    const isc::dhcp::Pkt4Ptr &query4_ptr) {
+  /* Get switch hostname and port name from DHCP option 82
+   * https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst4500/12-2/15-02SG/configuration/guide/config/dhcp.html#57094
+   */
+  auto option82{query4_ptr->getOption(82)};
+  if (!option82) {
+    LOG_FATAL(schmatrix_logger, SCHMATRIX_DHCP_OPTION_82_ERROR);
+    return std::make_tuple(1, nullptr, nullptr, nullptr);
+  }
+
+  auto circuit_id{option82->getOption(1)->getData()};
+  auto remote_id{option82->getOption(2)->getData()};
+
+  // Check suboption ID types
+  if (circuit_id[0] != 0 || remote_id[0] != 1) {
+    LOG_FATAL(schmatrix_logger, SCHMATRIX_DHCP_OPTION_82_ERROR);
+    return std::make_tuple(1, nullptr, nullptr, nullptr);
+  }
+
+  std::string port_id{std::to_string(circuit_id[4]) + "/" +
+                      std::to_string(circuit_id[5])};
+  std::string switch_name{remote_id.begin() + 2, remote_id.end()};
+  auto switch_id{g_switch_data.at(switch_name)};
+
+  return std::make_tuple(1, std::move(switch_name), std::move(port_id),
+                         std::move(switch_id));
+}
+
 extern "C" {
 // Check IP conflict
 int pkt4_receive(isc::hooks::CalloutHandle &handle) {
   isc::dhcp::Pkt4Ptr query4_ptr;
   handle.getArgument("query4", query4_ptr);
 
-  const std::string &mac_address{query4_ptr->getHWAddr()->toText(false)};
-  const char *values[]{mac_address.c_str()};
-  isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "ip_conflict", 1,
+  // Skip non MUEB devices check
+  auto hwaddr_ptr = query4_ptr->getHWAddr();
+  if (hwaddr_ptr->hwaddr_[0] != 0x54 || hwaddr_ptr->hwaddr_[1] != 0x10 ||
+      hwaddr_ptr->hwaddr_[2] != 0xEC) {
+    return 0;
+  }
+
+  const auto [result, switch_name, port_id, switch_id] =
+      parseOption82(query4_ptr);
+  const std::string &mac_address{hwaddr_ptr->toText(false)};
+  const char *values[2] = {port_id.c_str(), switch_id.c_str()};
+
+  // Get room id
+  isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "mueb_in_room", 2,
                                         values, nullptr, nullptr, 0));
-  /* Drop packet
-   * MUEB with IP conflict needs manual fix
+  // Handle incorrect room
+  if (r.getRows() < 0) {
+    LOG_ERROR(schmatrix_logger, SCHMATRIX_UNKNOWN_ROOM)
+        .arg(mac_address)
+        .arg(switch_name)
+        .arg(port_id);
+    return 1;
+  }
+
+  const auto room_id{PQgetvalue(r, 0, 0)};
+  values[0] = mac_address.c_str();
+  values[1] = room_id;
+
+  // Drop packet if multiple MUEBs(excluding current) is in the same room
+  isc::db::PgSqlResult r2(PQexecPrepared(*g_pg_sql_connection,
+                                         "mueb_count_in_room", 2, values,
+                                         nullptr, nullptr, 0));
+  if (r.getRows() > 0 && std::atoi(PQgetvalue(r, 0, 0)) > 0) {
+    LOG_WARN(schmatrix_logger, SCHMATRIX_MULTIPLE_MUEB).arg(room_id);
+    handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
+    return 0;
+  }
+
+  isc::db::PgSqlResult r3(PQexecPrepared(*g_pg_sql_connection, "ip_conflict", 1,
+                                         values, nullptr, nullptr, 0));
+  /* Drop packet when a MUEB has IP conflict
+   * Needs manual fix
    */
-  if (r.getRows() > 0 && atoi(PQgetvalue(r, 0, 0)) > 0) {
+  if (r.getRows() > 0 && std::atoi(PQgetvalue(r, 0, 0)) > 0) {
     handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_DROP);
   }
 
@@ -60,23 +127,11 @@ int lease4_select(isc::hooks::CalloutHandle &handle) {
   // Critical part begin, it's not safe to lease IP yet
   handle.setStatus(isc::hooks::CalloutHandle::NEXT_STEP_SKIP);
 
-  // Get switch hostname and port name from DHCP option 82
-  // https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst4500/12-2/15-02SG/configuration/guide/config/dhcp.html#57094
-  auto option82{query4_ptr->getOption(82)};
-  auto circuit_id{option82->getOption(1)->getData()};
-  auto remote_id{option82->getOption(2)->getData()};
-
-  // Check suboption ID types
-  if (circuit_id[0] != 0 || remote_id[0] != 1) {
-    LOG_FATAL(schmatrix_logger, SCHMATRIX_DHCP_OPTION_82_ERROR);
+  auto [result, switch_name, port_id, switch_id] = parseOption82(query4_ptr);
+  if (result != 0) {
     return 1;
   }
 
-  std::string port_id{std::to_string(circuit_id[4]) + "/" +
-                      std::to_string(circuit_id[5])};
-  std::string switch_name{remote_id.begin() + 2, remote_id.end()};
-  auto switch_id{g_switch_data.at(switch_name)};
-
   // Check for IP override
   const char *values[3] = {mac_address.c_str()};
   isc::db::PgSqlResult r(PQexecPrepared(*g_pg_sql_connection, "ip_override", 1,
diff --git a/src/framework_functions.cc b/src/framework_functions.cc
index 386c905fa2185efd188e3fb2f77bc5a4862d2a72..1f7d7e7e7e670723d3199ebd10962caf819dcf69 100644
--- a/src/framework_functions.cc
+++ b/src/framework_functions.cc
@@ -42,15 +42,26 @@ int load(isc::hooks::LibraryHandle& handle) {
   }
 
   // Store prepared statements
-  std::array<isc::db::PgSqlTaggedStatement, 6> statements{
+  std::array<isc::db::PgSqlTaggedStatement, 8> statements{
       {{1,
         {isc::db::OID_TEXT},
         "ip_conflict",
         "select ip_conflict::int from mueb where mac_address = $1::macaddr"},
+       {2,
+        {isc::db::OID_TEXT, isc::db::OID_TEXT},
+        "mueb_in_room",
+        "select room_id from port p join room r using(room_id) where p.port_id "
+        "= $1 and p.switch_id = $2::inet"},
+       {2,
+        {isc::db::OID_TEXT, isc::db::OID_TEXT},
+        "mueb_count_in_room",
+        "select count(*) from port p join mueb m using(port_id, switch_id) "
+        "where m.mac_address::macaddr != $1 and p.room_id = $2"},
        {1,
         {isc::db::OID_TEXT},
         "ip_override",
-        "select ip_override from mueb where mac_address = $1::macaddr and ip_override "
+        "select ip_override from mueb where mac_address = $1::macaddr and "
+        "ip_override "
         "is not null"},
        {2,
         {isc::db::OID_TEXT, isc::db::OID_TEXT},
@@ -65,8 +76,10 @@ int load(isc::hooks::LibraryHandle& handle) {
        {3,
         {isc::db::OID_TEXT, isc::db::OID_TEXT, isc::db::OID_TEXT},
         "insert_mueb",
-        "insert into mueb (mac_address) values ($1::macaddr) on conflict (mac_address) do update set "
-        "port_id = $2, switch_id = $3::inet where mueb.mac_address = $1::macaddr"},
+        "insert into mueb (mac_address) values ($1::macaddr) on conflict "
+        "(mac_address) do update set "
+        "port_id = $2, switch_id = $3::inet where mueb.mac_address = "
+        "$1::macaddr"},
        {1,
         {isc::db::OID_TEXT},
         "set_ip_conflict",
diff --git a/src/messages.cc b/src/messages.cc
index 79375a2dc640cd8677d91203bf99265483fb9441..15908e9e024d44f14dc49ffd2c77f588742f3568 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -1,4 +1,4 @@
-// File created from messages.mes on Sun Aug 08 2021 19:54
+// File created from messages.mes on Thu Sep 02 2021 20:36
 
 #include <cstddef>
 #include <log/message_types.h>
@@ -10,6 +10,7 @@ extern const isc::log::MessageID SCHMATRIX_DHCP_STATE = "SCHMATRIX_DHCP_STATE";
 extern const isc::log::MessageID SCHMATRIX_IP_CONFLICT = "SCHMATRIX_IP_CONFLICT";
 extern const isc::log::MessageID SCHMATRIX_IP_OVERRIDDEN = "SCHMATRIX_IP_OVERRIDDEN";
 extern const isc::log::MessageID SCHMATRIX_MISSING_PARAMETERS = "SCHMATRIX_MISSING_PARAMETERS";
+extern const isc::log::MessageID SCHMATRIX_MULTIPLE_MUEB = "SCHMATRIX_MULTIPLE_MUEB";
 extern const isc::log::MessageID SCHMATRIX_NOT_MUEB = "SCHMATRIX_NOT_MUEB";
 extern const isc::log::MessageID SCHMATRIX_OPEN_DATABASE = "SCHMATRIX_OPEN_DATABASE";
 extern const isc::log::MessageID SCHMATRIX_QUERIED_IP = "SCHMATRIX_QUERIED_IP";
@@ -24,6 +25,7 @@ const char* values[] = {
     "SCHMATRIX_IP_CONFLICT", "Could not lease IP: %1 to MUEB: %2 because of IP conflict",
     "SCHMATRIX_IP_OVERRIDDEN", "MUEB: %1 IP's overridden to: %2",
     "SCHMATRIX_MISSING_PARAMETERS", "Not all parameters are provided",
+    "SCHMATRIX_MULTIPLE_MUEB", "Multiple MUEBs in the same room %1",
     "SCHMATRIX_NOT_MUEB", "Device with MAC: %1 is not a MUEB",
     "SCHMATRIX_OPEN_DATABASE", "Opened database successfully",
     "SCHMATRIX_QUERIED_IP", "Queried IP is: %1",
diff --git a/src/messages.h b/src/messages.h
index 0f763981a49a0c0e4aaab30230944af97559e028..c7113e9344b7cb40be115e3e08aa6ac30eddb035 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -1,4 +1,4 @@
-// File created from messages.mes on Sun Aug 08 2021 19:54
+// File created from messages.mes on Thu Sep 02 2021 20:36
 
 #ifndef MESSAGES_H
 #define MESSAGES_H
@@ -11,6 +11,7 @@ extern const isc::log::MessageID SCHMATRIX_DHCP_STATE;
 extern const isc::log::MessageID SCHMATRIX_IP_CONFLICT;
 extern const isc::log::MessageID SCHMATRIX_IP_OVERRIDDEN;
 extern const isc::log::MessageID SCHMATRIX_MISSING_PARAMETERS;
+extern const isc::log::MessageID SCHMATRIX_MULTIPLE_MUEB;
 extern const isc::log::MessageID SCHMATRIX_NOT_MUEB;
 extern const isc::log::MessageID SCHMATRIX_OPEN_DATABASE;
 extern const isc::log::MessageID SCHMATRIX_QUERIED_IP;
diff --git a/src/messages.mes b/src/messages.mes
index 7ff3eb3ff8df69dcd09b687fbbf1bbea799cb920..d1e174f1af8cd49f602b4fd43e8f651a0f763bab 100644
--- a/src/messages.mes
+++ b/src/messages.mes
@@ -17,3 +17,5 @@
 % SCHMATRIX_IP_OVERRIDDEN MUEB: %1 IP's overridden to: %2
 
 % SCHMATRIX_DHCP_OPTION_82_ERROR Invalid DHCP option 82
+
+% SCHMATRIX_MULTIPLE_MUEB Multiple MUEBs in the same room %1