int MLStorage::checkUID(const MString& uid) { int rtnValue = 0; MLogClient logClient; if (uid.length() > 64) { logClient.logTimeStamp(MLogClient::MLOG_ERROR, "MLStorage::checkUID detected UID > 64 characters"); rtnValue = 1; } char buf[128]; int len = 0; uid.safeExport(buf, sizeof(buf)); int i; for (i = 0; i < ::strlen(buf); i++) { char c = buf[i]; if (c == '.') continue; if (c >= '0' && c <= '9') continue; logClient.logTimeStamp(MLogClient::MLOG_ERROR, "MLStorage::checkUID detected a character not a digit or not a period"); rtnValue = 1; break; } return rtnValue; }
int MAMessenger::logMsg (MHL7Msg& message, const MString& event, char* hl7Type) { int logdirLen = mLogDir.size() + 1; int eventLen = event.size() + 1; char logdir[logdirLen]; char eventstr[eventLen]; event.safeExport(eventstr, eventLen); mLogDir.safeExport(logdir, logdirLen); sprintf (mStream, "%s/msg%d_%s.%s", logdir, ++gMsgNumber, eventstr, hl7Type); ofstream msgFile (mStream, ios::out | ios::trunc | ios::binary); { MLogClient logClient; char x[512]; sprintf(x, "Log %s message to: %s", hl7Type, mStream); logClient.log(MLogClient::MLOG_VERBOSE, "<no peer>", "MAMessenter::logMsg", __LINE__, x); } int length=0; message.exportToWire (mStream, mStreamSize, length); msgFile << mStream << endl; return 0; }
MHL7Factory::MHL7Factory(const MString& tablePath, const MString& version) { char path[1024]; char v[1024]; tablePath.safeExport(path, sizeof(path)); version.safeExport(v, sizeof(v)); mFlavor = ::HL7Init(path, v); if (mFlavor == 0) { cerr << "Could not initialize HL7 toolkit with " << tablePath << ":" << version << endl; exit(1); } }
MHL7Msg* MHL7Factory::produceACK(MHL7Msg& msg, const MString& prefix, const MString& ackCode, const MString& errorCondition) { HL7MSG* pMsg = ::HL7Alloca(mFlavor); if (pMsg == 0) { cerr << "Could not allocate HL7 Message" << endl; exit(1); } MHL7MessageControlID c; MString controlID = prefix + c.controlID(); char p[512]; controlID.safeExport(p, sizeof(p)); ::HL7InsSegm(pMsg, "MSH"); ::HL7PutFld(pMsg, "^~\\&", 2); ::HL7PutFld(pMsg, "ACK", 9); ::HL7PutFld(pMsg, p, 10); ::HL7PutFld(pMsg, "P", 11); // ::HL7PutFld(pMsg, "2.3.1", 12); ::HL7InsSegm(pMsg, "MSA"); HL7_COPY_MAP m[] = { { "MSH", 5, "MSH", 3}, // Sending Application { "MSH", 6, "MSH", 4}, // Sending Facility { "MSH", 3, "MSH", 5}, // Receiving Application { "MSH", 4, "MSH", 6}, // Receiving Application { "MSH", 10,"MSA", 2}, // Message Control ID { "MSH", 12,"MSH", 12}, // Version ID { "", 0, "", 0} }; this->copyFields(m, msg, pMsg); MHL7Msg* returnMsg = new MHL7Msg(pMsg); if (ackCode == "") { returnMsg->setValue("MSA", 1, 0, "AA"); } else { returnMsg->setValue("MSA", 1, 0, ackCode); } if (errorCondition != "") { returnMsg->setValue("MSA", 6, 0, errorCondition); } return returnMsg; }
MHL7Msg* MHL7Factory::produceRSPK22Baseline(MHL7Msg& msg, const MString& prefix) { HL7MSG* pMsg = ::HL7Alloca(mFlavor); if (pMsg == 0) { cerr << "Could not allocate HL7 Message" << endl; exit(1); } MHL7MessageControlID c; MString controlID = prefix + c.controlID(); char p[512]; controlID.safeExport(p, sizeof(p)); ::HL7InsSegm(pMsg, "MSH"); ::HL7PutFld(pMsg, "^~\\&", 2); ::HL7PutFld(pMsg, "RSP^K22", 9); ::HL7PutFld(pMsg, p, 10); ::HL7PutFld(pMsg, "P", 11); ::HL7InsSegm(pMsg, "MSA"); ::HL7PutFld(pMsg, "AA", 1); ::HL7InsSegm(pMsg, "QAK"); ::HL7InsSegm(pMsg, "QPD"); HL7_COPY_MAP m[] = { { "MSH", 5, "MSH", 3}, // Sending Application { "MSH", 6, "MSH", 4}, // Sending Facility { "MSH", 3, "MSH", 5}, // Receiving Application { "MSH", 4, "MSH", 6}, // Receiving Application { "MSH", 12,"MSH", 12}, // Version number { "MSH", 10,"MSA", 2}, // Message Control ID { "QPD", 1, "QPD", 1}, // Message Query Name { "QPD", 2, "QPD", 2}, // Query Tag { "QPD", 3, "QPD", 3}, // Person Identifier { "QPD", 8, "QPD", 8}, // What Domains Returned { "QPD", 2, "QAK", 1}, // Query Tag { "", 0, "", 0} }; this->copyFields(m, msg, pMsg); MHL7Msg* returnMsg = new MHL7Msg(pMsg); return returnMsg; }
int MConnector::connectUDP(const MString& host, int port, CTN_SOCKET& returnSocket) { MLogClient logClient; #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); int nOption = SO_SYNCHRONOUS_NONALERT; ::setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &nOption, sizeof(int)); #endif returnSocket = socket(AF_INET, SOCK_DGRAM, 0); if (returnSocket == CTN_BAD_SOCKET) { return 1; } struct sockaddr_in server; server.sin_family = AF_INET; char tmp[1024]=""; host.safeExport(tmp, sizeof tmp); struct hostent* hp = ::gethostbyname(tmp); if (hp == NULL) { return 1; } (void)::memcpy(&server.sin_addr, hp->h_addr, (unsigned long)hp->h_length); server.sin_port = (u_short)htons(port); if (::connect(returnSocket, (struct sockaddr*)& server, sizeof(server)) < 0) { #ifdef _WIN32 ::closesocket(returnSocket); #else ::close(returnSocket); #endif returnSocket = 0; return 1; } strstream x(tmp, sizeof(tmp)); x << "MConnector::connectUDP(MLogClient:connectUDP " << host << ", " << port << ", internal socket " << returnSocket << '\0'; logClient.log(MLogClient::MLOG_VERBOSE, tmp); return 0; }
int MAMessenger::logMsg (MHL7Msg& message, const MString& event, char* hl7Type) { int logdirLen = mLogDir.size() + 1; int eventLen = event.size() + 1; char logdir[logdirLen]; char eventstr[eventLen]; event.safeExport(eventstr, eventLen); mLogDir.safeExport(logdir, logdirLen); sprintf (mStream, "%s/msg%d_%s.%s", logdir, ++gMsgNumber, eventstr, hl7Type); ofstream msgFile (mStream, ios::out | ios::trunc | ios::binary); int length=0; message.exportToWire (mStream, mStreamSize, length); msgFile << mStream << endl; cout << "(Analysis Messenger) Logged " << hl7Type << " message to file.\n"; return 0; }
int MHL7Msg::saveAs(const MString& path) { if (mToolkitMsg == 0) return -1; char wire[10240]; char *ptr; size_t exportedLength = 0; ptr = wire; int status = ::HL7WriteMsg(mToolkitMsg, wire, sizeof(wire), &exportedLength); //MASSERT (status == HL7_OK); if (status != HL7_OK) { ptr = new char[102400]; if (ptr == 0) return -1; status = ::HL7WriteMsg(mToolkitMsg, ptr, 102400, &exportedLength); if (status != HL7_OK) { cout << "MHL7Msg::saveAs HL7 toolkit error: " << mToolkitMsg->ErrorMessage << endl; cout << " Unable to save HL7 Message in file: " << path << endl; delete []ptr; return -1; } } char p[1024]; path.safeExport(p, sizeof(p)); ofstream f(p, ios::out | ios::trunc | ios::binary); if (!f) return -1; f.write(ptr, exportedLength); return 0; }
int MConnector::connectTCP(const MString& host, int port, CTN_SOCKET& returnSocket) { #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); int nOption = SO_SYNCHRONOUS_NONALERT; ::setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &nOption, sizeof(int)); #endif returnSocket = socket(AF_INET, SOCK_STREAM, 0); if (returnSocket == CTN_BAD_SOCKET) { return 1; } struct sockaddr_in server; server.sin_family = AF_INET; char tmp[1024]; host.safeExport(tmp, sizeof tmp); struct hostent* hp = ::gethostbyname(tmp); if (hp == NULL) { return 1; } (void)::memcpy(&server.sin_addr, hp->h_addr, (unsigned long)hp->h_length); server.sin_port = (u_short)htons(port); if (::connect(returnSocket, (struct sockaddr*)& server, sizeof(server)) < 0) { #ifdef _WIN32 ::closesocket(returnSocket); #else ::close(returnSocket); #endif returnSocket = 0; return 1; } return 0; }
CONDITION MLMPPS::handleNSetDataSet(DUL_PRESENTATIONCONTEXT* ctx, MSG_N_SET_REQ** message, MSG_N_SET_RESP* response, DUL_ASSOCIATESERVICEPARAMETERS* params, MString& directoryName) { MLogClient logClient; logClient.log(MLogClient::MLOG_VERBOSE, params->callingAPTitle, "MLMPPS::handleNSetDataSet", __LINE__, "MPPS N-Set dataset received"); //::DCM_DumpElements(&(*message)->dataSet, 1); MFileOperations f; MString instanceUID((*message)->instanceUID); MString slash("/"); MString callingAPTitle(params->callingAPTitle); MString newDirectory = mStorageDir + slash + params->callingAPTitle + slash + instanceUID; f.createDirectory(newDirectory); f.createDirectory(newDirectory); MString s = f.uniqueFile(newDirectory, "set"); char* s1 = s.strData(); ::DCM_WriteFile(&(*message)->dataSet, DCM_ORDERLITTLEENDIAN, s1 ); logClient.log(MLogClient::MLOG_VERBOSE, params->callingAPTitle, "MLMPPS::handleNSetDataSet", __LINE__, "MPPS N-Set data set written to " + s); char mppsPath[512]; newDirectory.safeExport(mppsPath, sizeof(mppsPath)); strcat (mppsPath, "/mpps.dcm"); MPPSAssistant assistant; int rslt; rslt = assistant.validateNSetDataSet(mppsPath, s1); rslt = assistant.mergeNSetDataSet(mppsPath, s1); logClient.log(MLogClient::MLOG_VERBOSE, params->callingAPTitle, "MLMPPS::handleNSetDataSet", __LINE__, MString("MPPS status updated ") + mppsPath); delete [] s1; response->dataSetType = DCM_CMDDATANULL; response->conditionalFields = 0; ::strcpy(response->classUID, (*message)->classUID); ::strcpy(response->instanceUID, (*message)->instanceUID); response->status = MSG_K_SUCCESS; return SRV_NORMAL; }
void ppwlQuery (const char* inFile, const MString& logDir, int numBase, const char* dbName) { MDBPostProcMgr ppmgr(dbName); MLQuery queryHandler(ppmgr, logDir); MString queryLevel(""); //Build a GPWorkitem query object MDICOMWrapper w(inFile); DCM_OBJECT* q = w.getNativeObject(); MSG_C_FIND_REQ query = { MSG_K_C_FIND_REQ, 0, 0, DCM_CMDDATAIDENTIFIER, 0, NULL, "" }; strcpy(query.classUID, DICOM_SOPGPWORKLIST_FIND); query.identifier = q; MSG_C_FIND_REQ *queryMessage = &query; //Build a MWL response object MSG_C_FIND_RESP response = { MSG_K_C_FIND_RESP, 0, 0, DCM_CMDDATAIDENTIFIER, 0, NULL, "" }; strcpy(response.classUID, DICOM_SOPGPWORKLIST_FIND); queryHandler.handleCFindCommand (NULL, // presentation context &queryMessage, //c-find request message &response, // c-find response message NULL, // associate service parameters queryLevel); char filename[1024]; char logDirText[1024]; logDir.safeExport(logDirText, sizeof(logDirText)); int index; int count = queryHandler.objectVectorSize(); MDICOMDomainXlate xlate; for (index = 0; index < count; index++) { //cout << "--PostProc worklist query result " << index+1 << endl; MGPWorkitem workitem = queryHandler.getMGPWorkitemObject(index).workitem(); /* MActionItemVector aiv = queryHandler.getMMWLObjects(index).actionItemVector(); */ //cout << workitem << endl; DCM_OBJECT* r; ::DCM_CreateObject(&r, 0); xlate.translateDICOM(workitem, q, r); // Log query results to a file. The filename is built with 'numBase' if (response.dataSetType != DCM_CMDDATANULL) { sprintf(filename, "%s/msg%d_result.PPWL", logDirText, numBase+index); ::DCM_WriteFile(&r, DCM_ORDERLITTLEENDIAN, filename); ::DCM_CloseObject(&r); } } return; }
int evaluate(const MString& tstFile, const MString& stdFile, const MString& maskName, bool verbose, int logLevel, const MString& language) { char buf[1024]; maskName.safeExport(buf, sizeof(buf)); ifstream f(buf); if (!f) { cout << "ERR: Unable to open mask file: " << maskName << endl; ::exit(1); } MDICOMWrapper tstWrapper(tstFile); MDICOMWrapper stdWrapper(stdFile); MDICOMElementEval eval; int rtnValue = 0; while (f.getline(buf, sizeof(buf))) { if ((buf[0] == '#' || buf[0] == '\n' || buf[0] == '\0')) continue; int gggg = 0, eeee = 0; int seqGGGG = 0, seqEEEE = 0; char c = ' '; if (::sscanf(buf, "%x %x %x %x %c", &seqGGGG, &seqEEEE, &gggg, &eeee, &c) != 5) { seqGGGG = seqEEEE = 0; if (::sscanf(buf, "%x %x %c", &gggg, &eeee, &c) != 3) { cout << "ERR: Mask file lines should be <gggg eeee c>: " << buf << endl; cout << "ERR: or <gggg eeee gggg eeee c>" << buf << endl; ::exit(1); } } DCM_TAG seqTag = DCM_MAKETAG(seqGGGG, seqEEEE); DCM_TAG tag = DCM_MAKETAG(gggg, eeee); MString tstString; MString stdString; bool attributePresent = false; DCM_ELEMENT e; ::memset(&e, 0, sizeof(e)); e.tag = tag; ::DCM_LookupElement(&e); ::COND_PopCondition(TRUE); if (seqGGGG == 0x0000) { if (tstWrapper.attributePresent(tag)) attributePresent = true; tstString = tstWrapper.getString(tag); stdString = stdWrapper.getString(tag); } else { tstString = tstWrapper.getString(seqTag, tag); stdString = stdWrapper.getString(seqTag, tag); } if (logLevel >= 3) { if (e.representation == DCM_PN) { cout << "CTX: " << buf << ":" << tstString << endl; cout << "CTX: " << buf << ":" << stdString << endl; } else { cout << "CTX: " << buf << ":" << tstString << ":" << stdString << endl; } } switch (c) { case '=': if (seqGGGG == 0x0000) { int tmp = 0; tmp = eval.evalElement(logLevel, tstWrapper, stdWrapper, tag, language); if (tmp != 0) { rtnValue = 1; } } else { if (tstString != stdString) { cout << "ERR: C-Find response failed for an attribute: " << buf << endl; cout << "ERR: Your value: " << tstString << endl; cout << "ERR: Expected v: " << stdString << endl; rtnValue = 1; } } break; case 'O': if (tstString.size() == 0) { cout << "WARN: C-Find response examined for optional attribute: " << buf << endl; cout << "WARN: Your response did not contain the value or it was 0-length" << endl; cout << "WARN: This is merely an informative message." << endl; } break; case 'P': if (tstString.size() == 0) { cout << "ERR: C-Find response expected to find a value for: " << buf << endl; cout << "ERR: Your response did not contain the value or it was 0-length" << endl; rtnValue = 1; } break; case 'Z': // Test for present, but attribute can be zero length if (! attributePresent) { cout << "ERR: C-Find response expected to find a value for: " << buf << endl; cout << "ERR: Your response did not contain the value" << endl; rtnValue = 1; } break; default: break; } } return rtnValue; }
CONDITION MLMPPS::handleNCreateDataSet(DUL_PRESENTATIONCONTEXT* ctx, MSG_N_CREATE_REQ** message, MSG_N_CREATE_RESP* response, DUL_ASSOCIATESERVICEPARAMETERS* params, MString& directoryName) { MLogClient logClient; logClient.log(MLogClient::MLOG_VERBOSE, params->callingAPTitle, "MLMPPS::handleNCreateDataSetCommand", __LINE__, "MPPS N-Create dataset received"); //::DCM_DumpElements(&(*message)->dataSet, 1); MFileOperations f; MString instanceUID((*message)->instanceUID); if (instanceUID == "") { logClient.log(MLogClient::MLOG_ERROR, params->callingAPTitle, "MLMPPS::handleNCreateDataSetCommand", __LINE__, "Zero-length instance UID received with N-Create message"); } MString slash("/"); MString callingAPTitle(params->callingAPTitle); MString newDirectory = mStorageDir + slash + params->callingAPTitle + slash + instanceUID; f.createDirectory(newDirectory); MString s = f.uniqueFile(newDirectory, "crt"); char* s1 = s.strData(); ::DCM_WriteFile(&(*message)->dataSet, DCM_ORDERLITTLEENDIAN, s1 ); logClient.log(MLogClient::MLOG_CONVERSATION, params->callingAPTitle, "MLMPPS::handleNCreateDataSetCommand", __LINE__, "N-Create stored in " + s); delete [] s1; char mppsPath[512]; newDirectory.safeExport(mppsPath, sizeof(mppsPath)); strcat (mppsPath, "/mpps.dcm"); ::DCM_WriteFile(&(*message)->dataSet, DCM_ORDERLITTLEENDIAN, mppsPath); logClient.log(MLogClient::MLOG_CONVERSATION, params->callingAPTitle, "MLMPPS::handleNCreateDataSetCommand", __LINE__, MString("MPPS status stored in ") + mppsPath); response->dataSetType = DCM_CMDDATANULL; response->conditionalFields = 0; response->status = MSG_K_SUCCESS; return SRV_NORMAL; }