Skip to content

Commit

Permalink
server loop fix
Browse files Browse the repository at this point in the history
  • Loading branch information
knopkem committed Mar 28, 2020
1 parent f8ba478 commit 4181ef0
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 50 deletions.
38 changes: 38 additions & 0 deletions examples/move.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ addon.startScp(JSON.stringify(
}
});


setTimeout(function() {
addon.moveScu(JSON.stringify(
{
Expand Down Expand Up @@ -53,4 +54,41 @@ setTimeout(function() {
console.log(result);
}
});


addon.moveScu(JSON.stringify(
{
"source": {
"aet": "IMEBRA",
"ip" : "127.0.0.1",
"port": "9999"
},
"target": {
"aet": "CONQUESTSRV1",
"ip" : "127.0.0.1",
"port": "5678"
},
"tags" : [
{
"key": "0020000D",
"value": "1.3.6.1.4.1.5962.99.1.2280943358.716200484.1363785608958.78.0",
},
{
"key": "00080052",
"value": "STUDY",
},
],
"destination" : "IMEBRA"
}
), (result) => {
try
{
console.log(JSON.parse(result));
}
catch {
console.log(result);
}
});


}, 3000);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dicom-dimse-native",
"version": "0.1.4",
"version": "0.1.5",
"description": "native addon using imebra dicom toolkit",
"main": "index.js",
"scripts": {
Expand Down
100 changes: 51 additions & 49 deletions src/ServerAsyncWorker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,67 +51,69 @@ void ServerAsyncWorker::Execute(const ExecutionProgress &progress)

imebra::TCPListener tcpListener(TCPPassiveAddress(in.source.ip, in.source.port));

// Wait until a connection arrives or terminate() is called on the tcpListener
imebra::TCPStream tcpStream(tcpListener.waitForConnection());

// Allocate a stream reader and a writer that use the TCP stream.
// If you need a more complex stream (e.g. a stream that uses your
// own services to send and receive data) then use a Pipe
imebra::StreamReader readSCU(tcpStream.getStreamInput());
imebra::StreamWriter writeSCU(tcpStream.getStreamOutput());

// Add all the abstract syntaxes and the supported transfer
// syntaxes for each abstract syntax (the pair abstract/transfer syntax is
// called "presentation context")
imebra::PresentationContexts presentationContexts;
std::vector<std::string> dcmLongSCUStorageSOPClassUIDs = ns::dcmLongSCUStorageSOPClassUIDs();
for (int j = 0; j < dcmLongSCUStorageSOPClassUIDs.size(); j++)
{
imebra::PresentationContext context(dcmLongSCUStorageSOPClassUIDs[j], true, true);
context.addTransferSyntax(imebra::uidImplicitVRLittleEndian_1_2_840_10008_1_2);
context.addTransferSyntax(imebra::uidExplicitVRLittleEndian_1_2_840_10008_1_2_1);
presentationContexts.addPresentationContext(context);
}

// The AssociationSCP constructor will negotiate the assocation
imebra::AssociationSCP scp(in.source.aet, 1, 1, presentationContexts, readSCU, writeSCU, 0, 10);

// The DIMSE service will use the negotiated association to send and receive
// DICOM commands
imebra::DimseService dimse(scp);

// Receive commands until the association is closed
for (;;)
{

try
// Wait until a connection arrives or terminate() is called on the tcpListener
imebra::TCPStream tcpStream(tcpListener.waitForConnection());

// Allocate a stream reader and a writer that use the TCP stream.
// If you need a more complex stream (e.g. a stream that uses your
// own services to send and receive data) then use a Pipe
imebra::StreamReader readSCU(tcpStream.getStreamInput());
imebra::StreamWriter writeSCU(tcpStream.getStreamOutput());

// Add all the abstract syntaxes and the supported transfer
// syntaxes for each abstract syntax (the pair abstract/transfer syntax is
// called "presentation context")
imebra::PresentationContexts presentationContexts;
std::vector<std::string> dcmLongSCUStorageSOPClassUIDs = ns::dcmLongSCUStorageSOPClassUIDs();
for (int j = 0; j < dcmLongSCUStorageSOPClassUIDs.size(); j++)
{
// receive a C-Store
imebra::CStoreCommand command(dimse.getCommand().getAsCStoreCommand());

// The store command has a payload. We can do something with it, or we can
// use the methods in CStoreCommand to get other data sent by the peer
imebra::DataSet payload = command.getPayloadDataSet();
imebra::PresentationContext context(dcmLongSCUStorageSOPClassUIDs[j], true, true);
context.addTransferSyntax(imebra::uidImplicitVRLittleEndian_1_2_840_10008_1_2);
context.addTransferSyntax(imebra::uidExplicitVRLittleEndian_1_2_840_10008_1_2_1);
presentationContexts.addPresentationContext(context);
}

// Do something with the payload
std::string sop = payload.getString(TagId(tagId_t::SOPInstanceUID_0008_0018), 0);
std::string study = payload.getString(TagId(tagId_t::StudyInstanceUID_0020_000D), 0);
std::experimental::filesystem::path p(in.storagePath + std::string("/") + study);
std::experimental::filesystem::create_directories(p);
imebra::CodecFactory::save(payload, p.string() + std::string("/") + sop + std::string(".dcm"), imebra::codecType_t::dicom);
// The AssociationSCP constructor will negotiate the assocation
imebra::AssociationSCP scp(in.source.aet, 1, 1, presentationContexts, readSCU, writeSCU, 0, 10);

std::string msg = ns::createJsonResponse(ns::PENDING, "storing: " + sop);
SendInfo(msg, progress);
// The DIMSE service will use the negotiated association to send and receive
// DICOM commands
imebra::DimseService dimse(scp);

// Send a response
dimse.sendCommandOrResponse(CStoreResponse(command, dimseStatusCode_t::success));
try
{
// Receive commands until the association is closed
for (;;)
{
// receive a C-Store
imebra::CStoreCommand command(dimse.getCommand().getAsCStoreCommand());

// The store command has a payload. We can do something with it, or we can
// use the methods in CStoreCommand to get other data sent by the peer
imebra::DataSet payload = command.getPayloadDataSet();

// Do something with the payload
std::string sop = payload.getString(TagId(tagId_t::SOPInstanceUID_0008_0018), 0);
std::string study = payload.getString(TagId(tagId_t::StudyInstanceUID_0020_000D), 0);
std::experimental::filesystem::path p(in.storagePath + std::string("/") + study);
std::experimental::filesystem::create_directories(p);
imebra::CodecFactory::save(payload, p.string() + std::string("/") + sop + std::string(".dcm"), imebra::codecType_t::dicom);

std::string msg = ns::createJsonResponse(ns::PENDING, "storing: " + sop);
SendInfo(msg, progress);

// Send a response
dimse.sendCommandOrResponse(CStoreResponse(command, dimseStatusCode_t::success));
}
}
catch (const StreamEOFError &e)
{
// The association has been closed, do not abort
SendInfo("assoc closed, reason: " + std::string(e.what()), progress, ns::FAILURE);
// SendInfo("assoc closed, reason: " + std::string(e.what()), progress, ns::FAILURE);
}
}

SendInfo("shutting down scp...", progress);
}

0 comments on commit 4181ef0

Please sign in to comment.