AdsLib
Loading...
Searching...
No Matches
AmsConnection.h
1// SPDX-License-Identifier: MIT
6#pragma once
7
8#include "AmsPort.h"
9#include "Sockets.h"
10#include "Router.h"
11
12#include <atomic>
13#include <chrono>
14#include <condition_variable>
15#include <thread>
16
17using Timepoint = std::chrono::steady_clock::time_point;
18#define WAITING_FOR_RESPONSE ((uint32_t)0xFFFFFFFF)
19
20struct AmsRequest {
21 Frame frame;
22 const AmsAddr& destAddr;
23 uint16_t port;
24 uint16_t cmdId;
25 uint32_t bufferLength;
26 void* buffer;
27 uint32_t* bytesRead;
28 Timepoint deadline;
29
30 AmsRequest(const AmsAddr& ams,
31 uint16_t __port,
32 uint16_t __cmdId,
33 uint32_t __bufferLength = 0,
34 void* __buffer = nullptr,
35 uint32_t* __bytesRead = nullptr,
36 size_t payloadLength = 0)
37 : frame(sizeof(AmsTcpHeader) + sizeof(AoEHeader) + payloadLength),
38 destAddr(ams),
39 port(__port),
40 cmdId(__cmdId),
41 bufferLength(__bufferLength),
42 buffer(__buffer),
43 bytesRead(__bytesRead)
44 {}
45
46 void SetDeadline(uint32_t tmms)
47 {
48 deadline = std::chrono::steady_clock::now();
49 deadline += std::chrono::milliseconds(tmms);
50 }
51};
52
54 std::atomic<AmsRequest*> request;
55 std::atomic<uint32_t> invokeId;
56
58 void Notify(uint32_t error);
59 void Release();
60
61 // wait for response or timeout and return received errorCode or ADSERR_CLIENT_SYNCTIMEOUT
62 uint32_t Wait();
63
64private:
65 std::mutex mutex;
66 std::condition_variable cv;
67 uint32_t errorCode;
68};
69
71 AmsConnection(Router& __router, const struct addrinfo* destination = nullptr);
73
74 SharedDispatcher CreateNotifyMapping(uint32_t hNotify, std::shared_ptr<Notification> notification);
75 long DeleteNotification(const AmsAddr& amsAddr, uint32_t hNotify, uint32_t tmms, uint16_t port);
76 long AdsRequest(AmsRequest& request, uint32_t timeout);
77
84 bool IsConnectedTo(const struct addrinfo* targetAddresses) const;
85
86private:
87 friend struct AmsRouter;
88 Router& router;
89 TcpSocket socket;
90 std::thread receiver;
91 std::atomic<size_t> refCount;
92 std::atomic<uint32_t> invokeId;
93 std::array<AmsResponse, Router::NUM_PORTS_MAX> queue;
94
95 template<class T> void ReceiveFrame(AmsResponse* response, size_t length, uint32_t aoeError) const;
96 bool ReceiveNotification(const AoEHeader& header);
97 void ReceiveJunk(size_t bytesToRead) const;
98 void Receive(void* buffer, size_t bytesToRead, timeval* timeout = nullptr) const;
99 void Receive(void* buffer, size_t bytesToRead, const Timepoint& deadline) const;
100 template<class T> void Receive(T& buffer) const { Receive(&buffer, sizeof(T)); }
101 AmsResponse* Write(AmsRequest& request, const AmsAddr srcAddr);
102 void Recv();
103 void TryRecv();
104 uint32_t GetInvokeId();
105 AmsResponse* Reserve(AmsRequest* request, uint16_t port);
106 AmsResponse* GetPending(uint32_t id, uint16_t port);
107
108 std::map<VirtualConnection, SharedDispatcher> dispatcherList;
109 std::recursive_mutex dispatcherListMutex;
110 SharedDispatcher DispatcherListAdd(const VirtualConnection& connection);
111 SharedDispatcher DispatcherListGet(const VirtualConnection& connection);
112
113public:
114 const uint32_t ownIp;
115};
The complete address of an ADS device can be stored in this structure.
Definition: AdsDef.h:237
Definition: AmsConnection.h:70
bool IsConnectedTo(const struct addrinfo *targetAddresses) const
Definition: AmsConnection.cpp:100
Definition: AmsConnection.h:20
Definition: AmsConnection.h:53
AmsResponse()
Definition: AmsConnection.cpp:9
Definition: AmsRouter.h:11
Definition: AmsHeader.h:18
Definition: AmsHeader.h:109
Definition: Frame.h:11
Definition: Router.h:10
Definition: Sockets.h:57