001/* ***** BEGIN LICENSE BLOCK ***** 002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 003 * 004 * The contents of this file are subject to the Mozilla Public License Version 005 * 1.1 (the "License")), you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * http://www.mozilla.org/MPL/ 008 * 009 * Software distributed under the License is distributed on an "AS IS" basis, 010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 011 * for the specific language governing rights and limitations under the 012 * License. 013 * 014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in 015 * Java(TM), hosted at https://github.com/gunterze/dcm4che. 016 * 017 * The Initial Developer of the Original Code is 018 * Agfa Healthcare. 019 * Portions created by the Initial Developer are Copyright (C) 2012 020 * the Initial Developer. All Rights Reserved. 021 * 022 * Contributor(s): 023 * See @authors listed below 024 * 025 * Alternatively, the contents of this file may be used under the terms of 026 * either the GNU General Public License Version 2 or later (the "GPL"), or 027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 028 * in which case the provisions of the GPL or the LGPL are applicable instead 029 * of those above. If you wish to allow use of your version of this file only 030 * under the terms of either the GPL or the LGPL, and not to allow others to 031 * use your version of this file under the terms of the MPL, indicate your 032 * decision by deleting the provisions above and replace them with the notice 033 * and other provisions required by the GPL or the LGPL. If you do not delete 034 * the provisions above, a recipient may use your version of this file under 035 * the terms of any one of the MPL, the GPL or the LGPL. 036 * 037 * ***** END LICENSE BLOCK ***** */ 038 039package org.dcm4che3.net; 040 041import org.dcm4che3.data.Tag; 042import org.dcm4che3.data.Attributes; 043import org.dcm4che3.util.StringUtils; 044import org.dcm4che3.util.TagUtils; 045import org.dcm4che3.util.UIDUtils; 046import org.slf4j.Logger; 047import org.slf4j.LoggerFactory; 048 049/** 050 * @author Gunter Zeilinger <gunterze@gmail.com> 051 * 052 */ 053public enum Dimse { 054 C_STORE_RQ(0x0001, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 055 Tag.MessageID, ":C-STORE-RQ[pcid="), 056 C_STORE_RSP(0x8001, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 057 Tag.MessageIDBeingRespondedTo, ":C-STORE-RSP[pcid="), 058 C_GET_RQ(0x0010, Tag.AffectedSOPClassUID, 0, 059 Tag.MessageID, ":C-GET-RQ[pcid="), 060 C_GET_RSP(0x8010, Tag.AffectedSOPClassUID, 0, 061 Tag.MessageIDBeingRespondedTo, ":C-GET-RSP[pcid="), 062 C_FIND_RQ(0x0020, Tag.AffectedSOPClassUID, 0, 063 Tag.MessageID, ":C-FIND-RQ[pcid="), 064 C_FIND_RSP(0x8020, Tag.AffectedSOPClassUID, 0, 065 Tag.MessageIDBeingRespondedTo, ":C-FIND-RSP[pcid="), 066 C_MOVE_RQ(0x0021, Tag.AffectedSOPClassUID, 0, 067 Tag.MessageID, ":C-MOVE-RQ[pcid="), 068 C_MOVE_RSP(0x8021, Tag.AffectedSOPClassUID, 0, 069 Tag.MessageIDBeingRespondedTo, ":C-MOVE-RSP[pcid="), 070 C_ECHO_RQ(0x0030, Tag.AffectedSOPClassUID, 0, 071 Tag.MessageID, ":C-ECHO-RQ[pcid="), 072 C_ECHO_RSP(0x8030, Tag.AffectedSOPClassUID, 0, 073 Tag.MessageIDBeingRespondedTo, ":C-ECHO-RSP[pcid="), 074 N_EVENT_REPORT_RQ(0x0100, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 075 Tag.MessageID, ":N-EVENT-REPORT-RQ[pcid="), 076 N_EVENT_REPORT_RSP(0x8100, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 077 Tag.MessageIDBeingRespondedTo, ":N-EVENT-REPORT-RSP[pcid="), 078 N_GET_RQ(0x0110, Tag.RequestedSOPClassUID, Tag.RequestedSOPInstanceUID, 079 Tag.MessageID, ":N-GET-RQ[pcid="), 080 N_GET_RSP(0x8110, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 081 Tag.MessageIDBeingRespondedTo, ":N-GET-RSP[pcid="), 082 N_SET_RQ(0x0120, Tag.RequestedSOPClassUID, Tag.RequestedSOPInstanceUID, 083 Tag.MessageID, ":N-SET-RQ[pcid="), 084 N_SET_RSP(0x8120, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 085 Tag.MessageIDBeingRespondedTo, ":N-SET-RSP[pcid="), 086 N_ACTION_RQ(0x0130, Tag.RequestedSOPClassUID, Tag.RequestedSOPInstanceUID, 087 Tag.MessageID, ":N-ACTION-RQ[pcid="), 088 N_ACTION_RSP(0x8130, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 089 Tag.MessageIDBeingRespondedTo, ":N-ACTION-RSP[pcid="), 090 N_CREATE_RQ(0x0140, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 091 Tag.MessageID, ":N-CREATE-RQ[pcid="), 092 N_CREATE_RSP(0x8140, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 093 Tag.MessageIDBeingRespondedTo, ":N-CREATE-RSP[pcid="), 094 N_DELETE_RQ(0x0150, Tag.RequestedSOPClassUID, Tag.RequestedSOPInstanceUID, 095 Tag.MessageID, ":N-DELETE-RQ[pcid="), 096 N_DELETE_RSP(0x8150, Tag.AffectedSOPClassUID, Tag.AffectedSOPInstanceUID, 097 Tag.MessageIDBeingRespondedTo, ":N-DELETE-RSP[pcid="), 098 C_CANCEL_RQ(0x0FFF, 0, 0, Tag.MessageIDBeingRespondedTo, ":C-CANCEL-RQ[pcid="); 099 100 public static final Logger LOG = LoggerFactory.getLogger(Dimse.class); 101 102 private final int commandField; 103 private final int tagOfSOPClassUID; 104 private final int tagOfSOPInstanceUID; 105 private final int tagOfMessageID; 106 private final String prompt; 107 108 private Dimse(int cmdField, int tagOfSOPClassUID, int tagOfSOPInstanceUID, 109 int tagOfMessageID, String prompt) { 110 this.commandField = cmdField; 111 this.tagOfSOPClassUID = tagOfSOPClassUID; 112 this.tagOfSOPInstanceUID = tagOfSOPInstanceUID; 113 this.tagOfMessageID = tagOfMessageID; 114 this.prompt = prompt; 115 } 116 117 public int commandField() { 118 return commandField; 119 } 120 121 public int tagOfSOPClassUID() { 122 return tagOfSOPClassUID; 123 } 124 125 public int tagOfSOPInstanceUID() { 126 return tagOfSOPInstanceUID; 127 } 128 129 public boolean isRSP() { 130 return (commandField & 0x8000) != 0; 131 } 132 133 public boolean isRetrieveRQ() { 134 return this == C_GET_RQ || this == C_MOVE_RQ; 135 } 136 137 public boolean isRetrieveRSP() { 138 return this == C_GET_RSP || this == C_MOVE_RSP; 139 } 140 141 public boolean isCService() { 142 return (commandField & 0x100) == 0; 143 } 144 145 public int commandFieldOfRSP() { 146 return commandField | 0x8000; 147 } 148 149 public static Dimse valueOf(int commandField) { 150 switch(commandField) { 151 case 0x0001: 152 return C_STORE_RQ; 153 case 0x8001: 154 return C_STORE_RSP; 155 case 0x0010: 156 return C_GET_RQ; 157 case 0x8010: 158 return C_GET_RSP; 159 case 0x0020: 160 return C_FIND_RQ; 161 case 0x8020: 162 return C_FIND_RSP; 163 case 0x0021: 164 return C_MOVE_RQ; 165 case 0x8021: 166 return C_MOVE_RSP; 167 case 0x0030: 168 return C_ECHO_RQ; 169 case 0x8030: 170 return C_ECHO_RSP; 171 case 0x0100: 172 return N_EVENT_REPORT_RQ; 173 case 0x8100: 174 return N_EVENT_REPORT_RSP; 175 case 0x0110: 176 return N_GET_RQ; 177 case 0x8110: 178 return N_GET_RSP; 179 case 0x0120: 180 return N_SET_RQ; 181 case 0x8120: 182 return N_SET_RSP; 183 case 0x0130: 184 return N_ACTION_RQ; 185 case 0x8130: 186 return N_ACTION_RSP; 187 case 0x0140: 188 return N_CREATE_RQ; 189 case 0x8140: 190 return N_CREATE_RSP; 191 case 0x0150: 192 return N_DELETE_RQ; 193 case 0x8150: 194 return N_DELETE_RSP; 195 case 0x0FFF: 196 return C_CANCEL_RQ; 197 default: 198 throw new IllegalArgumentException("commandField: " + commandField); 199 } 200 } 201 202 public String toString(Attributes cmdAttrs, int pcid, String tsuid) { 203 StringBuilder sb = new StringBuilder(); 204 sb.append(cmdAttrs.getInt(tagOfMessageID, -1)).append(prompt).append(pcid); 205 switch (this) { 206 case C_STORE_RQ: 207 promptIntTo(cmdAttrs, ", prior=", Tag.Priority, sb); 208 promptMoveOriginatorTo(cmdAttrs, sb); 209 break; 210 case C_GET_RQ: 211 promptIntTo(cmdAttrs, ", prior=", Tag.Priority, sb); 212 promptAttributeIdentifierListTo(cmdAttrs, sb); 213 break; 214 case C_FIND_RQ: 215 case C_MOVE_RQ: 216 promptIntTo(cmdAttrs, ", prior=", Tag.Priority, sb); 217 break; 218 case C_GET_RSP: 219 case C_MOVE_RSP: 220 promptNumberOfSubOpsTo(cmdAttrs, sb); 221 break; 222 case N_EVENT_REPORT_RQ: 223 case N_EVENT_REPORT_RSP: 224 promptIntTo(cmdAttrs, ", eventID=", Tag.EventTypeID, sb); 225 break; 226 case N_ACTION_RQ: 227 case N_ACTION_RSP: 228 promptIntTo(cmdAttrs, ", actionID=", Tag.ActionTypeID, sb); 229 break; 230 } 231 if (isRSP()) { 232 sb.append(", status=") 233 .append(Integer.toHexString(cmdAttrs.getInt(Tag.Status, -1))) 234 .append('H'); 235 promptIntTo(cmdAttrs, ", errorID=", Tag.ErrorID, sb); 236 promptStringTo(cmdAttrs, ", errorComment=", Tag.ErrorComment, sb); 237 promptAttributeIdentifierListTo(cmdAttrs, sb); 238 } 239 promptUIDTo(cmdAttrs, " cuid=", tagOfSOPClassUID, sb); 240 promptUIDTo(cmdAttrs, " iuid=", tagOfSOPInstanceUID, sb); 241 promptUIDTo(" tsuid=", tsuid, sb); 242 return sb.toString(); 243 } 244 245 private static void promptIntTo(Attributes cmd, String name, int tag, 246 StringBuilder sb) { 247 int val = cmd.getInt(tag, 0); 248 if (val != 0 || cmd.containsValue(tag)) 249 sb.append(name).append(val); 250 } 251 252 private static void promptStringTo(Attributes cmd, String name, int tag, 253 StringBuilder sb) { 254 String s = cmd.getString(tag, null); 255 if (s != null) 256 sb.append(name).append(s); 257 } 258 259 private static void promptUIDTo(Attributes cmd, String name, int tag, 260 StringBuilder sb) { 261 if (tag != 0) { 262 String uid = cmd.getString(tag, null); 263 if (uid != null) 264 promptUIDTo(name, uid, sb); 265 } 266 } 267 268 private static void promptUIDTo(String name, String uid, StringBuilder sb) { 269 sb.append(StringUtils.LINE_SEPARATOR).append(name); 270 UIDUtils.promptTo(uid, sb); 271 } 272 273 private static void promptMoveOriginatorTo(Attributes cmd, StringBuilder sb) { 274 String aet = cmd.getString(Tag.MoveOriginatorApplicationEntityTitle, 275 null); 276 if (aet != null) 277 sb.append(StringUtils.LINE_SEPARATOR) 278 .append(" orig=") 279 .append(aet) 280 .append(" >> ") 281 .append(cmd.getInt(Tag.MoveOriginatorMessageID, -1)) 282 .append(":C-MOVE-RQ"); 283 } 284 285 private static void promptAttributeIdentifierListTo(Attributes cmd, 286 StringBuilder sb) { 287 int[] tags = cmd.getInts(Tag.AttributeIdentifierList); 288 if (tags == null) 289 return; 290 291 sb.append(StringUtils.LINE_SEPARATOR).append(" tags=["); 292 if (tags.length > 0) { 293 for (int tag : tags) 294 sb.append(TagUtils.toString(tag)).append(", "); 295 sb.setLength(sb.length()-2); 296 } 297 sb.append(']'); 298 } 299 300 private static void promptNumberOfSubOpsTo(Attributes cmd, StringBuilder sb) { 301 promptIntTo(cmd, ", remaining=", Tag.NumberOfRemainingSuboperations, sb); 302 promptIntTo(cmd, ", completed=", Tag.NumberOfCompletedSuboperations, sb); 303 promptIntTo(cmd, ", failed=", Tag.NumberOfFailedSuboperations, sb); 304 promptIntTo(cmd, ", warning=", Tag.NumberOfWarningSuboperations, sb); 305 } 306}