001/** 002 * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ 003 * 004 * This file is part of Dicoogle/dicoogle. 005 * 006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Dicoogle/dicoogle is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Dicoogle. If not, see <http://www.gnu.org/licenses/>. 018 */ 019/** 020 * 021 * Generic DICOM Worklist Server SCP 022 */ 023package pt.ua.dicoogle.server.queryretrieve; 024 025//import configurations.ConfigurationsValues; 026 027//import gui.MainWindow; 028//import gui.MainWindow.LOG_MODES; 029import java.io.IOException; 030import java.util.concurrent.Executor; 031 032 033import org.dcm4che2.data.DicomObject; 034import org.dcm4che2.net.Association; 035import org.dcm4che2.net.ConfigurationException; 036import org.dcm4che2.data.UID; 037import org.dcm4che2.net.CommandUtils; 038import org.dcm4che2.net.Device; 039import org.dcm4che2.net.NetworkApplicationEntity; 040import org.dcm4che2.net.NetworkConnection; 041import org.dcm4che2.net.NewThreadExecutor; 042import org.dcm4che2.net.TransferCapability; 043import org.dcm4che2.net.UserIdentity; 044import org.dcm4che2.net.service.VerificationService; 045import pt.ua.dicoogle.core.ServerSettings; 046 047/** 048 * 049 * @author Joaoffr <joaoffr@ua.pt> 050 * @author DavidP <davidp@ua.pt> 051 * 052 * @version $Revision: 002 $ $Date: 2008-11-22 14:25:00 $ 053 * @since Nov 21, 2008 054 * 055 */ 056public class DicomEchoReply extends VerificationService { 057 058 059 /** Settings */ 060 ServerSettings s = ServerSettings.getInstance(); 061 062 private static final String[] TRANSF_CAP = { 063 UID.ImplicitVRLittleEndian, 064 UID.ExplicitVRBigEndian, 065 UID.ExplicitVRLittleEndian 066 }; 067 068 /* Implemented SOP Class */ 069 private static final String SOP_CLASS = UID.VerificationSOPClass; 070 071 private static final int PORT_OFFSET = 100; 072 073 private static final String SERVICE_LABEL = ""; 074 075 076 /**** Class Atributes ****/ 077 078 private static final String MODULE_NAME = "DICOMWLS_EchoReply"; /* DEFAULT Implemented module name */ 079 private final NetworkApplicationEntity remoteAE = new NetworkApplicationEntity(); /* Remote Application Entity (client) */ 080 private final NetworkConnection remoteConn = new NetworkConnection(); /* Remote connection associated with remoteAE */ 081 private final Device device = new Device(MODULE_NAME); /* Module device */ 082 private final NetworkApplicationEntity localAE = new NetworkApplicationEntity(); /* Local Application Entity (this server) 'ea' */ 083 private final NetworkConnection localConn = new NetworkConnection(); /* Local connection associated with localAE 'conn' */ 084 private boolean started = false; /* True if server is allready started */ 085 private int port = 0; 086 087 088 089 /* Module executor */ 090 private static final Executor executor = (Executor) new NewThreadExecutor(MODULE_NAME); /* Server thread */ 091 092 093 094 public DicomEchoReply() { 095 096 super(); 097 098 this.port = s.getWlsPort() + DicomEchoReply.PORT_OFFSET; ; 099 /* clients */ 100 this.remoteAE.setInstalled(true); 101 this.remoteAE.setAssociationInitiator(true); 102 this.remoteAE.setNetworkConnection(this.remoteConn); 103 104 105 106 /* server */ 107 this.started = false; 108 this.localAE.setInstalled(true); 109 this.localAE.setAssociationAcceptor(true); 110 this.localAE.setAssociationInitiator(false); 111 this.localAE.setNetworkConnection(this.localConn ); 112 this.localAE.setAETitle(s.getAE() + DicomEchoReply.SERVICE_LABEL); 113 this.localAE.register(new VerificationService()); 114 this.localAE.register(this); 115 116 TransferCapability[] tc = { new TransferCapability( DicomEchoReply.SOP_CLASS, 117 DicomEchoReply.TRANSF_CAP, 118 TransferCapability.SCP) }; 119 this.localAE.setTransferCapability(tc); 120 121/* this.localAE.setDimseRspTimeout(confs.getWlsConfigs().getDIMSE_RSP_TIMEOUT()); 122 this.localAE.setIdleTimeout(confs.getWlsConfigs().getIDLE_TIMEOUT());*/ 123 124 /*this.localAE.setMaxPDULengthReceive(confs.getWlsConfigs().getMAX_PDU_LENGTH_RECEIVE()); 125 this.localAE.setMaxPDULengthSend(confs.getWlsConfigs().getMAX_PDU_LENGTH_SEND());*/ 126 /** 127 this.localAE.setSupportedCharacterSet("CharacterSetSup");*/ 128 129 this.localConn.setPort(this.port); 130 //this.localConn.setMaxScpAssociations(confs.getWlsConfigs().getMAX_CLIENT_ASSOCS()); 131 /*this.localConn.setHostname(DicomWLS.LOCAL_HOST_NAME);*/ 132 // this.localConn.setAcceptTimeout(confs.getWlsConfigs().getACCEPT_TIMEOUT()); 133 //this.localConn.setConnectTimeout(confs.getWlsConfigs().getCONNECTION_TIMEOUT()); 134 135 136 //this.device.setDescription(confs.getWlsConfigs().getDEVICE_DESCRIPTION()); 137 this.device.setNetworkApplicationEntity(this.localAE); 138 this.device.setNetworkConnection(this.localConn); 139 /*this.device.setDeviceName(DicomWLS.MODULE_NAME);*/ 140 141 } 142 143 144 /** 145 * Set local Host Name 146 * @param hostname 147 */ 148 public final void setLocalHost(String hostname) { 149 this.localConn.setHostname(hostname); 150 } 151 152 /** 153 * Get Local Host Name 154 * @return 155 */ 156 public final String getLocalHost() { 157 return this.localConn.getHostname(); 158 } 159 160 /** 161 * Set Remote Host Name 162 * @param hostname 163 */ 164 public final void setRemoteHost(String hostname) { 165 this.remoteConn.setHostname(hostname); 166 } 167 168 /** 169 * Get Remote Host Name 170 * @return 171 */ 172 public final String getRemoteHost() { 173 return this.remoteConn.getHostname(); 174 } 175 176 /** 177 * Set Local Port 178 * @param port 179 */ 180 public final void setLocalPort(int port) { 181 int tmp = (port >= 1 && port <= 0xffff) ? port : 105; 182 this.localConn.setPort(tmp); 183 } 184 185 /** 186 * Get Local Port 187 * @return 188 */ 189 public final int getLocalPort() { 190 return this.localConn.getPort(); 191 } 192 193 /** 194 * Set Remote Application Entity Title 195 * @param called 196 */ 197 public final void setRemoteAET(String called) { 198 this.remoteAE.setAETitle(called); 199 } 200 201 /** 202 * Get Remote Application Entity Title 203 * @return 204 */ 205 public final String getRemoteAET() { 206 return this.remoteAE.getAETitle(); 207 } 208 209 /** 210 * Set Local Application Entity Title 211 * @param calling 212 */ 213 public final void setLocalAET(String calling) { 214 this.localAE.setAETitle(calling); 215 } 216 217 /** 218 * Get Local Application Entity Title 219 * @return 220 */ 221 public final String getLocalAET() { 222 return this.localAE.getAETitle(); 223 } 224 225 /** 226 * Set Local User Identity 227 * @param userIdentity 228 */ 229 public final void setUserIdentity(UserIdentity userIdentity) { 230 this.localAE.setUserIdentity(userIdentity); 231 } 232 233 /** 234 * Get Local User Identity 235 * @return 236 */ 237 public final UserIdentity getUserIdentity() { 238 return this.localAE.getUserIdentity(); 239 } 240 241 public boolean isStarted() { 242 return started; 243 } 244 245 public void setStarted(boolean started) { 246 this.started = started; 247 } 248 249 /** 250 * 251 * @param connectTimeout 252 */ 253 public final void setConnectTimeout(int connectTimeout) { 254 this.localConn.setConnectTimeout(connectTimeout); 255 } 256 257 /** 258 * 259 * @param maxPDULength 260 */ 261 public final void setMaxPDULengthReceive(int maxPDULength) { 262 this.localAE.setMaxPDULengthReceive(maxPDULength); 263 } 264 265 /** 266 * 267 * @param maxPDULength 268 */ 269 public final void setMaxPDULengthSend(int maxPDULength) { 270 this.localAE.setMaxPDULengthSend(maxPDULength); 271 } 272 273 /** 274 * 275 * @param packPDV 276 */ 277 public final void setPackPDV(boolean packPDV) { 278 this.localAE.setPackPDV(packPDV); 279 } 280 281 /** 282 * 283 * @param period 284 */ 285 public final void setAssociationReaperPeriod(int period) { 286 this.device.setAssociationReaperPeriod(period); 287 } 288 289 /** 290 * 291 * @param timeout 292 */ 293 public final void setDimseRspTimeout(int timeout) { 294 this.localAE.setDimseRspTimeout(timeout); 295 } 296 297 /** 298 * 299 * @param tcpNoDelay 300 */ 301 public final void setTcpNoDelay(boolean tcpNoDelay) { 302 this.localConn.setTcpNoDelay(tcpNoDelay); 303 } 304 305 /** 306 * 307 * @param timeout 308 */ 309 public final void setAcceptTimeout(int timeout) { 310 this.localConn.setAcceptTimeout(timeout); 311 } 312 313 /** 314 * 315 * @param timeout 316 */ 317 public final void setReleaseTimeout(int timeout) { 318 this.localConn.setReleaseTimeout(timeout); 319 } 320 321 /** 322 * 323 * @param timeout 324 */ 325 public final void setSocketCloseDelay(int timeout) { 326 this.localConn.setSocketCloseDelay(timeout); 327 } 328 329 /** 330 * 331 * @param bufferSize 332 */ 333 public final void setReceiveBufferSize(int bufferSize) { 334 this.localConn.setReceiveBufferSize(bufferSize); 335 } 336 337 /** 338 * 339 * @param bufferSize 340 */ 341 public final void setSendBufferSize(int bufferSize) { 342 this.localConn.setSendBufferSize(bufferSize); 343 } 344 345 /** 346 * 347 * @param ts 348 */ 349 public void setTransferSyntax(String[] ts) { 350 TransferCapability[] tc = { new TransferCapability( 351 UID.ModalityWorklistInformationModelFIND, ts, 352 TransferCapability.SCU) }; 353 this.localAE.setTransferCapability(tc); 354 } 355 356 /** 357 * 358 * @param timeout 359 */ 360 public final void setIdleTimeout(int timeout) { 361 this.localAE.setIdleTimeout(timeout); 362 } 363 364 365 366 /** 367 * Start server socket accept client(s) connection 368 * 369 * @return 370 * @throws java.io.IOException 371 * @throws org.dcm4che2.net.ConfigurationException 372 * @throws java.lang.InterruptedException 373 */ 374 public boolean startListening() { 375 if (this.device != null) { 376 try { 377 CommandUtils.setIncludeUIDinRSP(true); 378 this.device.startListening(DicomEchoReply.executor); 379 } catch (Exception ex) { 380 ///MainWindow.getMw().add2ServerLogln(ex.getMessage(), LOG_MODES.ERROR); 381 return false; 382 } 383 this.started = true; 384 return true; 385 } 386 387 return false; 388 } 389 390 /** 391 * Stop all active client socket connections 392 * 393 * @return 394 * @throws java.io.IOException 395 * @throws org.dcm4che2.net.ConfigurationException 396 * @throws java.lang.InterruptedException 397 */ 398 public boolean stopListening() { 399 if (this.device != null) { 400 this.device.stopListening(); 401 this.started = false; 402 return true; 403 } 404 405 return false; 406 } 407 408 @Override 409 public String toString() { 410 return( "[START INFO PRINT]" + "\n" + 411 "\tModuleName = " + DicomEchoReply.MODULE_NAME + "\n" + 412 "\tLocalAETitle = " + this.localAE.getAETitle() + "\n" + 413 "\tPort = " + this.localConn.getPort() + "\n" + 414 "\tTransfereCapabilities = " + strVectConcat(this.localAE.getTransferCapability()[0].getTransferSyntax(), "; ") + "\n" + 415 "\tModality = " + DicomEchoReply.SOP_CLASS + "\n" + 416 "\tStarted = " + this.started + "\n" + 417 "[END INFO PRINT]" + "\n" 418 ); 419 } 420 421 @Override 422 public void cecho(Association as, int pcid, DicomObject cmd) throws IOException { 423 ///MainWindow.getMw().add2ServerLogln("CEcho request from " + as.getRemoteAET() + " received!", LOG_MODES.INFO); 424 425 super.cecho(as, pcid, cmd); 426 427 //System.out.println(cmd); 428 429 ///MainWindow.getMw().add2ServerLogln("CEcho response send to " + as.getRemoteAET() + "!", LOG_MODES.INFO); 430 431 } 432 433 434 private static String strVectConcat(String[] stVectIN, String sep) { 435 436 if (stVectIN == null) return new String("[any]"); 437 438 String temp = new String(""); 439 for (int i = 0; i < stVectIN.length - 1; i++) 440 temp = temp + stVectIN[i] + sep; 441 442 temp = temp + stVectIN[stVectIN.length - 1]; 443 444 return temp; 445 } 446 447} 448