From 102ecfe92241932eb7f5a004334d8031174d936a Mon Sep 17 00:00:00 2001
From: remymahler <remy.mahler@digitalstrom.com>
Date: Thu, 11 Feb 2016 10:37:28 +0100
Subject: [PATCH 1/3] Update zone of device in datamodel

ref #12410

Add function to update zone of device. Also check for valid entry and
fix it, if it is invalid.
---
 src/datamodel.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 src/datamodel.h |  4 +++-
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/datamodel.c b/src/datamodel.c
index 1cfdeaa..b1a6bf6 100644
--- a/src/datamodel.c
+++ b/src/datamodel.c
@@ -6193,6 +6193,53 @@ uint8_t Datamodel_updateVdcName(const char *vdc_dsuid, const char *name)
     return ERROR_OK;
 }
 
+uint8_t Datamodel_updateDeviceZone(uint16_t* zoneId, uint16_t deviceId, const char* vdcdsuid_str)
+{
+    uint8_t localZoneId = 0;
+
+    // get default vdc zone id, if not defined
+    if (*zoneId == 0) {
+        *zoneId = Datamodel_getVdcDefaultZoneID(vdcdsuid_str);
+    }
+    if (*zoneId != 0) {
+        Datamodel *me = &l_datamodel;
+        localZoneId  = Datamodel_get_or_create_localZone_by_zoneId(me, *zoneId);
+    } else {
+        // Assign local zone id
+        dsuid_t vdcdsuid;
+        dsuid_from_string(vdcdsuid_str, &vdcdsuid);
+        Datamodel *me = &l_datamodel;
+        DatamodelZoneInfo* zoneInfo;
+        zoneInfo = Datamodel_CreateGetZoneInfoByDsuid(me, &vdcdsuid);
+        if (zoneInfo) {
+            localZoneId = zoneInfo->super.localZoneId;
+            Datamodel_AddDeviceToZone(zoneInfo);
+        } else {
+          vdsm_report(LOG_ERR, "Datamodel updateDeviceZone zone Info not found.\n");
+          return ERROR_ZONE_NOT_FOUND;
+        }
+    }
+
+    LOCK_ACCESS
+    Datamodel *me = &l_datamodel;
+    if (!me->databaseOpen) {
+        vdsm_report(LOG_ERR, "Datamodel updateDeviceZone Database closed!\n");
+        UNLOCK_ACCESS
+        return ERROR_OUT_OF_RESOURCES;
+    }
+
+    sqlite3_stmt *statement;
+    SQL_ASSERT(sqlite3_prepare_v2(me->pDb,
+        "UPDATE devices SET localZoneId=? WHERE deviceId=?;", -1, &statement, 0) == SQLITE_OK);
+    SQL_ASSERT(sqlite3_bind_int(statement, 1, localZoneId) == SQLITE_OK);
+    SQL_ASSERT(sqlite3_bind_int(statement, 2, deviceId) == SQLITE_OK);
+    SQL_ASSERT(sqlite3_step(statement) == SQLITE_DONE);
+    sqlite3_finalize(statement);
+    UNLOCK_ACCESS
+
+    return ERROR_OK;
+}
+
 /*............................................................................*/
 // LOCK_ACCESS: do not use it here. function is internally used.
 // Locking in under responsibility of calling function
