The most important feature that was added this build is the ability to receive N-EVENT-REPORT commands in the Requester class DCXREQ that represents the SCU.
The methods new methods CommitFilesAndWaitForResult and CommitInstancesAndWaitForResult in the requester class enable us to wait for the commit result on the same association that sent the request.
The following code shows how to build a Storage Commitment SCU with the new methods.
[Test]
public void CommitFilesAndWaitForResultOnSameAssoc()
{
bool status;
bool gotIt;
String fullpath = "SCMTEST";
Directory.CreateDirectory(fullpath);
CommonTestUtilities.CreateDummyImages(fullpath, 1, 1);
string succeededInstances;
string failedInstances;
string MyAETitle = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
DCXREQ r = new DCXREQ();
//r.OnCommitResult += new IDCXREQEvents_OnCommitResultEventHandler(a1.accepter_OnCommitResult);
r.OnFileSent += new IDCXREQEvents_OnFileSentEventHandler(OnFileSent);
r.Send(MyAETitle, IS_AE, IS_Host, IS_port, fullpath + "\\SER1\\IMG1", out succeededInstances, out failedInstances);
DCXOBJ obj = new DCXOBJ();
obj.openFile(fullpath + "\\SER1\\IMG1");
string sop_class_uid = obj.getElementByTag((int)DICOM_TAGS_ENUM.sopClassUid).Value.ToString();
string instance_uid = obj.getElementByTag((int)DICOM_TAGS_ENUM.sopInstanceUID).Value.ToString();
string transactionUID = r.CommitFilesAndWaitForResult(MyAETitle, IS_AE, IS_Host, IS_port, fullpath + "\\SER1\\IMG1",
5, out gotIt, out status, out succeededInstances, out failedInstances);
Directory.Delete(fullpath, true);
Assert.True(status, "Commit result is not success");
Assert.That(failedInstances.Length == 0);
Assert.AreEqual(succeededInstances, sop_class_uid + ";" + instance_uid + ";");
}
It's important to remember that the SCP may send the result on a separate association so unless you're absolutely sure about the way the SCP will behave, you should be prepared to receive the result with your accepter that can either run in a separate thread or you can set it up just for this purpose.
Here's a little code snippet that does exactly this. It prepares an accepter, then send the request and then wait for the result either to be send instantly in the same association or on a separate one. Note that this is a NUnit test function with a lot of verification code. To simply send the commit and wait for the result you should call the send and wait methods and if didn't get the result, wait on the accepter.
class SyncAccepter
{
public bool _gotIt = false;
public bool _status = false;
public string _transaction_uid;
public string _succeeded_instances;
public string _failed_instances;
public DCXACC accepter;
public string MyAETitle;
public void accepter_OnCommitResult(
bool status,
string transaction_uid,
string succeeded_instances,
string failed_instances)
{
_gotIt = true;
_status = status;
_transaction_uid = transaction_uid;
_succeeded_instances = succeeded_instances;
_failed_instances = failed_instances;
}
public SyncAccepter()
{
accepter = new DCXACC();
accepter.OnCommitResult += new IDCXACCEvents_OnCommitResultEventHandler(accepter_OnCommitResult);
MyAETitle = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
accepter.WaitForConnection(MyAETitle, 104, 0);
}
public bool WaitForIt(int timeout)
{
if (accepter.WaitForConnection(MyAETitle, 104, timeout))
return accepter.WaitForCommand(timeout);
else
return false;
}
}
[Test]
public void CommitFilesSameThread()
{
// Create test files
String fullpath = "SCMTEST";
Directory.CreateDirectory(fullpath);
CommonTestUtilities.CreateDummyImages(fullpath, 1, 1);
// Send test files
string MyAETitle = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
DCXREQ r = new DCXREQ();
string succeededInstances;
string failedInstances;
r.Send(MyAETitle, IS_AE, IS_Host, IS_port, fullpath + "\\SER1\\IMG1", out succeededInstances, out failedInstances);
Assert.That(failedInstances.Length == 0);
Assert.That(succeededInstances.Length > 0);
// Commit files and wait for result on separate association for 30 seconds
SyncAccepter a1 = new SyncAccepter();
r.CommitFiles(MyAETitle, IS_AE, IS_Host, IS_port, fullpath + "\\SER1\\IMG1");
a1.WaitForIt(30);
if (a1._gotIt)
{
// Check the result
Assert.True(a1._status, "Commit result is not success");
Assert.That(a1._failed_instances.Length == 0);
DCXOBJ obj = new DCXOBJ();
obj.openFile(fullpath + "\\SER1\\IMG1");
string sop_class_uid = obj.getElementByTag((int)DICOM_TAGS_ENUM.sopClassUid).Value.ToString();
string instance_uid = obj.getElementByTag((int)DICOM_TAGS_ENUM.sopInstanceUID).Value.ToString();
Assert.AreEqual(a1._succeeded_instances, sop_class_uid + ";" + instance_uid + ";");
}
else
Assert.Fail("Didn't get commit result");
/// Cleanup
Directory.Delete(fullpath, true);
}
}
195 | code | fixed | 1.0.1.6 | N-EVENT-REPORT Response for Storage Commit always return error to SCP | edit |
Returns status 0x00fe always. | |||||
196 | code | fixed | 1.0.1.6 | DCXOBJ TransferSyntax (set) method is reverted after saveFile | edit |
Do the following: 1) Change Transfer Syntax 2) Save file 3) Load the file 4) Check the meta header transfer syntax -> Same as before (1) Reason, xfer member of DCXOBJ doesn't change at (1) even that the object is changed. | |||||
197 | code | fixed | 1.0.1.6 | Can't get printer info if printer is only color | edit |
Reported by L&T (6.2) If printer negotiates only basic color print management, then GetPrinterInfo will not work. | |||||
198 | new | fixed | 1.0.1.6 | Get Storage Commit result N-EVENT-REPORT on requester association | edit |
SCM SCP may send N-EVENT-REPORT with SCM Result on same association that the SCM SCU initiated and sent the request N-ACTION. It may also send it on a new association that the SCP initiates. SCM SCU may disconnect association immediatly after recieving the N-ACTION Response from the SCP. This change allows both ways to be implemented in RZDCX by adding the CommitInstancesAndWaitForResult andCommitFilesAndWaitForResult. These methods send the request and then wait for the N-EVENT-REPORT | |||||
199 | code | fixed | 1.0.1.6 | get property SamplesPrePixel in DCXPrintImageBox may return wrong valu | edit |
Casting between int, enum and ushort may cause wrong interpratation of get value. Resolve by explicit cast in method. | |||||
200 | code | fixed | 1.0.1.6 | Get TM (Time) data element is not identical to set | edit |
Get time of 13:04:59.123 doesn't get expected result. See unit test.change control: return value is up to millisecond i.e. formated as hh:mm:dd.ttt |