svghmi/svghmi.c
branchsvghmi
changeset 3270 38f7122ccbf9
parent 2863 e120d6985a2f
child 3271 561dbd1e3e04
--- a/svghmi/svghmi.c	Mon Jul 05 10:51:02 2021 +0200
+++ b/svghmi/svghmi.c	Wed Jul 07 16:31:13 2021 +0200
@@ -9,6 +9,8 @@
 #define HMI_BUFFER_SIZE %(buffer_size)d
 #define HMI_ITEM_COUNT %(item_count)d
 #define HMI_HASH_SIZE 8
+#define MAX_CONNECTIONS %(max_connections)d
+
 static uint8_t hmi_hash[HMI_HASH_SIZE] = {%(hmi_hash_ints)s};
 
 /* PLC reads from that buffer */
@@ -45,11 +47,11 @@
 
     /* publish/write/send */
     long wlock;
-    buf_state_t wstate;
+    buf_state_t wstate[MAX_CONNECTIONS];
 
     /* zero means not subscribed */
-    uint16_t refresh_period_ms;
-    uint16_t age_ms;
+    uint16_t refresh_period_ms[MAX_CONNECTIONS];
+    uint16_t age_ms[MAX_CONNECTIONS];
 
     /* retrieve/read/recv */
     long rlock;
@@ -81,15 +83,16 @@
 
 static int write_iterator(uint32_t index, hmi_tree_item_t *dsc)
 {
-    if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0)
-    {
-        if(dsc->wstate == buf_set){
+    uint32_t session_index = 0;
+    if(AtomicCompareExchange(&dsc->wlock, 0, 1) == 0) while(session_index < MAX_CONNECTIONS)
+    {
+        if(dsc->wstate[session_index] == buf_set){
             /* if being subscribed */
-            if(dsc->refresh_period_ms){
-                if(dsc->age_ms + ticktime_ms < dsc->refresh_period_ms){
-                    dsc->age_ms += ticktime_ms;
+            if(dsc->refresh_period_ms[session_index]){
+                if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){
+                    dsc->age_ms[session_index] += ticktime_ms;
                 }else{
-                    dsc->wstate = buf_tosend;
+                    dsc->wstate[session_index] = buf_tosend;
                     global_write_dirty = 1;
                 }
             }
@@ -105,34 +108,36 @@
         if(__Is_a_string(dsc)){
             sz = ((STRING*)visible_value_p)->len + 1;
         }
-        if(dsc->wstate == buf_new /* just subscribed 
+        if(dsc->wstate[session_index] == buf_new /* just subscribed 
            or already subscribed having value change */
-           || (dsc->refresh_period_ms > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){
+           || (dsc->refresh_period_ms[session_index] > 0 && memcmp(dest_p, visible_value_p, sz) != 0)){
             /* copy and flag as set */
             memcpy(dest_p, visible_value_p, sz);
             /* if not already marked/signaled, do it */
-            if(dsc->wstate != buf_set && dsc->wstate != buf_tosend) {
-                if(dsc->wstate == buf_new || ticktime_ms > dsc->refresh_period_ms){
-                    dsc->wstate = buf_tosend;
+            if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) {
+                if(dsc->wstate[session_index] == buf_new || ticktime_ms > dsc->refresh_period_ms[session_index]){
+                    dsc->wstate[session_index] = buf_tosend;
                     global_write_dirty = 1;
                 } else {
-                    dsc->wstate = buf_set;
-                }
-                dsc->age_ms = 0;
+                    dsc->wstate[session_index] = buf_set;
+                }
+                dsc->age_ms[session_index] = 0;
             }
         }
 
         AtomicCompareExchange(&dsc->wlock, 1, 0);
+        session_index++;
     }
     // else ... : PLC can't wait, variable will be updated next turn
     return 0;
 }
 
+static uint32_t send_session_index;
 static int send_iterator(uint32_t index, hmi_tree_item_t *dsc)
 {
     while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
 
-    if(dsc->wstate == buf_tosend)
+    if(dsc->wstate[send_session_index] == buf_tosend)
     {
         uint32_t sz = __get_type_enum_size(dsc->type);
         if(sbufidx + sizeof(uint32_t) + sz <=  sizeof(sbuf))
@@ -145,7 +150,7 @@
             /* TODO : force into little endian */
             memcpy(dst_p, &index, sizeof(uint32_t));
             memcpy(dst_p + sizeof(uint32_t), src_p, sz);
-            dsc->wstate = buf_free;
+            dsc->wstate[send_session_index] = buf_free;
             sbufidx += sizeof(uint32_t) /* index */ + sz;
         }
         else
@@ -179,24 +184,25 @@
     return 0;
 }
 
-void update_refresh_period(hmi_tree_item_t *dsc, uint16_t refresh_period_ms)
+void update_refresh_period(hmi_tree_item_t *dsc, uint32_t session_index, uint16_t refresh_period_ms)
 {
     while(AtomicCompareExchange(&dsc->wlock, 0, 1)) sched_yield();
     if(refresh_period_ms) {
-        if(!dsc->refresh_period_ms)
-        {
-            dsc->wstate = buf_new;
+        if(!dsc->refresh_period_ms[session_index])
+        {
+            dsc->wstate[session_index] = buf_new;
         }
     } else {
-        dsc->wstate = buf_free;
-    }
-    dsc->refresh_period_ms = refresh_period_ms;
+        dsc->wstate[session_index] = buf_free;
+    }
+    dsc->refresh_period_ms[session_index] = refresh_period_ms;
     AtomicCompareExchange(&dsc->wlock, 1, 0);
 }
 
+static uint32_t reset_session_index;
 static int reset_iterator(uint32_t index, hmi_tree_item_t *dsc)
 {
-    update_refresh_period(dsc, 0);
+    update_refresh_period(dsc, reset_session_index, 0);
     return 0;
 }
 
@@ -236,13 +242,14 @@
 }
 
 /* PYTHON CALLS */
-int svghmi_send_collect(uint32_t *size, char **ptr){
+int svghmi_send_collect(uint32_t session_index, uint32_t *size, char **ptr){
 
     SVGHMI_SuspendFromPythonThread();
 
     if(continue_collect) {
         int res;
         sbufidx = HMI_HASH_SIZE;
+        send_session_index = session_index;
         if((res = traverse_hmi_tree(send_iterator)) == 0)
         {
             if(sbufidx > HMI_HASH_SIZE){
@@ -270,7 +277,7 @@
 
 // Returns :
 //   0 is OK, <0 is error, 1 is heartbeat
-int svghmi_recv_dispatch(uint32_t size, const uint8_t *ptr){
+int svghmi_recv_dispatch(uint32_t session_index, uint32_t size, const uint8_t *ptr){
     const uint8_t* cursor = ptr + HMI_HASH_SIZE;
     const uint8_t* end = ptr + size;
 
@@ -336,6 +343,7 @@
             case reset:
             {
                 progress = 0;
+                reset_session_index = session_index;
                 traverse_hmi_tree(reset_iterator);
             }
             break;
@@ -348,7 +356,7 @@
                 if(index < HMI_ITEM_COUNT)
                 {
                     hmi_tree_item_t *dsc = &hmi_tree_item[index];
-                    update_refresh_period(dsc, refresh_period_ms);
+                    update_refresh_period(dsc, session_index, refresh_period_ms);
                 }
                 else
                 {