# HG changeset patch
# User jfp <jf.pieronne@laposte.net>
# Date 1737989825 -3600
#      Mon Jan 27 15:57:05 2025 +0100
# Node ID f95a3736a0ecd03b7d510c697a9e499df738e945
# Parent  56bdbeabb0c4c8500eaaae1c4063e1f40ec7e2a1
Clean code, use struct ptd_buf

diff --git a/python/local/ovms_module/ovms/ptd/_vmsptd.pyx b/python/local/ovms_module/ovms/ptd/_vmsptd.pyx
--- a/python/local/ovms_module/ovms/ptd/_vmsptd.pyx
+++ b/python/local/ovms_module/ovms/ptd/_vmsptd.pyx
@@ -66,6 +66,12 @@
         void* va_range_ps_start_va "va_range$ps_start_va"
         void* va_range_ps_end_va "va_range$ps_end_va"
 
+    ctypedef struct ptd_buf:
+            unsigned short status;
+            unsigned short len;
+            char buf[];
+
+
     ctypedef struct ptd_handler:
         unsigned short channel
         int nbpagelets
@@ -75,9 +81,9 @@
         int timer_status
         int read_start_read
         int maxbuf
-        char* read_buf
-        char* echo_buf
-        char* write_buf
+        ptd_buf* read_buf
+        ptd_buf* echo_buf
+        ptd_buf* write_buf
         VA_RANGE inadr
 
     ctypedef struct DevChar:
@@ -318,9 +324,9 @@
         buflen = sizeof(charbuff.devchar)
     handler.handler = <ptd_handler *>allocate_page_aligned_memory(allocsz, pgsize)
     ptrc = <char *>handler.handler + pgsize
-    handler.handler.read_buf = ptrc
-    handler.handler.write_buf = ptrc + maxbuf
-    handler.handler.echo_buf = ptrc + 2 * maxbuf
+    handler.handler.read_buf = <ptd_buf *>ptrc
+    handler.handler.write_buf = <ptd_buf *>(ptrc + maxbuf)
+    handler.handler.echo_buf = <ptd_buf *>(ptrc + 2 * maxbuf)
     handler.handler.nbpagelets = nbpagelets
     handler.handler.maxbuf = maxbuf
     handler.handler.inadr.va_range_ps_start_va = ptrc
@@ -351,7 +357,7 @@
     checkStatus(s)
     s = lib_free_ef(<unsigned int *>&(handler.handler.efn))
     checkStatus(s)
-    free_page_aligned_memory(handler.handler.read_buf)
+    free_page_aligned_memory(<char *>handler.handler.read_buf)
     return s
 
 def readw(PtdHandler handler):
@@ -363,19 +369,19 @@
         while handler.handler.read_status != 2:
             s = sys_hiber()
         s = SS__NORMAL
-    handler.handler.read_status = 0 
-    (<unsigned short *>(handler.handler.inadr.va_range_ps_start_va))[0] = 0
+    handler.handler.read_status = 0
+    (<ptd_buf *>(handler.handler.read_buf)).status = 0
     with nogil:
         s = ptd_readw(EFN_C_ENF, handler.handler.channel, 0, 0,
-                        handler.handler.read_buf,
+                        <char *>handler.handler.read_buf,
                         handler.handler.maxbuf - 4)
     checkStatus(s)
-    s = (<unsigned short *>(handler.handler.read_buf))[0]
+    s = (<ptd_buf *>(handler.handler.read_buf)).status
     checkStatus(s)
     handler.handler.read_status = 0 
-    cdef char* buf = <char *>(handler.handler.read_buf) + 4
-    cdef unsigned short* retlenPtr = <unsigned short *>(buf - 2)
-    return s, buf[:retlenPtr[0]]
+    cdef char* buf = <char *>handler.handler.read_buf.buf
+    cdef unsigned short retlen = (<ptd_buf *>(handler.handler.read_buf)).len
+    return s, buf[:retlen]
 
 def read_timeout(PtdHandler handler, short timeout):
     "status, res = read_timeout(handler, timeout)\n\
@@ -403,10 +409,11 @@
     # if a read request was not previously started, start one
     if handler.handler.read_status == 0:
         handler.handler.read_status = 1
