ngscopeclient v0.2.1
Loading...
Searching...
No Matches
SCPITransport.h
Go to the documentation of this file.
1/***********************************************************************************************************************
2* *
3* libscopehal *
4* *
5* Copyright (c) 2012-2026 Andrew D. Zonenberg and contributors *
6* All rights reserved. *
7* *
8* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
9* following conditions are met: *
10* *
11* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
12* following disclaimer. *
13* *
14* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
15* following disclaimer in the documentation and/or other materials provided with the distribution. *
16* *
17* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
18* derived from this software without specific prior written permission. *
19* *
20* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
21* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
23* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
26* POSSIBILITY OF SUCH DAMAGE. *
27* *
28***********************************************************************************************************************/
29
37#ifndef SCPITransport_h
38#define SCPITransport_h
39
40#include <chrono>
41
43{
44 std::string path;
45 std::string description;
46};
47
53{
54public:
56 virtual ~SCPITransport();
57
58 virtual std::string GetConnectionString() =0;
59 virtual std::string GetName() =0;
60
61 virtual bool SetTimeouts(unsigned int txUs, unsigned int rxUs);
62
63 /*
64 Queued command API
65
66 Note that ngscopeclient flushes the command queue in ScopeThread.
67 Headless applications will need to do this manually after performing a write-only application, otherwise
68 the command will remain queued indefinitely.
69
70 TODO: look into a background thread or something that's automatically launched by the transport to do this
71 after some kind of fixed timeout?
72 */
73 void SendCommandQueued(const std::string& cmd);
74 std::string SendCommandQueuedWithReply(const std::string& cmd, bool endOnSemicolon = true);
75 void SendCommandImmediate(const std::string& cmd);
76 std::string SendCommandImmediateWithReply(const std::string& cmd, bool endOnSemicolon = true);
77 void* SendCommandImmediateWithRawBlockReply(const std::string& cmd, size_t& len);
78 bool FlushCommandQueue();
79
80 //Manual mutex locking for ReadRawData() etc
81 std::recursive_mutex& GetMutex()
82 { return m_netMutex; }
83
84 //Immediate command API
85 virtual void FlushRXBuffer(void);
86 virtual bool SendCommand(const std::string& cmd) =0;
87 virtual std::string ReadReply(bool endOnSemicolon = true, std::function<void(float)> progress = nullptr) =0;
88 virtual size_t ReadRawData(size_t len, unsigned char* buf, std::function<void(float)> progress = nullptr) =0;
89 virtual void SendRawData(size_t len, const unsigned char* buf) =0;
90
91 virtual bool IsCommandBatchingSupported() =0;
92 virtual bool IsConnected() =0;
93
103 void EnableRateLimiting(std::chrono::milliseconds interval)
104 {
105 m_rateLimitingEnabled = true;
106 m_rateLimitingInterval = interval;
107 m_nextCommandReady = std::chrono::system_clock::now();
108 }
109
128 void DeduplicateCommand(const std::string& cmd)
129 { m_dedupCommands.emplace(cmd); }
130
131public:
132 typedef SCPITransport* (*CreateProcType)(const std::string& args);
133 typedef std::vector<TransportEndpoint> (*EnumEndpointsProcType)();
134 static void DoAddTransportClass(const std::string& name, CreateProcType proc, EnumEndpointsProcType eproc);
135
136 static void EnumTransports(std::vector<std::string>& names);
137 static SCPITransport* CreateTransport(const std::string& transport, const std::string& args);
138
139 static std::vector<TransportEndpoint> EnumEndpoints(const std::string& transport);
140 static std::vector<TransportEndpoint> EnumTransportEndpoints();
141
142protected:
143 void RateLimitingWait();
144
145 //Class enumeration
146 typedef std::map< std::string, CreateProcType > CreateMapType;
147 static CreateMapType m_createprocs;
148
149 typedef std::map< std::string, EnumEndpointsProcType > EnumEndpointsMapType;
150 static EnumEndpointsMapType m_enumEndpointsProcs;
151
152 //Queued commands waiting to be sent
153 std::mutex m_queueMutex;
154 std::recursive_mutex m_netMutex;
155 std::list<std::string> m_txQueue;
156
157 //Set of commands that are OK to deduplicate
158 std::set<std::string> m_dedupCommands;
159
160 //Rate limiting (send max of one command per X time)
161 bool m_rateLimitingEnabled;
162 std::chrono::system_clock::time_point m_nextCommandReady;
163 std::chrono::milliseconds m_rateLimitingInterval;
164};
165
166#define TRANSPORT_INITPROC(T) \
167 static SCPITransport* CreateInstance(const std::string& args) \
168 { \
169 return new T(args); \
170 } \
171 virtual std::string GetName() override \
172 { return GetTransportName(); }
173
174#define AddTransportClass(T) SCPITransport::DoAddTransportClass(T::GetTransportName(), T::CreateInstance, T::EnumTransportEndpoints)
175
176#endif
Definition AcceleratorBuffer.h:204
Abstraction of a transport layer for moving SCPI data between endpoints.
Definition SCPITransport.h:53
void EnableRateLimiting(std::chrono::milliseconds interval)
Enables rate limiting. Rate limiting is only applied to the queued command API.
Definition SCPITransport.h:103
virtual bool SetTimeouts(unsigned int txUs, unsigned int rxUs)
Base implementation does nothing.
Definition SCPITransport.cpp:306
void RateLimitingWait()
Block until it's time to send the next command when rate limiting.
Definition SCPITransport.cpp:174
bool FlushCommandQueue()
Pushes all pending commands from SendCommandQueued() calls and blocks until they are all sent.
Definition SCPITransport.cpp:183
void SendCommandQueued(const std::string &cmd)
Pushes a command into the transmit FIFO then returns immediately.
Definition SCPITransport.cpp:87
std::string SendCommandQueuedWithReply(const std::string &cmd, bool endOnSemicolon=true)
Sends a command (flushing any pending/queued commands first), then returns the response.
Definition SCPITransport.cpp:212
void SendCommandImmediate(const std::string &cmd)
Sends a command (jumping ahead of the queue) which does not require a response.
Definition SCPITransport.cpp:238
void * SendCommandImmediateWithRawBlockReply(const std::string &cmd, size_t &len)
Sends a command (jumping ahead of the queue) which reads a binary block response.
Definition SCPITransport.cpp:251
std::string SendCommandImmediateWithReply(const std::string &cmd, bool endOnSemicolon=true)
Sends a command (jumping ahead of the queue), then returns the response.
Definition SCPITransport.cpp:223
void DeduplicateCommand(const std::string &cmd)
Adds a command to the set of commands which may be deduplicated in the queue.
Definition SCPITransport.h:128
Definition SCPITransport.h:43