void sendPPS(boolean create, Dataset pps, String aet) throws Exception { ActiveAssociation aa = openAssociation(aet, UIDs.GeneralPurposePerformedProcedureStepSOPClass); try { Association a = aa.getAssociation(); DcmObjectFactory dof = DcmObjectFactory.getInstance(); Command cmdRq = dof.newCommand(); final String iuid = pps.getString(Tags.SOPInstanceUID); if (create) { cmdRq.initNCreateRQ(a.nextMsgID(), UIDs.GeneralPurposePerformedProcedureStepSOPClass, iuid); } else { cmdRq.initNSetRQ(a.nextMsgID(), UIDs.GeneralPurposePerformedProcedureStepSOPClass, iuid); } Dimse dimseRq = AssociationFactory.getInstance().newDimse(PCID_GPPPS, cmdRq, pps.exclude(SOP_IUID)); if (log.isDebugEnabled()) { log.debug("GP-PPS Attributes:"); log.debug(pps); } final Dimse dimseRsp = aa.invoke(dimseRq).get(); final Command cmdRsp = dimseRsp.getCommand(); final int status = cmdRsp.getStatus(); switch (status) { case 0x0000: break; case 0x0116: log.warn( "Received Warning Status 116H (=Attribute Value Out of Range) from remote AE " + aet); break; default: throw new DcmServiceException(status, cmdRsp.getString(Tags.ErrorComment)); } } finally { try { aa.release(true); } catch (Exception e) { log.warn("Failed to release " + aa.getAssociation()); } } }
public Vector cGET(Dataset ds) throws ConnectException, IOException, InterruptedException { PresContext pc; List dimseList; Vector datasetVector; // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // Test, if Presentation Context for C-MOVE is supported // API doc: Association.getAcceptedPresContext(String asuid, String tsuid) if ((pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelGET, UIDs.ExplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelGET, UIDs.ImplicitVRLittleEndian)) == null) { throw new ConnectException( "Association does not support presentation context for StudyRootQueryRetrieveInformationModelMOVE SOP."); } // Get the Study Instance UID of the study to mode String suid = ds.getString(Tags.SOPInstanceUID); // Prepare info for logging String patName = ds.getString(Tags.PatientName); String patID = ds.getString(Tags.PatientID); String studyDate = ds.getString(Tags.StudyDate); String prompt = "Study[" + suid + "] from " + studyDate + " for Patient[" + patID + "]: " + patName; // log.info("Moving: " + prompt); // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command rqCmd = dof.newCommand(); // API doc: Command.initCMoveRQ(int msgID, String sopClassUID, int priority, String moveDest) rqCmd.initCGetRSP(assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelGET, priority); Dataset rqDs = dof.newDataset(); rqDs.putCS(Tags.QueryRetrieveLevel, getQueryRetrieveLevel(STUDY_LEVEL)); // Only Unique Key allowed in C-MOVE. PS 3.4 -C.2.2.1 Attribute Types rqDs.putUI(Tags.SOPInstanceUID, suid); // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse moveRq = aFact.newDimse(pc.pcid(), rqCmd, rqDs); // Invoke active association with move request Dimse FutureRSP future = aassoc.invoke(moveRq); // Response to the C-MOVE request. // The result cannot be accessed until it has been set. Dimse moveRsp = future.get(); Command rspCmd = moveRsp.getCommand(); if (DEBUG) { StringWriter w = new StringWriter(); w.write("C-FIND RQ Identifier:\n"); keys.dumpDataset(w, null); log.debug(w.toString()); } // Invoke active association with find request Dimse // Response to the C-FIND request. // The result cannot be accessed until it has been set. // Get the list of found objects dimseList = future.listPending(); // >>>> Extract Dataset from Dimse datasetVector = new Vector(); // If no List of DIMSE objects was generated or it is empty return an empty Vector if (dimseList == null || dimseList.isEmpty()) { return datasetVector; } // Process all elements for (int i = 0; i < dimseList.size(); i++) { datasetVector.addElement(((Dimse) dimseList.get(i)).getDataset()); if (((Dimse) dimseList.get(i)).getDataset() == null) System.out.println(" Dataset created succesffullyu "); } // PS 3.7 - 9.3.4 C-MOVE PROTOCOL, 9.3.4.2 C-MOVE-RSP int status = rspCmd.getStatus(); switch (status) { case 0x0000: // log.info("Moved: " + prompt); break; case 0xB000: log.error("One or more failures during move of " + prompt); break; default: log.error("Failed to move " + prompt + "\n\terror tstatus: " + Integer.toHexString(status)); break; } System.out.println("The move sise is : " + datasetVector.size()); return datasetVector; }
/** * Queries the archive for DICOM objects matching Attribute Keys defined in the loacal field * "keys". This field is set by the constructor out of the configuration parameters or by the * methods setQueryKeys(Configuration) and setQueryKeys(Dataset). See PS 3.4 - Annex C * QUERY/RETRIEVE SERVICE CLASS. * * <p>The method returns, when the result is received from the communication partner. * * @return the result of the cFIND as a Vector of Dataset objects each specifying one matching * DICOM object. If no matching objects are found an empty Vector is returned. * @throws ConnectException * @throws IOException */ public Vector cFIND() throws ConnectException, IOException, InterruptedException { List dimseList; Vector datasetVector; // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // Test, if Presentation Context for C-FIND is supported // API doc: Association.getAcceptedPresContext(String asuid, String tsuid) // UIDs.StudyRootQueryRetrieveInformationModelGET if ((pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelFIND, UIDs.ExplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext( UIDs.StudyRootQueryRetrieveInformationModelFIND, UIDs.ImplicitVRLittleEndian)) == null) { throw new ConnectException( "Association does not support presentation context for StudyRootQueryRetrieveInformationModelFIND SOP."); } // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command rqCmd = dof.newCommand(); // API doc: Command.initCFindRQ(int msgID, String sopClassUID, int priority) rqCmd.initCFindRQ(assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelFIND, priority); // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse findRq = aFact.newDimse(pc.pcid(), rqCmd, keys); if (DEBUG) { StringWriter w = new StringWriter(); w.write("C-FIND RQ Identifier:\n"); keys.dumpDataset(w, null); log.debug(w.toString()); } // Invoke active association with find request Dimse FutureRSP future = aassoc.invoke(findRq); // Response to the C-FIND request. // The result cannot be accessed until it has been set. Dimse findRsp = future.get(); // Get the list of found objects dimseList = future.listPending(); // >>>> Extract Dataset from Dimse datasetVector = new Vector(); // If no List of DIMSE objects was generated or it is empty return an empty Vector if (dimseList == null || dimseList.isEmpty()) { return datasetVector; } // Process all elements for (int i = 0; i < dimseList.size(); i++) { datasetVector.addElement(((Dimse) dimseList.get(i)).getDataset()); } return datasetVector; }
/** * Stores a DICOM object in an archive (Storage SCP). * * <p>See PS 3.4 - Annex B STORAGE SERVICE CLASS. * * @param ds the Dataset to store. * @throws ConnectException * @throws ParseException * @throws IOException * @throws InterruptedException * @throws IllegalStateException */ public void cSTORE(Dataset ds) throws InterruptedException, IOException, ConnectException, ParseException { String sopClassUID; String sopInstUID; PresContext pc = null; // An association must be active if (aassoc == null) { throw new ConnectException("No Association established"); } // SOP Class UID must be given if ((sopClassUID = ds.getString(Tags.SOPClassUID)) == null) { throw new ParseException("No SOP Class UID in Dataset", 0); } // SOP Instance UID must be given if ((sopInstUID = ds.getString(Tags.SOPInstanceUID)) == null) { throw new ParseException("No SOP Instance UID in Dataset", 0); } // Test, if applicable presentation context was found if ((pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ImplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ExplicitVRLittleEndian)) == null && (pc = aassoc .getAssociation() .getAcceptedPresContext(sopClassUID, UIDs.ExplicitVRBigEndian)) == null) { throw new ConnectException("No applicable presentation context found"); } // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure Command cStoreRQ = oFact.newCommand(); // API doc: Command.initCStoreRQ(int msgID, String sopClassUID, String sopInstUID, int priority) cStoreRQ.initCStoreRQ(assoc.nextMsgID(), sopClassUID, sopInstUID, priority); // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds) // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM Dimse storeRq = aFact.newDimse(pc.pcid(), cStoreRQ, ds); // PS 3.7 - 9.3.1 C-STORE PROTOCOL, 9.3.1.2 C-STORE-RSP // Always returns SUCESS result code. // Invoke active association with echo request Dimse FutureRSP future = aassoc.invoke(storeRq); System.out.println("store is going in this AE"); // Response to the C-ECHO request. // The result cannot be accessed until it has been set. Dimse storeRsp = future.get(); Command rspCmd = storeRsp.getCommand(); // PS 3.7 - 9.3.5 C-MOVE PROTOCOL, 9.3.5.2 C-ECHO-RSP int status = rspCmd.getStatus(); switch (status) { case 0x0000: // Success break; default: log.error("C-STORE failed: " + Integer.toHexString(status)); break; } }