+        (<ptd_buf *>(handler.handler.read_buf)).status = 0
         with nogil:
             s = ptd_read(EFN_C_ENF, handler.handler.channel, read_ast,
                          <int>handler.handler,
-                         handler.handler.read_buf,
+                         <char *>handler.handler.read_buf,
                          handler.handler.maxbuf - 4)
         checkStatus(s)
     while ((handler.handler.read_status == 1) and 
@@ -416,13 +423,13 @@
         handler.handler.timer_status = 0
         handler.handler.read_status = 0
         return SS__TIMEOUT, None
-    s = (<unsigned short *>(handler.handler.read_buf))[0]
+    s = (<ptd_buf *>(handler.handler.read_buf)).status
     checkStatus(s)
-    cdef char* buf = <char *>(handler.handler.read_buf) + 4
-    cdef unsigned short* retlenPtr = <unsigned short *>(buf - 2)
+    cdef char* buf = <char *>(handler.handler.read_buf.buf)
+    cdef unsigned short retlen = (<ptd_buf *>(handler.handler.read_buf)).len
     handler.handler.timer_status = 0
     handler.handler.read_status = 0
-    return s, buf[:retlenPtr[0]]
+    return s, buf[:retlen]
 
 def write(PtdHandler handler, wrtstr, echo=False):
     "status, res = write(handler, wrstr, echo=False)"
@@ -434,28 +441,23 @@
     with_echo = echo
     if wlen > handler.handler.maxbuf - 4:
         raise ValueError(f'Invalid wrtstr length, maximum is {handler.handler.maxbuf - 4}')
-    cdef char* wrtbuf = <char *>(handler.handler.write_buf)
-    cdef char* readbuf = \
-       <char *>(handler.handler.echo_buf)
-    cdef char* buf = <char *>(readbuf) + 4
-    cdef unsigned short* retlenPtr = <unsigned short *>(buf - 2)
+    cdef ptd_buf* wrtbuf = <ptd_buf *>(handler.handler.write_buf)
+    cdef ptd_buf* echobuf = <ptd_buf *>(handler.handler.echo_buf)
     memset(wrtbuf, 4, 0)
-    strncpy(wrtbuf + 4, wrtstrPtr, wlen) 
-    memset(readbuf, 4, 0)
-    if handler.handler.read_status != 0:
-        cancel(handler)
+    strncpy(<char *>wrtbuf + 4, wrtstrPtr, wlen) 
+    memset(echobuf, 4, 0)
     with nogil:
         s = ptd_write(handler.handler.channel, 0, 0,
-                      handler.handler.write_buf, wlen, readbuf if with_echo else NULL,
+                      <char *>wrtbuf, wlen, <char *>echobuf if with_echo else NULL,
                       handler.handler.maxbuf - 4 if with_echo else 0)
     checkStatus(s)
-    s = (<unsigned short *>(wrtbuf))[0]
+    s = wrtbuf.status
     checkStatus(s)
     if with_echo:
-        s = (<unsigned short *>(readbuf))[0]
+        s = echobuf.status
         checkStatus(s)
-        return s, buf[:retlenPtr[0]]
-    return s, buf[:0]
+        return s, echobuf.buf[:echobuf.len]
+    return s, echobuf.buf[:0]
 
 def set_event_notification(PtdHandler handler):
     "status = set_event_notification(handler)"
diff --git a/python/local/ovms_module/ovms/ptd/ovptd.h b/python/local/ovms_module/ovms/ptd/ovptd.h
--- a/python/local/ovms_module/ovms/ptd/ovptd.h
+++ b/python/local/ovms_module/ovms/ptd/ovptd.h
@@ -62,6 +62,16 @@
   } terminatorSetShortForm;
 #pragma __member_alignment __restore
 
+#pragma __member_alignment __save
+#pragma __nomember_alignment
+typedef struct {
+    unsigned short status;
+    unsigned short len;
+    char buf[];
+}  ptd_buf;
+typedef volatile ptd_buf ptd_buf_volatile;
+#pragma __member_alignment __restore
+
 typedef volatile struct {
     unsigned short channel;
     int nbpagelets;
@@ -73,9 +83,9 @@
                             1: the pseudoterminal is starting an 
                                application's read request.*/
     int maxbuf;
-    char* read_buf;
-    char* echo_buf;
-    char* write_buf;
+    volatile ptd_buf* read_buf;
+    volatile ptd_buf* echo_buf;
+    volatile ptd_buf* write_buf;
     VA_RANGE inadr;
 } ptd_handler;