1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef GDCMULCONNECTIONMANAGER_H 19 #define GDCMULCONNECTIONMANAGER_H 20 21 #include "gdcmULTransitionTable.h" 22 #include "gdcmULConnection.h" 23 #include "gdcmULConnectionInfo.h" 24 #include "gdcmPresentationDataValue.h" 25 #include "gdcmULConnectionCallback.h" 26 #include "gdcmSubject.h" 27 #include "gdcmPresentationContext.h" 28 29 namespace gdcm { 30 class File; 31 class BaseRootQuery; 32 class BaseQuery; 33 34 namespace network { 35 36 /** 37 * \brief ULConnectionManager 38 * \details The ULConnectionManager performs actions on the ULConnection given inputs 39 * from the user and from the state of what's going on around the connection 40 * (ie, timeouts of the ARTIM timer, responses from the peer across the 41 * connection, etc). 42 * 43 * Its inputs are ULEvents, and it performs ULActions. 44 */ 45 class GDCM_EXPORT ULConnectionManager : public Subject 46 { 47 protected: 48 ULConnection* mConnection; 49 ULConnection* mSecondaryConnection; 50 ULTransitionTable mTransitions; 51 52 //no copying 53 ULConnectionManager(const ULConnectionManager& inCM); 54 55 //event handler loop. 56 //will just keep running until the current event is nonexistent. 57 //at which point, it will return the current state of the connection 58 //this starts by initiating an action, but can be put into a passive mode 59 //for a cmove/cstore combination by setting startWaiting to true 60 EStateID RunEventLoop(ULEvent& inEvent, ULConnection* inWhichConnection, 61 ULConnectionCallback* inCallback, const bool& startWaiting); 62 63 //like the above, but will manage the event loop for a move event (which 64 //is basically two simultaneous connections interwoven, one inbound and 65 //the other outbound. Note, for instance, that cmoversp's can be sent back 66 //during the other connection's operation. 67 EStateID RunMoveEventLoop(ULEvent& inEvent, ULConnectionCallback* inCallback); 68 69 public: 70 ULConnectionManager(); 71 ~ULConnectionManager() override; 72 73 // NOTE: (MM) The following two functions are difficults to use, therefore marking 74 // them as internal for now. 75 76 // \internal 77 /// returns true if a connection of the given AETitle (ie, 'this' program) 78 /// is able to connect to the given AETitle and Port in a certain amount of 79 /// time providing the connection type will establish the proper exchange 80 /// syntax with a server; if a different functionality is required, a 81 /// different connection should be established. 82 /// returns false if the connection type is 'move'-- have to give a return 83 /// port for move to work as specified. 84 bool EstablishConnection(const std::string& inAETitle, 85 const std::string& inConnectAETitle, 86 const std::string& inComputerName, long inIPAddress, 87 uint16_t inConnectPort, double inTimeout, 88 std::vector<PresentationContext> const & pcVector ); 89 90 /// returns true for above reasons, but contains the special 'move' port 91 /// \internal 92 bool EstablishConnectionMove(const std::string& inAETitle, 93 const std::string& inConnectAETitle, 94 const std::string& inComputerName, long inIPAddress, 95 uint16_t inConnectPort, double inTimeout, 96 uint16_t inReturnPort, 97 std::vector<PresentationContext> const & pcVector); 98 // \endinternal 99 100 101 //bool ReestablishConnection(const EConnectionType& inConnectionType, 102 // const DataSet& inDS); 103 104 //allows for a connection to be broken, but waits for an acknowledgement 105 //of the breaking for a certain amount of time. Returns true of the 106 //other side acknowledges the break 107 bool BreakConnection(const double& inTimeout); 108 109 //severs the connection, if it's open, without waiting for any kind of response. 110 //typically done if the program is going down. 111 void BreakConnectionNow(); 112 113 //This function will send a given piece of data 114 //across the network connection. It will return true if the 115 //sending worked, false otherwise. 116 //note that sending is asynchronous; as such, there's 117 //also a 'receive' option, but that requires a callback function. 118 //bool SendData(); 119 120 //send the Data PDU associated with Echo (ie, a default DataPDU) 121 //this lets the user confirm that the connection is alive. 122 //the user should look to cout to see the response of the echo command 123 //returns the PresentationDataValue that was returned by the remote 124 //host. Note that the PDV can be uninitialized, which would indicate failure. 125 //Echo does not use a callback for results. 126 std::vector<PresentationDataValue> SendEcho(); 127 128 // \internal 129 // API will change... 130 std::vector<DataSet> SendStore(const File &file, std::istream * pStream = nullptr, std::streampos dataSetOffset = 0 ); 131 std::vector<DataSet> SendFind(const BaseRootQuery* inRootQuery); 132 std::vector<DataSet> SendMove(const BaseRootQuery* inRootQuery); 133 134 std::vector<DataSet> SendNEventReport (const BaseQuery* inQuery); 135 std::vector<DataSet> SendNGet (const BaseQuery* inQuery); 136 std::vector<DataSet> SendNSet (const BaseQuery* inQuery); 137 std::vector<DataSet> SendNAction (const BaseQuery* inQuery); 138 std::vector<DataSet> SendNCreate (const BaseQuery* inQuery); 139 std::vector<DataSet> SendNDelete (const BaseQuery* inQuery); 140 // \endinternal 141 142 ///callback based API 143 void SendStore(const File & file, ULConnectionCallback* inCallback, std::istream * pStream = nullptr , std::streampos dataSetOffset = 0 ); 144 void SendFind(const BaseRootQuery* inRootQuery, ULConnectionCallback* inCallback); 145 /// return false upon error 146 bool SendMove(const BaseRootQuery* inRootQuery, ULConnectionCallback* inCallback); 147 148 void SendNEventReport (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 149 void SendNGet (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 150 void SendNSet (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 151 void SendNAction (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 152 void SendNCreate (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 153 void SendNDelete (const BaseQuery* inQuery, ULConnectionCallback* inCallback); 154 155 }; 156 } 157 } 158 159 #endif // GDCMULCONNECTIONMANAGER_H 160