#ifndef CMPPS_H
#define CMPPS_H
#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dcdatset.h"
#include "dcmtk/dcmdata/dcfilefo.h"
#include "dcmtk/dcmdata/dcdeftag.h"
#include "dcmtk/dcmnet/scu.h"
#include "DR_dataset.h"
#include "DR_dicom_node.h"
class MPPSScu:public DcmSCU
{
public:
MPPSScu(DR_Dicom_Node *node);
//发送mpps
void SendDcmMessage(mode::DR_Dataset *set,bool create);
public:
static DWORD WINAPI sendThreadProc(LPVOID lpParameter);
OFBool opt_secureConnection;
};
#endif
#include "stdafx.h"
#include "CMPPSScu.h"
#include "droclog.h"
#include "GlobleParemter.h"
#include "Tool.h"
#include "droc3.h"
#include "DR_dicom_node.h"
#include "dcmtk/config/osconfig.h"
#include "dcmtk/ofstd/ofconapp.h"
#include "dcmtk/dcmdata/dcdict.h"
#include "dcmtk/dcmdata/cmdlnarg.h"
#include "dcmtk/dcmdata/dcuid.h" /* for dcmtk version name */
#include "dcmtk/dcmdata/dcostrmz.h"
#define IN_PROGRESS "IN PROGRESS"
#define COMPLETED "COMPLETED"
#define DISCONTINUED "DISCONTINUED"
mode::DR_Dataset MPPSset;
std::string host;
int port;
std::string AEing;
std::string AECall;
int opt_acse_timeout;
OFBool opt_secureConnection;
int create=1;
//创建
void CteateCreateDataset();
//设置
void CteateSetDataset();
//取消
void CteateDiscontiunedSetDataset();
//发送消息
OFCondition SendMpps(DcmDataset *data,bool create);
T_DIMSE_BlockingMode blockMode=DIMSE_BLOCKING;
MPPSScu::MPPSScu(DR_Dicom_Node *node)
{
opt_secureConnection=OFFalse;
host=node->node_ip;
port=node->node_port;
AEing=node->node_calling_ae;
AECall=node->node_called_ae;
}
OFCondition SendMpps(DcmDataset *data,bool create)
{
OFString abstr=UID_ModalityPerformedProcedureStepSOPClass;
OFString tr=UID_LittleEndianExplicitTransferSyntax;
OFString temp_str;
T_ASC_Parameters *params;
DIC_NODENAME localHost;
DIC_NODENAME peerHost;
T_ASC_Association *assoc;
T_ASC_Network *net;
int opt_maxReceivePDULength=16383;
const char* tre[] ={
UID_LittleEndianImplicitTransferSyntax,
UID_LittleEndianExplicitTransferSyntax,
UID_BigEndianExplicitTransferSyntax,
UID_DeflatedExplicitVRLittleEndianTransferSyntax};
WSAData winSockData;
/* we need at least version 1.1 */
WORD winSockVersionNeeded = MAKEWORD( 1, 1 );
WSAStartup(winSockVersionNeeded, &winSockData);
OFCondition cond = ASC_initializeNetwork(NET_REQUESTOR, 0, opt_acse_timeout, &net);
if (cond.bad()) {
return cond;
}
cond = ASC_createAssociationParameters(¶ms, opt_maxReceivePDULength);
ASC_setAPTitles(params, AEing.c_str(), AECall.c_str(), NULL);
cond = ASC_setTransportLayerType(params, opt_secureConnection);
if (cond.bad()){
return cond;
}
gethostname(localHost, sizeof(localHost) - 1);
sprintf(peerHost, "%s:%d", host.c_str(), port);
ASC_setPresentationAddresses(params, localHost, peerHost);
const char *ptr=tr.c_str();
OFList<OFString> combinedSyntaxes;
for (int i=0;i<DIM_OF(tre);i++){
combinedSyntaxes.push_back(tre[i]);
}
const char **transferSyntaxes = new const char*[combinedSyntaxes.size()];
int transferSyntaxCount = 0;
OFListConstIterator(OFString) s_cur = combinedSyntaxes.begin();
OFListConstIterator(OFString) s_end = combinedSyntaxes.end();
while (s_cur != s_end) {
transferSyntaxes[transferSyntaxCount++] = (*s_cur).c_str();
++s_cur;
}
cond = ASC_addPresentationContext(params,1,
abstr.c_str(), transferSyntaxes, transferSyntaxCount, ASC_SC_ROLE_SCU);
//请求关联
DICOM_INFO( "Requesting Association");
cond = ASC_requestAssociation(net, params, &assoc);
if (cond.bad()) {
if (cond == DUL_ASSOCIATIONREJECTED) {
T_ASC_RejectParameters rej;
ASC_getRejectParameters(params, &rej);
DICOM_FATAL( "Association Rejected:" << OFendl << ASC_printRejectParameters(temp_str, &rej));
delete[] transferSyntaxes;
transferSyntaxes=0;
return cond;
} else {
DICOM_FATAL( "Association Request Failed: " << DimseCondition::dump(temp_str, cond));
delete[] transferSyntaxes;
transferSyntaxes=0;
return cond;
}
}
/* dump the connection parameters if in debug mode*/
DICOM_DEBUG( ASC_dumpConnectionParameters(temp_str, assoc));
/* count the presentation contexts which have been accepted by the SCP */
/* If there are none, finish the execution */
if (ASC_countAcceptedPresentationContexts(params) == 0) {
DICOM_FATAL( "No Acceptable Presentation Contexts");
delete[] transferSyntaxes;
transferSyntaxes=0;
return cond;
}
T_ASC_PresentationContextID presId;
presId = ASC_findAcceptedPresentationContextID(assoc, abstr.c_str());
//构建消息
T_DIMSE_Message req, rsp;
bzero((char*)&req, sizeof(req));
bzero((char*)&rsp, sizeof(rsp));
if (create){
T_DIMSE_N_CreateRQ n_creterq;
bzero(OFreinterpret_cast(char*, &n_creterq), sizeof(n_creterq));
strcpy(n_creterq.AffectedSOPClassUID, abstr.c_str());
strcpy(n_creterq.AffectedSOPInstanceUID, MPPSset.stu.instansuid.c_str());
n_creterq.opts=O_NCREATE_AFFECTEDSOPINSTANCEUID;
n_creterq.DataSetType = DIMSE_DATASET_PRESENT;
n_creterq.MessageID=1;
req.CommandField = DIMSE_N_CREATE_RQ;
req.msg.NCreateRQ = n_creterq;
}
else{
T_DIMSE_N_SetRQ n_setrq;
bzero(OFreinterpret_cast(char*, &n_setrq), sizeof(n_setrq));
strcpy(n_setrq.RequestedSOPClassUID, abstr.c_str());
strcpy(n_setrq.RequestedSOPInstanceUID, MPPSset.stu.instansuid.c_str());
n_setrq.DataSetType = DIMSE_DATASET_PRESENT;
n_setrq.MessageID=1;
req.CommandField = DIMSE_N_SET_RQ;
req.msg.NSetRQ = n_setrq;
}
DcmDataset statedata;
//发送消息
//Sleep(2000);
cond=DIMSE_sendMessageUsingMemoryData(assoc,presId,&req,&statedata,data,0,0);
if (cond.bad()){
DICOM_FATAL( "Send Message failed");
}
T_ASC_PresentationContextID thisPresId;
thisPresId = presId;
DcmDataset *statedata1;
T_DIMSE_Message response;
cond = DIMSE_receiveCommand(assoc,blockMode, opt_acse_timeout, &thisPresId, &response, &statedata1);
if (cond.bad())
return cond;
cond = ASC_destroyAssociation(&assoc);
if (cond.bad()) {
DICOM_FATAL( DimseCondition::dump(temp_str, cond));
}
/* drop the network, i.e. free memory of T_ASC_Network* structure. This call */
/* is the counterpart of ASC_initializeNetwork(...) which was called above. */
cond = ASC_dropNetwork(&net);
if (cond.bad()) {
DICOM_FATAL( DimseCondition::dump(temp_str, cond));
}
delete[] transferSyntaxes;
return EC_Normal;
}
void CteateCreateDataset()
{
GlobleParemter *globle = GlobleParemter::GetInstance();
CString modlity = globle->m_system_manage.modlity.c_str();
std::string storagesopid;
if (modlity==_T("DX")) //dx
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
else if (modlity==_T("CR"))//cr
{
storagesopid=UID_ComputedRadiographyImageStorage;
}
else if(modlity==_T("CT")) //
{
storagesopid=UID_CTImageStorage;
}
else if (modlity==_T("RF")) //胃肠
{
storagesopid=UID_XRayRadiofluoroscopicImageStorage ;
}
else if(modlity==_T("MR"))
{
storagesopid=UID_MRImageStorage ;
}
else if (modlity==_T("MG"))
{
storagesopid=UID_DigitalMammographyXRayImageStorageForProcessing ;
}
else
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
DcmDataset dcmset;
dcmset.putAndInsertString(DCM_SpecificCharacterSet,"ISO_IR 100");
dcmset.putAndInsertString(DCM_PatientID,MPPSset.pat.m_pid.c_str());
dcmset.putAndInsertString(DCM_PatientName,MPPSset.pat.m_real_name.c_str());
char *strmodlity=Tool::Convert1(modlity.GetBuffer());
dcmset.putAndInsertString(DCM_Modality,strmodlity);
delete []strmodlity;
OFDate data;data.setISOFormattedDate(OFString(MPPSset.pat.m_birthday.c_str()));
OFString datestr;
data.getISOFormattedDate(datestr,false);
dcmset.putAndInsertString(DCM_PatientBirthDate,datestr.c_str());
std::string sex=MPPSset.pat.m_sex;
std::string str_m,str_f,str_o;
str_m=gettext("male");
str_f=gettext("female");
str_o=gettext("other");
if (sex==str_m){
sex="M";
}
else if (sex==str_f){
sex="F";
}
else if (sex==str_o){
sex="O";
}
dcmset.putAndInsertString(DCM_PatientSex,sex.c_str());
dcmset.putAndInsertString(DCM_StudyID,MPPSset.stu.s_sid.c_str());
dcmset.putAndInsertString(DCM_PerformedStationName,MPPSset.stu.s_ae.c_str());
dcmset.putAndInsertString(DCM_PerformedProcedureStepStatus,IN_PROGRESS);
dcmset.putAndInsertString(DCM_PerformedProcedureStepID,MPPSset.stu.s_scheduled_ps.c_str());
dcmset.putAndInsertString(DCM_PerformedStationAETitle ,MPPSset.stu.s_ae.c_str());
DcmSequenceOfItems * ScheduledStepAttributesSequence=new DcmSequenceOfItems(DCM_ScheduledStepAttributesSequence);
DcmItem *item=new DcmItem;
ScheduledStepAttributesSequence->insert(item);
item->putAndInsertString(DCM_AccessionNumber,MPPSset.stu.s_accession_num.c_str());
item->putAndInsertString(DCM_RequestedProcedureDescription,MPPSset.stu.s_desc.c_str());
item->putAndInsertString(DCM_ScheduledProcedureStepDescription,MPPSset.stu.s_desc.c_str());
item->putAndInsertString(DCM_ScheduledProcedureStepID,MPPSset.stu.s_reserve1.c_str());
item->putAndInsertString(DCM_RequestedProcedureID,MPPSset.stu.s_reserve2.c_str());
item->putAndInsertString(DCM_StudyInstanceUID,MPPSset.stu.instansuid.c_str());
DcmSequenceOfItems * ReferencedStudySequence=new DcmSequenceOfItems(DCM_ReferencedStudySequence);
item->insert(ReferencedStudySequence);
DcmItem *item0=new DcmItem;
ReferencedStudySequence->insert(item0);
item0->putAndInsertString(DCM_ReferencedSOPClassUID,storagesopid.c_str());
item0->putAndInsertString(DCM_ReferencedSOPInstanceUID,MPPSset.stu.instansuid.c_str());
dcmset.insert(ScheduledStepAttributesSequence);
SendMpps(&dcmset,1);
}
void CteateSetDataset()
{
GlobleParemter *globle = GlobleParemter::GetInstance();
CString modlity = globle->m_system_manage.modlity.c_str();
std::string storagesopid;
if (modlity==_T("DX")) //dx
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
else if (modlity==_T("CR"))//cr
{
storagesopid=UID_ComputedRadiographyImageStorage;
}
else if(modlity==_T("CT")) //
{
storagesopid=UID_CTImageStorage;
}
else if (modlity==_T("RF")) //胃肠
{
storagesopid=UID_XRayRadiofluoroscopicImageStorage ;
}
else if(modlity==_T("MR"))
{
storagesopid=UID_MRImageStorage ;
}
else if (modlity==_T("MG"))
{
storagesopid=UID_DigitalMammographyXRayImageStorageForProcessing ;
}
else
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
DcmDataset dcmset;
CTime t;
t=CTime::GetCurrentTime();
char date[50]; memset(date,0,50);
char dtime[50];memset(dtime,0,50);
sprintf(date,"%04d%02d%02d",t.GetYear(),t.GetMonth(),t.GetDay());
sprintf(dtime,"%02d%02d%02d",t.GetHour(),t.GetMinute(),t.GetSecond());
//在数据库查询实例uid 用检查实例uid代替
dcmset.putAndInsertString(DCM_SpecificCharacterSet,"ISO_IR 100");
dcmset.putAndInsertString(DCM_SOPInstanceUID,MPPSset.stu.instansuid.c_str());
dcmset.putAndInsertString(DCM_PerformedProcedureStepEndDate,date);
dcmset.putAndInsertString(DCM_PerformedProcedureStepEndTime,dtime);
dcmset.putAndInsertString(DCM_PerformedProcedureStepStatus,COMPLETED);
DcmSequenceOfItems *ExposureDoseSequence=new DcmSequenceOfItems(DCM_ExposureDoseSequence);
dcmset.insert(ExposureDoseSequence);
DcmSequenceOfItems * PerformedSeriesSequence=new DcmSequenceOfItems(DCM_PerformedSeriesSequence);
dcmset.insert(PerformedSeriesSequence);
DAO_Series dao;
DAO_Protocol daopro;
DAO_Instance daoins;
std::vector<DR_Series> sers;
dao.SelectBySid(sers,MPPSset.stu.s_id);
int ls=sers.size();
for (int i=0;i<ls;i++){
DcmItem *sericeitem=new DcmItem;
PerformedSeriesSequence->insert(sericeitem);
sericeitem->putAndInsertString(DCM_SeriesDescription,sers[i].se_desc.c_str());
sericeitem->putAndInsertString(DCM_SeriesInstanceUID,sers[i].instansuid.c_str());
DR_Protocol pro;
daopro.SelectById(pro,sers[i].se_protocol_id);
sericeitem->putAndInsertString(DCM_ProtocolName,pro.protocol_name.c_str());
DcmSequenceOfItems *ReferencedImageSequence=new DcmSequenceOfItems(DCM_ReferencedImageSequence);
sericeitem->insert(ReferencedImageSequence);
std::vector<DR_Instance> inss;
daoins.Select(inss,sers[i].se_id);
int lsi=inss.size();
for (int j=0;j<lsi;j++){
DcmItem *Imageitem=new DcmItem;
ReferencedImageSequence->insert(Imageitem);
Imageitem->putAndInsertString(DCM_ReferencedSOPClassUID,storagesopid.c_str());
Imageitem->putAndInsertString(DCM_ReferencedSOPInstanceUID,inss[j].i_insiuid.c_str());
}
}
DICOM_INFO("MPPS>>"<<DcmObject::PrintHelper(dcmset));
SendMpps(&dcmset,0);
}
void CteateDiscontiunedSetDataset()
{
GlobleParemter *globle = GlobleParemter::GetInstance();
CString modlity = globle->m_system_manage.modlity.c_str();
std::string storagesopid;
if (modlity==_T("DX")) //dx
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
else if (modlity==_T("CR"))//cr
{
storagesopid=UID_ComputedRadiographyImageStorage;
}
else if(modlity==_T("CT")) //
{
storagesopid=UID_CTImageStorage;
}
else if (modlity==_T("RF")) //胃肠
{
storagesopid=UID_XRayRadiofluoroscopicImageStorage ;
}
else if(modlity==_T("MR"))
{
storagesopid=UID_MRImageStorage ;
}
else if (modlity==_T("MG"))
{
storagesopid=UID_DigitalMammographyXRayImageStorageForProcessing ;
}
else
{
storagesopid=UID_DigitalXRayImageStorageForPresentation;
}
DcmDataset dcmset;
CTime t;
t=CTime::GetCurrentTime();
char date[50]; memset(date,0,50);
char dtime[50];memset(dtime,0,50);
sprintf(date,"%04d%02d%02d",t.GetYear(),t.GetMonth(),t.GetDay());
sprintf(dtime,"%02d%02d%02d",t.GetHour(),t.GetMinute(),t.GetSecond());
//在数据库查询实例uid 用检查实例uid代替
dcmset.putAndInsertString(DCM_SpecificCharacterSet,"ISO_IR 100");
dcmset.putAndInsertString(DCM_SOPInstanceUID,MPPSset.stu.instansuid.c_str());
dcmset.putAndInsertString(DCM_PerformedProcedureStepEndDate,date);
dcmset.putAndInsertString(DCM_PerformedProcedureStepEndTime,dtime);
dcmset.putAndInsertString(DCM_PerformedProcedureStepStatus,DISCONTINUED);
DcmSequenceOfItems *ExposureDoseSequence=new DcmSequenceOfItems(DCM_ExposureDoseSequence);
dcmset.insert(ExposureDoseSequence);
DcmSequenceOfItems * PerformedSeriesSequence=new DcmSequenceOfItems(DCM_PerformedSeriesSequence);
dcmset.insert(PerformedSeriesSequence);
DAO_Series dao;
DAO_Protocol daopro;
DAO_Instance daoins;
std::vector<DR_Series> sers;
dao.SelectBySid(sers,MPPSset.stu.s_id);
int ls=sers.size();
for (int i=0;i<ls;i++){
DcmItem *sericeitem=new DcmItem;
PerformedSeriesSequence->insert(sericeitem);
sericeitem->putAndInsertString(DCM_SeriesDescription,sers[i].se_desc.c_str());
sericeitem->putAndInsertString(DCM_SeriesInstanceUID,sers[i].instansuid.c_str());
DR_Protocol pro;
daopro.SelectById(pro,sers[i].se_protocol_id);
sericeitem->putAndInsertString(DCM_ProtocolName,pro.protocol_name.c_str());
DcmSequenceOfItems *ReferencedImageSequence=new DcmSequenceOfItems(DCM_ReferencedImageSequence);
sericeitem->insert(ReferencedImageSequence);
std::vector<DR_Instance> inss;
daoins.Select(inss,sers[i].se_id);
int lsi=inss.size();
for (int j=0;j<lsi;j++){
DcmItem *Imageitem=new DcmItem;
ReferencedImageSequence->insert(Imageitem);
Imageitem->putAndInsertString(DCM_ReferencedSOPClassUID,storagesopid.c_str());
Imageitem->putAndInsertString(DCM_ReferencedSOPInstanceUID,inss[j].i_insiuid.c_str());
}
}
DICOM_INFO("MPPS>>"<<DcmObject::PrintHelper(dcmset));
SendMpps(&dcmset,0);
}
void MPPSScu::SendDcmMessage(mode::DR_Dataset *set0,bool create_)
{
MPPSset=*set0;
create=create_;
HANDLE th=CreateThread(NULL,0,sendThreadProc,0,0,NULL);
CloseHandle(th);
}
DWORD WINAPI MPPSScu::sendThreadProc(LPVOID lpParameter)
{
GlobleParemter *globle = GlobleParemter::GetInstance();
if (globle->m_system_manage.Ismpps==_T("1")){
DR_Dicom_Node node;
DAO_Dicom_Node dno;
dno.SelectByDef(node,"MPPS");
if (!node.node_called_ae.empty()){
host=node.node_ip;
port=node.node_port;
AEing=node.node_calling_ae;
AECall=node.node_called_ae;
if (create==1){
CteateCreateDataset();
}
else if(create==0){
CteateSetDataset();
}
else if (create==2){
CteateDiscontiunedSetDataset();
}
}
}
return 1;
}
//dicom协议交流群:107534874