MPPS SCU

21 篇文章 0 订阅
#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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值