ngscopeclient 0.1-dev+51fbda87c
SCPITransport.h
Go to the documentation of this file.
1/***********************************************************************************************************************
2* *
3* libscopehal *
4* *
5* Copyright (c) 2012-2024 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
47{
48public:
50 virtual ~SCPITransport();
51
52 virtual std::string GetConnectionString() =0;
53 virtual std::string GetName() =0;
54
55 /*
56 Queued command API
57
58 Note that glscopeclient flushes the command queue in ScopeThread.
59 Headless applications will need to do this manually after performing a write-only application, otherwise
60 the command will remain queued indefinitely.
61
62 TODO: look into a background thread or something that's automatically launched by the transport to do this
63 after some kind of fixed timeout?
64 */
65 void SendCommandQueued(const std::string& cmd);
66 std::string SendCommandQueuedWithReply(std::string cmd, bool endOnSemicolon = true);
67 void SendCommandImmediate(std::string cmd);
68 std::string SendCommandImmediateWithReply(std::string cmd, bool endOnSemicolon = true);
69 void* SendCommandImmediateWithRawBlockReply(std::string cmd, size_t& len);
70 bool FlushCommandQueue();
71
72 //Manual mutex locking for ReadRawData() etc
73 std::recursive_mutex& GetMutex()
74 { return m_netMutex; }
75
76 //Immediate command API
77 virtual void FlushRXBuffer(void);
78 virtual bool SendCommand(const std::string& cmd) =0;
79 virtual std::string ReadReply(bool endOnSemicolon = true, std::function<void(float)> progress = nullptr) =0;
80 virtual size_t ReadRawData(size_t len, unsigned char* buf, std::function<void(float)> progress = nullptr) =0;
81 virtual void SendRawData(size_t len, const unsigned char* buf) =0;
82
83 virtual bool IsCommandBatchingSupported() =0;
84 virtual bool IsConnected() =0;
85
95 void EnableRateLimiting(std::chrono::milliseconds interval)
96 {
97 m_rateLimitingEnabled = true;
98 m_rateLimitingInterval = interval;
99 m_nextCommandReady = std::chrono::system_clock::now();
100 }
101
120 void DeduplicateCommand(const std::string& cmd)
121 { m_dedupCommands.emplace(cmd); }
122
123public:
124 typedef SCPITransport* (*CreateProcType)(const std::string& args);
125 static void DoAddTransportClass(std::string name, CreateProcType proc);
126
127 static void EnumTransports(std::vector<std::string>& names);
128 static SCPITransport* CreateTransport(const std::string& transport, const std::string& args);
129
130protected:
131 void RateLimitingWait();
132
133 //Class enumeration
134 typedef std::map< std::string, CreateProcType > CreateMapType;
135 static CreateMapType m_createprocs;
136
137 //Queued commands waiting to be sent
138 std::mutex m_queueMutex;
139 std::recursive_mutex m_netMutex;
140 std::list<std::string> m_txQueue;
141
142 //Set of commands that are OK to deduplicate
143 std::set<std::string> m_dedupCommands;
144
145 //Rate limiting (send max of one command per X time)
146 bool m_rateLimitingEnabled;
147 std::chrono::system_clock::time_point m_nextCommandReady;
148 std::chrono::milliseconds m_rateLimitingInterval;
149};
150
151#define TRANSPORT_INITPROC(T) \
152 static SCPITransport* CreateInstance(const std::string& args) \
153 { \
154 return new T(args); \
155 } \
156 virtual std::string GetName() override \
157 { return GetTransportName(); }
158
159#define AddTransportClass(T) SCPITransport::DoAddTransportClass(T::GetTransportName(), T::CreateInstance)
160
161#endif
Abstraction of a transport layer for moving SCPI data between endpoints.
Definition: SCPITransport.h:47
void EnableRateLimiting(std::chrono::milliseconds interval)
Enables rate limiting. Rate limiting is only applied to the queued command API.
Definition: SCPITransport.h:95
void RateLimitingWait()
Block until it's time to send the next command when rate limiting.
Definition: SCPITransport.cpp:171
bool FlushCommandQueue()
Pushes all pending commands from SendCommandQueued() calls and blocks until they are all sent.
Definition: SCPITransport.cpp:180
void SendCommandQueued(const std::string &cmd)
Pushes a command into the transmit FIFO then returns immediately.
Definition: SCPITransport.cpp:84
void SendCommandImmediate(std::string cmd)
Sends a command (jumping ahead of the queue) which does not require a response.
Definition: SCPITransport.cpp:234
std::string SendCommandImmediateWithReply(std::string cmd, bool endOnSemicolon=true)
Sends a command (jumping ahead of the queue), then returns the response.
Definition: SCPITransport.cpp:219
void * SendCommandImmediateWithRawBlockReply(std::string cmd, size_t &len)
Sends a command (jumping ahead of the queue) which reads a binary block response.
Definition: SCPITransport.cpp:247
std::string SendCommandQueuedWithReply(std::string cmd, bool endOnSemicolon=true)
Sends a command (flushing any pending/queued commands first), then returns the response.
Definition: SCPITransport.cpp:208
void DeduplicateCommand(const std::string &cmd)
Adds a command to the set of commands which may be deduplicated in the queue.
Definition: SCPITransport.h:120