1 /*
2  *
3  *  Copyright (C) 1994-2018, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were partly developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *  For further copyrights, see the following paragraphs.
14  *
15  */
16 
17 /*
18 **  Copyright (C) 1993/1994, OFFIS, Oldenburg University and CERIUM
19 **
20 **  This software and supporting documentation were
21 **  developed by
22 **
23 **    Institut OFFIS
24 **    Bereich Kommunikationssysteme
25 **    Westerstr. 10-12
26 **    26121 Oldenburg, Germany
27 **
28 **    Fachbereich Informatik
29 **    Abteilung Prozessinformatik
30 **    Carl von Ossietzky Universitaet Oldenburg
31 **    Ammerlaender Heerstr. 114-118
32 **    26111 Oldenburg, Germany
33 **
34 **    CERIUM
35 **    Laboratoire SIM
36 **    Faculte de Medecine
37 **    2 Avenue du Pr. Leon Bernard
38 **    35043 Rennes Cedex, France
39 **
40 **  for CEN/TC251/WG4 as a contribution to the Radiological
41 **  Society of North America (RSNA) 1993 Digital Imaging and
42 **  Communications in Medicine (DICOM) Demonstration.
43 **
44 **  THIS SOFTWARE IS MADE AVAILABLE, AS IS, AND NEITHER OFFIS,
45 **  OLDENBURG UNIVERSITY NOR CERIUM MAKE ANY WARRANTY REGARDING
46 **  THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY OR
47 **  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER
48 **  DISEASES OR ITS CONFORMITY TO ANY SPECIFICATION.  THE
49 **  ENTIRE RISK AS TO QUALITY AND PERFORMANCE OF THE SOFTWARE
50 **  IS WITH THE USER.
51 **
52 **  Copyright of the software and supporting documentation
53 **  is, unless otherwise stated, jointly owned by OFFIS,
54 **  Oldenburg University and CERIUM and free access is hereby
55 **  granted as a license to use this software, copy this
56 **  software and prepare derivative works based upon this
57 **  software. However, any distribution of this software
58 **  source code or supporting documentation or derivative
59 **  works (source code and supporting documentation) must
60 **  include the three paragraphs of this copyright notice.
61 **
62 */
63 
64 /*
65 **
66 ** Author: Andrew Hewett                Created: 03-06-93
67 **
68 ** Module: dimecho
69 **
70 ** Purpose:
71 **      This file contains the routines which help with
72 **      verification services.
73 **
74 ** Module Prefix: DIMSE_
75 **
76 */
77 
78 
79 /*
80 ** Include Files
81 */
82 
83 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
84 
85 #define INCLUDE_CSTDLIB
86 #define INCLUDE_CSTDIO
87 #define INCLUDE_CSTRING
88 #include "dcmtk/ofstd/ofstdinc.h"
89 
90 #include "dcmtk/dcmnet/diutil.h"
91 #include "dcmtk/dcmnet/dimse.h"     /* always include the module header */
92 #include "dcmtk/dcmnet/cond.h"
93 
94 
95 OFCondition
DIMSE_echoUser(T_ASC_Association * assoc,DIC_US msgId,T_DIMSE_BlockingMode blockMode,int timeout,DIC_US * status,DcmDataset ** statusDetail)96 DIMSE_echoUser(
97     /* in */
98     T_ASC_Association *assoc, DIC_US msgId,
99     /* blocking info for response */
100     T_DIMSE_BlockingMode blockMode, int timeout,
101     /* out */
102     DIC_US *status, DcmDataset **statusDetail)
103 {
104     T_DIMSE_Message req, rsp;
105     T_ASC_PresentationContextID presID;
106     const char *sopClass;
107 
108     /* which SOP class  */
109     sopClass = UID_VerificationSOPClass;
110 
111     /* which presentation context should be used */
112     presID = ASC_findAcceptedPresentationContextID(assoc, sopClass);
113     if (presID == 0)
114     {
115         char buf[1024];
116         sprintf(buf, "DIMSE: No Presentation Context for: %s", sopClass);
117         return makeDcmnetCondition(DIMSEC_NOVALIDPRESENTATIONCONTEXTID, OF_error, buf);
118     }
119 
120     bzero((char*)&req, sizeof(req));
121     bzero((char*)&rsp, sizeof(rsp));
122 
123     req.CommandField = DIMSE_C_ECHO_RQ;
124     req.msg.CEchoRQ.MessageID = msgId;
125     OFStandard::strlcpy(req.msg.CEchoRQ.AffectedSOPClassUID,
126        sopClass, sizeof(req.msg.CEchoRQ.AffectedSOPClassUID));
127     req.msg.CEchoRQ.DataSetType = DIMSE_DATASET_NULL;
128 
129     OFCondition cond = DIMSE_sendMessageUsingMemoryData(assoc, presID, &req, NULL, NULL, NULL, NULL);
130     if (cond.bad()) return cond;
131 
132     /* receive response */
133     cond = DIMSE_receiveCommand(assoc, blockMode, timeout, &presID, &rsp, statusDetail);
134     if (cond.bad()) return cond;
135 
136     if (rsp.CommandField != DIMSE_C_ECHO_RSP)
137     {
138         char buf1[256];
139         sprintf(buf1, "DIMSE: Unexpected Response Command Field: 0x%x", (unsigned)rsp.CommandField);
140         return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
141     }
142 
143     if (rsp.msg.CEchoRSP.MessageIDBeingRespondedTo != msgId)
144     {
145         char buf1[256];
146         sprintf(buf1, "DIMSE: Unexpected Response MsgId: %d (expected: %d)", rsp.msg.CEchoRSP.MessageIDBeingRespondedTo, msgId);
147         return makeDcmnetCondition(DIMSEC_UNEXPECTEDRESPONSE, OF_error, buf1);
148     }
149 
150     *status = rsp.msg.CEchoRSP.DimseStatus;
151 
152     return EC_Normal;
153 }
154 
155 OFCondition
DIMSE_sendEchoResponse(T_ASC_Association * assoc,T_ASC_PresentationContextID presID,const T_DIMSE_C_EchoRQ * req,DIC_US status,DcmDataset * statusDetail)156 DIMSE_sendEchoResponse(T_ASC_Association * assoc,
157     T_ASC_PresentationContextID presID,
158     const T_DIMSE_C_EchoRQ *req, DIC_US status, DcmDataset *statusDetail)
159 {
160     T_DIMSE_Message rsp;
161 
162     bzero((char*)&rsp, sizeof(rsp));
163 
164     rsp.CommandField = DIMSE_C_ECHO_RSP;
165     rsp.msg.CEchoRSP.MessageIDBeingRespondedTo = req->MessageID;
166     OFStandard::strlcpy(rsp.msg.CEchoRSP.AffectedSOPClassUID,
167         req->AffectedSOPClassUID, sizeof(rsp.msg.CEchoRSP.AffectedSOPClassUID));
168     rsp.msg.CEchoRSP.opts = O_ECHO_AFFECTEDSOPCLASSUID;
169     rsp.msg.CEchoRSP.DataSetType = DIMSE_DATASET_NULL;
170     rsp.msg.CEchoRSP.DimseStatus = status;
171 
172     return DIMSE_sendMessageUsingMemoryData(assoc, presID, &rsp, statusDetail, NULL, NULL, NULL);
173 }
174