From 7db9b597defceeaffad0dc06d9b642b32a05a4a7 Mon Sep 17 00:00:00 2001
From: Erik von Reis <evonreis@caltech.edu>
Date: Thu, 5 May 2022 12:06:12 -0700
Subject: [PATCH] awgtpman: client interface will now detect and use older RPC
 interfaces

Version 4.0.1 and earlier had 4 testpoint interfaces instead of two.
This code autodetects which interfaces are used by awg
and switches to the appropriate interface
---
 src/gds/awgtpman/testpoint.c              | 147 +++++++++++++++++++++-
 src/gds/awgtpman/testpoint.h              |  14 +++
 src/gds/awgtpman/testpoint_interface_v3.h |  60 +++++++++
 3 files changed, 219 insertions(+), 2 deletions(-)
 create mode 100644 src/gds/awgtpman/testpoint_interface_v3.h

diff --git a/src/gds/awgtpman/testpoint.c b/src/gds/awgtpman/testpoint.c
index a0ed8977d..281b7b444 100644
--- a/src/gds/awgtpman/testpoint.c
+++ b/src/gds/awgtpman/testpoint.c
@@ -10,6 +10,7 @@
 #include "dtt/gdserr.h"
 #include "dtt/gdserrmsg.h"
 #include "tconv.h"
+#include "testpoint_interface_v3.h"
 
 #if defined (_CONFIG_DYNAMIC)
 #include "confinfo.h"
@@ -43,6 +44,7 @@ static int			tp_init = 0;
 static tpNode_t		tpNode[TP_MAX_NODE];
 static int			tpNum = 0;
 
+
 /*----------------------------------------------------------------------*/
 /*                                                         		*/
 /* Internal Procedure Name: tpSetHostAddress				*/
@@ -597,8 +599,11 @@ int tpQuery (int node, int tpinterface, testpoint_t tp[], int tplen,
         return -2;
     }
 
+    int max_interface = (testAwgTpInterfaceVersion(node) > 3)
+        ? TP_MAX_INTERFACE : TP_MAX_INTERFACE_V3;
+
     /* check interface */
-    if ((tpinterface < 0) || (tpinterface >= TP_MAX_INTERFACE)) {
+    if ((tpinterface < 0) || (tpinterface >= max_interface)) {
         return -2;
     }
 
@@ -678,7 +683,77 @@ static char* cmdreply (const char* m)
 /* Procedure Returns: void						*/
 /*                                                         		*/
 /*----------------------------------------------------------------------*/
-static void queryCmd (char* buf, int node)
+static void queryCmd_v3 (char* buf, int node)
+{
+    int		i;
+    char*		p;
+    testpoint_t	tp[TP_MAX_INDEX]; /* test points */
+    int		num;	/* number of test points */
+
+    sprintf (buf, "Test points for node %i\n", node);
+    /* query lsc exc */
+    num = tpQuery (node, TP_LSC_EX_INTERFACE, tp,
+                   TP_MAX_INDEX, 0, 0);
+    p = strend (buf);
+    sprintf (p, "LSC EX:");
+    p = strend (p);
+    if (num < 0) {
+        sprintf (p, " invalid\n");
+        return;
+    }
+    for (i = 0; i < num; i++) {
+        sprintf (p, " %i", tp[i]);
+        p = strend (p);
+    }
+    sprintf (p++, "\n");
+    /* query lsc tp */
+    num = tpQuery (node, TP_LSC_TP_INTERFACE, tp,
+                   TP_MAX_INDEX, 0, 0);
+    p = strend (buf);
+    sprintf (p, "LSC TP:");
+    p = strend (p);
+    if (num < 0) {
+        sprintf (p, " invalid\n");
+        return;
+    }
+    for (i = 0; i < num; i++) {
+        sprintf (p, " %i", tp[i]);
+        p = strend (p);
+    }
+    sprintf (p++, "\n");
+    /* query asc exc */
+    num = tpQuery (node, TP_ASC_EX_INTERFACE, tp,
+                   TP_MAX_INDEX, 0, 0);
+    p = strend (buf);
+    sprintf (p, "ASC EX:");
+    p = strend (p);
+    if (num < 0) {
+        sprintf (p, " invalid\n");
+        return;
+    }
+    for (i = 0; i < num; i++) {
+        sprintf (p, " %i", tp[i]);
+        p = strend (p);
+    }
+    sprintf (p++, "\n");
+    /* query asc tp */
+    num = tpQuery (node, TP_ASC_TP_INTERFACE, tp,
+                   TP_MAX_INDEX, 0, 0);
+    p = strend (buf);
+    sprintf (p, "ASC TP:");
+    p = strend (p);
+    if (num < 0) {
+        sprintf (p, " invalid\n");
+        return;
+    }
+    for (i = 0; i < num; i++) {
+        sprintf (p, " %i", tp[i]);
+        p = strend (p);
+    }
+    sprintf (p++, "\n");
+}
+
+static void queryCmd_v4 (char* buf, int node)
 {
     int		i;
     char*		p;
@@ -718,6 +793,23 @@ static void queryCmd (char* buf, int node)
     sprintf (p++, "\n");
 }
 
+static void queryCmd (char* buf, int node)
+{
+    int interface_version = testAwgTpInterfaceVersion(node);
+    switch (interface_version)
+    {
+    case 3:
+        queryCmd_v3(buf, node);
+        break;
+    case 4:
+        queryCmd_v4(buf, node);
+        break;
+    default:
+        printf("unrecognized awgtp interface version %d\n", interface_version);
+        break;
+    }
+}
+
 
 /*----------------------------------------------------------------------*/
 /*                                                         		*/
@@ -963,3 +1055,54 @@ int keepAlive (int node)
     clnt_destroy (clnt);
     return ret;
 }
