Hi, I'm trying to implement my own DcmSCP class to handle C-Store requests.
In handleIncomingCommand, I have to call DIMSE_storeProvider before calling sendStoreResponse. Otherwise the SCU stops with a "Connection reset by peer" message.
DIMSE_storeProvider needs an T_ASC_ASSOCIATION param, but m_assoc is private in DcmSCP.
How can I get the association from my inherited class?.
DIMSE_storeProvider's association parameter
Moderator: Moderator Team
-
- Posts: 347
- Joined: Mon, 2009-02-23, 19:57
-
- DCMTK Developer
- Posts: 2051
- Joined: Fri, 2004-11-05, 13:47
- Location: Oldenburg, Germany
- Contact:
Hi,
overwrite DcmSCP's function handleIncomingCommand and call in case of a DIMSE store packet your own handler.
For all others, you may call from your own handleIncomingCommand() implementation the orginal DcmSCP implementation (e.g. to handle the ECHO requests). Thus, call in the end of your function DcmSCP::handleIncomingComand(...).
Michael
overwrite DcmSCP's function handleIncomingCommand and call in case of a DIMSE store packet your own handler.
For all others, you may call from your own handleIncomingCommand() implementation the orginal DcmSCP implementation (e.g. to handle the ECHO requests). Thus, call in the end of your function DcmSCP::handleIncomingComand(...).
Michael
-
- Posts: 347
- Joined: Mon, 2009-02-23, 19:57
Michael, thanks for your answer.
As you can see in the comment in my code, DIMSE_storeProvider needs a T_ASC_ASSOCIATION pointer, how can I get it?. Is DIMSE_storeProvider really needed?.
I copied it from /dcmnet/apps/storescp.cc
This is what I get if I call storescu against my SCP:
Any hint?
I did exactly that. Here is my handleIncomingCommand:overwrite DcmSCP's function handleIncomingCommand and call in case of a DIMSE store packet your own handler.
Code: Select all
OFCondition DicomSCP::handleIncomingCommand(T_DIMSE_Message *incomingMsg,
const DcmPresentationContextInfo &presContextInfo)
{
OFCondition cond;
OFString tempStr;
T_ASC_PresentationContextID presID = presContextInfo.presentationContextID;
if( incomingMsg->CommandField == DIMSE_C_ECHO_RQ )
{
// Process C-ECHO request
cond = handleECHORequest( incomingMsg->msg.CEchoRQ, presID );
} else {
OFString tempStr;
T_DIMSE_C_StoreRSP response;
T_DIMSE_C_StoreRQ request = incomingMsg->msg.CStoreRQ;
DcmDataset *statusDetail = NULL;
char imageFileName[2048];
getFileName(imageFileName);
bzero((char*)&response, sizeof(response));
response.DimseStatus = STATUS_Success; /* assume */
response.MessageIDBeingRespondedTo = request.MessageID;
response.DataSetType = DIMSE_DATASET_NULL; /* always for C-STORE-RSP */
strcpy(response.AffectedSOPClassUID, request.AffectedSOPClassUID);
strcpy(response.AffectedSOPInstanceUID, request.AffectedSOPInstanceUID);
response.opts = (O_STORE_AFFECTEDSOPCLASSUID | O_STORE_AFFECTEDSOPINSTANCEUID);
if (request.opts & O_STORE_RQ_BLANK_PADDING) response.opts |= O_STORE_RSP_BLANK_PADDING;
if (dcmPeerRequiresExactUIDCopy.get()) response.opts |= O_STORE_PEER_REQUIRES_EXACT_UID_COPY;
// Dump debug information
DCMNET_INFO("C-STORE request");
DCMNET_INFO(DIMSE_dumpMessage(tempStr, request, DIMSE_INCOMING, NULL, presID));
DCMNET_INFO("Sending C-STORE Response");
// DIMSE_storeProvider needs a T_ASC_ASSOCIATION pointer
// how can I get it?
cond = DIMSE_storeProvider(m_assoc, presID, &request, imageFileName, true, NULL, NULL, NULL, DIMSE_BLOCKING, 0);
if(cond.bad())
DCMNET_INFO("Cannot storeProvider" << DimseCondition::dump(tempStr, cond));
else
DCMNET_INFO("Ok");
// Send an cstore response
OFCondition cond = sendSTOREResponse(presID, request, response, statusDetail);
if( cond.bad() )
DCMNET_INFO("Cannot send C-ECHO Response: " << DimseCondition::dump(tempStr, cond));
else
DCMNET_INFO("C-STORE Response successfully sent");
}
// return result
return cond;
}
I copied it from /dcmnet/apps/storescp.cc
This is what I get if I call storescu against my SCP:
Code: Select all
storescu -v -aet TEST -aec PACSERVER 127.0.0.1 5678 test.dcm
I: checking input files ...
I: Requesting Association
I: Association Accepted (Max Send PDV: 16372)
I: Sending file: test.dcm
I: Transfer Syntax: LittleEndianExplicit -> LittleEndianImplicit
I: Sending Store Request: MsgID 1, (CR)
XMIT: ....E: Store Failed, file: test.dcm:
E: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (Connection reset by peer) occurred in routine: writeDataPDU
E: Store SCU Failed: 0006:020e DIMSE Failed to send message
E: 0006:031d TCP I/O Error (Connection reset by peer) occurred in routine: writeDataPDU
I: Aborting Association
E: Association Abort Failed: 0006:031d TCP I/O Error (Broken pipe) occurred in routine: sendAbortTCP
-
- DCMTK Developer
- Posts: 2051
- Joined: Fri, 2004-11-05, 13:47
- Location: Oldenburg, Germany
- Contact:
Hi,
you should just not use DIMSE_storeProvider()! First, you receive the C-STORE command set which seems to work, right?
Then, the dataset should arrive, which you can receive by calling DcmSCP's function receiveDIMSEDataset(). For that you only need the presentation context and a pointer where the dataset should be stored. The last two parameters can be NULL.
You can then look into storescp (for example) how a received dataset can be stored to disk.
Michael
you should just not use DIMSE_storeProvider()! First, you receive the C-STORE command set which seems to work, right?
Then, the dataset should arrive, which you can receive by calling DcmSCP's function receiveDIMSEDataset(). For that you only need the presentation context and a pointer where the dataset should be stored. The last two parameters can be NULL.
You can then look into storescp (for example) how a received dataset can be stored to disk.
Michael
-
- DCMTK Developer
- Posts: 2051
- Joined: Fri, 2004-11-05, 13:47
- Location: Oldenburg, Germany
- Contact:
Who is online
Users browsing this forum: Bing [Bot] and 1 guest