diff --git a/src/datamodel.h b/src/datamodel.h
index c07f899..613e48e 100644
--- a/src/datamodel.h
+++ b/src/datamodel.h
@@ -1204,9 +1204,11 @@ void Datamodel_SetDeviceGroupMembershipAddGroup(uint16_t deviceId, uint8_t group
 void Datamodel_ClearDeviceGroupMembership(uint16_t deviceId);
 void Datamodel_DeriveGroupMembership(uint16_t deviceId);
 
-
 void Datamodel_updateDeviceVdc(uint16_t deviceId, char *vdcdsuid, uint16_t fid);
 
+
+uint8_t Datamodel_updateDeviceZone( /*I/O parameter */ uint16_t* zoneId, uint16_t deviceId, const char* vdcdsuid_str);
+
 bool Datamodel_DsmPropertiesRoomDimmingDisabled();
 uint8_t Datamodel_GetStopTimeoutZoneGroup(uint8_t localZoneId, uint8_t groupId);
 dsuid_t Datamodel_GetDsmid();
-- 
GitLab


From ff92506730aa9c4cf0e78440ececd1834b6738c0 Mon Sep 17 00:00:00 2001
From: remymahler <remy.mahler@digitalstrom.com>
Date: Thu, 11 Feb 2016 10:38:34 +0100
Subject: [PATCH 2/3] identation

ref #12410
---
 src/selectB.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/selectB.c b/src/selectB.c
index 13d0651..2503d11 100644
--- a/src/selectB.c
+++ b/src/selectB.c
@@ -960,7 +960,7 @@ static QState SelectB_register_get_params(SelectB *me, QEvent const *e)
 
         /* set zone on device */
         if (!device_api_set_zone(me->dsuid, resEvt->zoneId)) {
-          vdsm_report(LOG_ERR, "selectB could not set zone to device: %d.\n", me->deviceId);
+            vdsm_report(LOG_ERR, "selectB could not set zone to device: %d.\n", me->deviceId);
         }
 
         if (Fid_HasBinaryInputs(me->fid)) {
-- 
GitLab


From cc7cce10efc7c867e1dd5fa17ddc4f19c1bbd752 Mon Sep 17 00:00:00 2001
From: remymahler <remy.mahler@digitalstrom.com>
Date: Thu, 11 Feb 2016 11:53:41 +0100
Subject: [PATCH 3/3] modify state machine selectB.

ref #12410

From SelectB_register_lookup_device transit to SelectB_register_get_zone
even if device is registered.
Read back zoneId of a registered device.
Check for validity and send a valid zoneId,
if an invalid one was detected.
---
 src/selectB.c | 35 ++++++++++++++++++++++-------------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/src/selectB.c b/src/selectB.c
index 2503d11..9332d62 100644
--- a/src/selectB.c
+++ b/src/selectB.c
@@ -833,11 +833,6 @@ static QState SelectB_register_lookup_device(SelectB *me, QEvent const *e)
         me->vid = resEvt->device.vid;
         me->localZoneId = resEvt->device.localZoneId;
         me->deviceIsKnown = TRUE;
-        
-        DatamodelZoneInfo * zoneInfo = Datamodel_GetZoneInfoByLocalId(resEvt->device.localZoneId);
-        if (!device_api_set_zone(me->dsuid, zoneInfo->super.zoneId)) {
-            vdsm_report(LOG_ERR, "Could not write zoneId for device %s\n", me->dsuid);
-        }
 
         device_api_get_parameter(me->dsuid, 1, FID);
         QTimeEvt_postIn(&me->timeEvt, (QActive *)me, SELECT_B_WAIT_FOR_DSID_TICKS);
@@ -849,12 +844,7 @@ static QState SelectB_register_lookup_device(SelectB *me, QEvent const *e)
             QTimeEvt_disarm(&me->timeEvt);
             me->fid = longUpEvt->data;
             Datamodel_updateDeviceVdc(me->deviceId, me->vdc_dsuid, me->fid);
-
-            if (Fid_HasBinaryInputs(me->fid)) {
-                return Q_TRAN(&SelectB_register_get_sensors);
-            } else {
-                return Q_TRAN(&SelectB_register_get_LTMode_param);
-            }
+            return Q_TRAN(SelectB_register_get_zone);
         }
         break;
     }
@@ -900,9 +890,28 @@ static QState SelectB_register_get_zone(SelectB *me, QEvent const *e)
     }
     case SELECT_B_FILTERED_LONG_UPSTREAM_SIG: {
         LongUpstreamEvt const * longUpEvt = (LongUpstreamEvt const *)e;
-        if (longUpEvt->source == me->deviceId) {
-            me->zoneId = longUpEvt->data;
+        me->zoneId = longUpEvt->data;
+        if (me->deviceIsKnown == FALSE) {
             return Q_TRAN(&SelectB_register_get_params);
+        } else {
+            uint16_t zoneId = me->zoneId;
+            /* update device zone. 
+             * zoneId is checked if valid and set to a correct value, if it is invalid.
+             * If the zoneId is modified, it has to be set to the device.
+             */
+            Datamodel_updateDeviceZone(&zoneId, me->deviceId, me->vdc_dsuid);
+            if (zoneId != me->zoneId) {
+                me->zoneId = zoneId;
+                if (!device_api_set_zone(me->dsuid, zoneId)) {
+                    vdsm_report(LOG_ERR, "Could not write zoneId for device %s\n", me->dsuid);
+                }
+            }
+
+            if (Fid_HasBinaryInputs(me->fid)) {
+                return Q_TRAN(&SelectB_register_get_sensors);
+            } else {
+                return Q_TRAN(&SelectB_register_get_LTMode_param);
+            }
         }
         break;
     }
-- 
GitLab