+
+
+/// Find RPC interface version used by awgtpman
+/// version 4 was introduced about RCG version 4.1.0
+/// all previous interface versions, including for RCG 4.0.1,
+/// are considered version 3.
+/// Version 4 has only two testpoint interfaces: one for excitations and one for
+/// other test points.
+/// Version 3 has 4 testpoint interfaces: the two interfaces of version 4 are
+/// divided between LSC and ASC test points.
+///
+/// \param node the node number to identify
+/// \return the version number, 0 on error
+int testAwgTpInterfaceVersion(int node)
+{
+    // memoize
+    static int node_version[ TP_MAX_NODE ];
+
+    if ( node_version[ node ] )
+    {
+        return node_version[ node ];
+    }
+
+    testpoint_t     tp[ 128 ];
+    resultQueryTP_r result;
+
+    int chk = testpoint_client( );
+
+    if (chk < 0) {
+        printf("testAwgTpInterfaceVersion: testpoint_client() failed with return code %d\n", chk);
+        return 0;
+    }
+
+    CLIENT * clnt = tpMakeHandle (node);
+    if(clnt == NULL)
+    {
+        return 0;
+    }
+
+    if ((querytp_1 (tpNode[node].id, node, TP_ASC_TP_INTERFACE, 128, 0,
+                    0, &result, clnt) == RPC_SUCCESS) && (result.status >= 0)) {
+        printf("found version 3 or older test point interface\n");
+        node_version[node] = 3;
+    }
+    else
+    {
+        printf("found version 4 or newer test point interface\n");
+        node_version[node] = 4;
+    }
+    return node_version[node];
+}
\ No newline at end of file
diff --git a/src/gds/awgtpman/testpoint.h b/src/gds/awgtpman/testpoint.h
index 4fc9ae9a2..cd7f00721 100644
--- a/src/gds/awgtpman/testpoint.h
+++ b/src/gds/awgtpman/testpoint.h
@@ -200,6 +200,20 @@ int tpcmdline( const char* cmd );
 /*----------------------------------------------------------------------*/
 int keepAlive( int node );
 
+
+/// Find RPC interface version used by awgtpman
+/// version 4 was introduced about RCG version 4.1.0
+/// all previous interface versions, including for RCG 4.0.1,
+/// are considered version 3.
+/// Version 4 has only two testpoint interfaces: one for excitations and one for
+/// other test points.
+/// Version 3 has 4 testpoint interfaces: the two interfaces of version 4 are
+/// divided between LSC and ASC test points.
+///
+/// \param node the node number to identify
+/// \return the version number, 0 on error
+int testAwgTpInterfaceVersion(int node);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gds/awgtpman/testpoint_interface_v3.h b/src/gds/awgtpman/testpoint_interface_v3.h
new file mode 100644
index 000000000..bcbe1e79c
--- /dev/null
+++ b/src/gds/awgtpman/testpoint_interface_v3.h
@@ -0,0 +1,60 @@
+//
+// Created by erik.vonreis on 5/4/22.
+//
+// defines needed for older version 3 RPC interface, stolen from
+// version 4.0.1
+//
+
+#ifndef DAQD_TRUNK_TESTPOINT_INTERFACE_V3_H
+#define DAQD_TRUNK_TESTPOINT_INTERFACE_V3_H
+
+/** Test point interface id of LSC excitation.
+
+@author DS, September 98
+    @see Testpoint Definition
+        ************************************************************************/
+#define TP_LSC_EX_INTERFACE	0
+
+/** Test point interface id of ASC excitation.
+
+    @author DS, September 98
+    @see Testpoint Definition
+************************************************************************/
+#define TP_ASC_EX_INTERFACE	1
+
+/** Test point interface id of LSC readout.
+
+    @author DS, September 98
+    @see Testpoint Definition
+************************************************************************/
+#define TP_LSC_TP_INTERFACE	2
+
+/** Test point interface id of ASC readout.
+
+    @author DS, September 98
+    @see Testpoint Definition
+************************************************************************/
+#define TP_ASC_TP_INTERFACE	3
+
+
+#define TP_MAX_INTERFACE_V3     4
+
+#define TP_ID_TO_INTERFACE_V3(A) ( \
+	((A) == 0 ? -1 :	    \
+	((A) < TP_ID_LSC_TP_OFS ? TP_LSC_EX_INTERFACE :	    \
+	((A) < TP_ID_ASC_EX_OFS ? TP_LSC_TP_INTERFACE :	    \
+	((A) < TP_ID_ASC_TP_OFS ? TP_ASC_EX_INTERFACE :	    \
+	((A) < TP_ID_DAC_OFS ? TP_ASC_TP_INTERFACE :	    \
+	((A) < TP_ID_DS340_OFS ? TP_DAC_INTERFACE :	    \
+        ((A) < TP_ID_END_OFS ? TP_DS340_INTERFACE :         \
+         -1))))))))
+
+/** Maximum number of entries in the test point index. This number must
+    be greater or equal than any of the individual test point indexes.
+
+@author DS, September 98
+    @see Testpoint Definition
+        ************************************************************************/
+#define TP_MAX_INDEX		64
+
+#endif // DAQD_TRUNK_TESTPOINT_INTERFACE_V3_H
-- 
GitLab