Exemple #1
0
static int
writePart10MetaHeader(int fd, DCM_FILE_META* fileMeta)
{
    DCM_OBJECT* obj = 0;
    char buffer[2048];

    CONDITION cond = DCM_CreateObject(&obj, 0);
    if (cond != DCM_NORMAL)
    {
        return -1;
    }

    cond = DCM_SetFileMeta(&obj, fileMeta);
    if (cond != DCM_NORMAL)
    {
        return -1;
    }

    cond = DCM_ExportStream(&obj, 
                            DCM_EXPLICITLITTLEENDIAN | DCM_PART10FILE,
                            buffer, sizeof(buffer), callbackFunction, &fd);
    if (cond != DCM_NORMAL)
    {
        return -1;
    }

    return 0;
}
Exemple #2
0
CONDITION
IAP_QueryToObject(Query * query, DCM_OBJECT ** object, char *SOPClass, int *elementCount)
{
    CONDITION					cond, returnCondition;
    int	        				index;
    long       					flag;
    static char    				queryLevelString[48] = "";	/* Initialize for AIX compiler bug */
    DCM_ELEMENT					queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), (void *) &queryLevelString[0]};
    static DCM_FLAGGED_ELEMENT 	localList[] = {
										{DCM_IDSOPINSTANCEUID, DCM_UI, "", 1, sizeof(q.Image.ImageUID), (void *) &q.Image.ImageUID[0], DB_K_QIMAGEUID, &q.Image.Query_Flag},
								};

    q = *query;
    *elementCount = 0;

    if (*object == NULL) {
    	cond = DCM_CreateObject(object, 0);
    	if (cond != DCM_NORMAL)	return COND_PushCondition(IAP_OBJECTCREATEFAILED, IAP_Message(IAP_OBJECTCREATEFAILED), "IAP_QueryToObject");
    }

    returnCondition = IAP_NORMAL;
    flag = q.QueryState & (DB_K_LEVELPAT | DB_K_LEVELSTUDY | DB_K_LEVELSERIES | DB_K_LEVELIMAGE);
    if (flag == 0){
    	returnCondition = COND_PushCondition(IAP_INCOMPLETEQUERY, "IAP_QueryToObject");
    }else{
    	for (index = 0; index < DIM_OF(levelMap); index++) {
    		if ((q.QueryState & levelMap[index].flag) != 0) {
    			(void) strcpy(queryLevelString, levelMap[index].queryLevel);
    			queryLevelElement.length = strlen(queryLevelElement.d.string);
    			cond = DCM_ModifyElements(object, &queryLevelElement, 1, NULL, 0, NULL);
    			if (cond != DCM_NORMAL) return cond;
    		}
    	}
    }


    flag = q.QueryState &
	(DB_K_CLASSPAT | DB_K_CLASSSTUDY | DB_K_CLASSPATSTUDY);
    if (flag == 0){
    	returnCondition = COND_PushCondition(IAP_INCOMPLETEQUERY, "");
    }else{
    	for (index = 0; index < DIM_OF(classMap); index++) {
    		if ((q.QueryState & classMap[index].flag) != 0) {
    			(void) strcpy(SOPClass, classMap[index].SOPClass);
    			cond = DCM_NORMAL;
    		}
    	}
    }

    cond = DCM_ModifyElements(object, NULL, 0, list, (int) DIM_OF(list), elementCount);
    if (cond != DCM_NORMAL)	return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_QueryToObject");

    cond = DCM_ModifyElements(object, NULL, 0, localList, (int) DIM_OF(localList), elementCount);
    if (cond != DCM_NORMAL)	return COND_PushCondition(IAP_OBJECTACCESSFAILED, IAP_Message(IAP_OBJECTACCESSFAILED), "IAP_QueryToObject");

    return returnCondition;
}
Exemple #3
0
/*
** SRV_NEventReportResponse
**
** Purpose:
**	SRV_NEventReportResponse assists an application that wants to be an SCU
**	of a number of SOP classes. When an application receives an
**	N-EVENT_REPORT request message, it calls this function with the
**	N-EVENT_REPORT request and other parameters. SRV_NEventReportResponse
**	checks the caller's parameters and calls the user's callback function.
**	In the callback	function, the caller fills in the parameters of the
**	N-EVENT_REPORT response	message and then returns to the SRV function.
**
**	After the callback function returns, SRV_NEventReportResponse
**	constructs a N-EVENT_REPORT Response message and sends it to the peer
**	application which sent the request message.
**
**	The arguments to the callback function are:
**		MSG_N_EVENT_REPORT_REQ	*eventRequest
**		MSG_N_EVENT_REPORT_RESP	*eventResponse
**		void			*eventCtx
**		DUL_PRESENTATIONCONTEXT	*pc
**
**	The first two arguments are MSG structures that contain the
**	N-EVENT_REPORT Request and N-EVENT_REPORT Response messages
**	respectively. The third argument is the caller's context variable that
**	is passed to SRV_NEventReportResponse.  The presentation context is
**	the one negotiated for this SOP class.
**
**	The callback function should return SRV_NORMAL. Any other return
**	value will cause the SRV facility to abort the Association.
**
** Parameter Dictionary:
**	association	The key which is used for transmitting the
**			N-EVENT_REPORT response.
**	presentationCtx	Pointer to presentation context to be used when sending
**			the N-EVENT_REPORT response.
**	eventRequest	Pointer to the structure with the N-EVENT_REPORT request
**			parameters which was received by the application.
**	eventResponse	Pointer to structure in the caller's area which will be
**			filled with the parameters of the N-EVENT_REPORT
**			response command. After the parameters are filled in,
**			the N-EVENT_REPORT response is sent to the peer
**			application which sent the request.
**	eventCallback	Address of user callback function to be called
**			with the N-EVENT_REPORT response from SCU.
**	eventCtx	Pointer to user context information which will be
**			passed to the callback function. Caller uses this
**			variable to contain any context required for the
**			callback function.
**      dirName         Name of directory where files may be created.
**
**
** Return Values:
**
**	SRV_CALLBACKABORTEDSERVICE
**	SRV_ILLEGALPARAMETER
**	SRV_NOCALLBACK
**	SRV_NORMAL
**	SRV_OBJECTBUILDFAILED
**	SRV_RESPONSEFAILED
**
** Algorithm:
**	Receive a data set, if any, from the peer application
**	Invoke the callback function, if it exists.
**	Build a command and send it to the requesting peer application.
**	Send a data set, if any, to the peer application.
**
** Notes:
**	The callback function is responsible for explicitly setting the
**	following fields in the N-EVENT_REPORT request message:
**
**	type
**	messageIDRespondedTo
**	classUID
**	dataSetType
**	instanceUID
**	status
**
*/
CONDITION
SRV_NEventReportResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * presentationCtx, MSG_N_EVENT_REPORT_REQ ** eventRequest,
						 MSG_N_EVENT_REPORT_RESP * eventResponse, SRV_N_EVENTREPORT_RESP_CALLBACK * eventCallback, void *eventCtx, char *dirName)
{
    CONDITION	cond;
    DCM_OBJECT	* responseObject;

    eventResponse->status = MSG_K_SUCCESS;
    if (eventCallback == NULL) {
    	(void) MSG_Free((void **) eventRequest);
    	return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_NEventReportResponse");
    }
    if ((*eventRequest)->dataSetType != DCM_CMDDATANULL){
    	cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK, 0, dirName, &(*eventRequest)->dataSet);
    	if (cond != SRV_NORMAL){
    		(void) MSG_Free((void **) eventRequest);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse");
    	}
    }
    eventResponse->dataSetType = DCM_CMDDATANULL;

    cond = DCM_CreateObject(&eventResponse->dataSet, 0);
    if (cond != DCM_NORMAL) {
    	(void) MSG_Free((void **) eventRequest);
    	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse");
    }

    cond = eventCallback(*eventRequest, eventResponse, eventCtx, presentationCtx);
    (void) MSG_Free((void **) eventRequest);
    if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NEventReportRequest");

    if (eventResponse->type != MSG_K_N_EVENT_REPORT_RESP)
    	return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-EVENT_REPORT Response", "SRV_NEventReportResponse");

    cond = MSG_BuildCommand(eventResponse, &responseObject);
    if (cond != MSG_NORMAL) {
    	(void) DCM_CloseObject(&eventResponse->dataSet);
    	return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "N-EVENT_REPORT Response", "SRV_NEventReportResponse");
    }

    cond = SRV_SendCommand(association, presentationCtx, &responseObject);
    (void) DCM_CloseObject(&responseObject);
    if (cond != SRV_NORMAL) {
    	(void) DCM_CloseObject(&eventResponse->dataSet);
    	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse");
    }
    if (eventResponse->dataSetType != DCM_CMDDATANULL){ /* application specific event reply exists */
    	cond = SRV_SendDataSet(association, presentationCtx, &eventResponse->dataSet, NULL, NULL, 0);
    	if (cond != SRV_NORMAL){
    		(void) DCM_CloseObject(&eventResponse->dataSet);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_NEventReportResponse");
    	}
    }
    (void) DCM_CloseObject(&eventResponse->dataSet);
    return SRV_NORMAL;
}
Exemple #4
0
static void handleStudyQueries(DUL_ASSOCIATIONKEY** association,
			       DUL_ASSOCIATESERVICEPARAMETERS* params,
			       MSG_C_FIND_REQ* patientRequest,
			       LST_HEAD* patientList,
			       const char* queryLevel)
{
  ITEM* item;
  CONDITION cond;
  MSG_C_FIND_RESP response;

  item = (ITEM*)LST_Head(&patientList);
  (void)LST_Position(&patientList, item);
  while (item != 0) {
    char* patientName;
    char* patientID;
    char* charSet;
    MSG_C_FIND_REQ studyRequest;
    DCM_OBJECT* q;

    patientName = getString(item->obj, DCM_PATNAME);
    patientID = getString(item->obj, DCM_PATID);
    charSet = getString(patientRequest->identifier, DCM_IDSPECIFICCHARACTER);

    printf("%s %s\n", patientID, patientName);

    studyRequest = *patientRequest;
    studyRequest.identifier = 0;
    DCM_CreateObject(&q, 0);

    addString(q, DCM_PATID, patientID);
    addString(q, DCM_IDSPECIFICCHARACTER, charSet);
    addString(q, DCM_IDQUERYLEVEL, "STUDY");
    addString(q, DCM_RELSTUDYINSTANCEUID, "");
    addString(q, DCM_IDSTUDYDATE, "");
    addString(q, DCM_IDSTUDYTIME, "");
    addString(q, DCM_IDACCESSIONNUMBER, "");
    addString(q, DCM_IDSTUDYDESCRIPTION, "");

    studyRequest.identifier = q;
    studyRequest.messageID = SRV_MessageIDOut();

    item->lst = LST_Create();

    cond = SRV_CFindRequest(association, params,
			    &studyRequest, &response,
			    queryCallback, item->lst, "");
    if (!(CTN_SUCCESS(cond))) {
      (void) printf("Verification Request unsuccessful\n");
      COND_DumpConditions();
    } else {

    }

    item = LST_Next(&patientList);
  }
}
Exemple #5
0
DCM_OBJECT *
createQueryObject(const char *fileName)
{
    DCM_OBJECT *obj;
    CONDITION cond;
    DCM_ELEMENT e;
    char txt[1024] = "";

    int group = 0;
    int element = 0;
    char textValue[1024];

    if (fileName != NULL) {
	cond = DCM_OpenFile(fileName, DCM_ORDERLITTLEENDIAN, &obj);
	if (cond != DCM_NORMAL) {
	    COND_DumpConditions();
	    exit(1);
	}
	return obj;
    }
    cond = DCM_CreateObject(&obj, 0);
    if (cond != DCM_NORMAL) {
	COND_DumpConditions();
	exit(1);
    }
    while (fgets(txt, sizeof(txt), stdin) != NULL) {
	if (txt[0] == '#' || txt[0] == '\0')
	    continue;
	if (txt[0] == '\n' || txt[0] == '\r')
	    continue;

	if (sscanf(txt, "%x %x %[^\n]", &group, &element, textValue) != 3)
	    continue;

	e.tag = DCM_MAKETAG(group, element);
	DCM_LookupElement(&e);
	if (strncmp(textValue, "#", 1) == 0) {
	    e.length = 0;
	    e.d.string = NULL;
	} else {
	    e.length = strlen(textValue);
	    e.d.string = textValue;
	}

	cond = DCM_AddElement(&obj, &e);
	if (cond != DCM_NORMAL) {
	    COND_DumpConditions();
	    exit(1);
	}
    }

    return obj;
}
Exemple #6
0
CONDITION
IAP_InstanceArraytoElement(char *SOPArray, size_t SOPSpacing,
	      char *UIDArray, size_t UIDSpacing, int count, DCM_ELEMENT * e)
{
    CONDITION
	cond;
    DCM_ELEMENT
	classElement = {
	DCM_IDREFERENCEDSOPCLASSUID, DCM_UI, "", 1, 0, NULL
    },
	uidElement = {
	DCM_IDREFERENCEDSOPINSTUID, DCM_UI, "", 1, 0, NULL
    };
    DCM_OBJECT
	* object;
    DCM_SEQUENCE_ITEM
	* item;

    e->d.sq = LST_Create();
    if (e->d.sq == NULL)
	return 0;		/* repair */

    while (count-- > 0) {
	item = malloc(sizeof(*item));
	if (item == NULL)
	    return 0;		/* repair */
	cond = DCM_CreateObject(&item->object);
	if (cond != DCM_NORMAL)
	    return 0;		/* repair */
	classElement.d.string = SOPArray;
	classElement.length = strlen(SOPArray);
	cond = DCM_AddElement(&item->object, &classElement);
	if (cond != DCM_NORMAL)
	    return 0;		/* repair */
	uidElement.d.string = UIDArray;
	uidElement.length = strlen(UIDArray);
	cond = DCM_AddElement(&item->object, &uidElement);
	if (cond != DCM_NORMAL)
	    return 0;		/* repair */

	cond = LST_Enqueue(&e->d.sq, item);
	if (cond != LST_NORMAL)
	    return 0;		/* repair */

	SOPArray += SOPSpacing;
	UIDArray += UIDSpacing;
    }
    return HAP_NORMAL;
}
Exemple #7
0
CONDITION
MSGPRV_BuildObject(DCM_OBJECT ** object, DCM_ELEMENT * required, int requiredCount, DCM_FLAGGED_ELEMENT * conditional, int conditionalCount)
{
    int	        	index;
    CONDITION		cond;
    DCM_ELEMENT		e;

    cond = DCM_CreateObject(object);
    if (cond != DCM_NORMAL)	return COND_PushCondition(0, "");	/* repair */

    cond = DCM_ModifyElements(object, required, requiredCount, conditional, conditionalCount, NULL);
    if (cond != DCM_NORMAL)	return COND_PushCondition(0, "");	/* repair */

    return MSG_NORMAL;
}
Exemple #8
0
CONDITION
SRV_CGetResponse(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, DUL_PRESENTATIONCONTEXT * getPresentationCtx,
				 MSG_C_GET_REQ ** getRequest, MSG_C_GET_RESP * getResponse, SRV_C_GET_RESP_CALLBACK * getCallback, void *getCtx, char *dirName)
{
    int      		flag, responseCount = 0;
    U32				l;
    char        	queryLevelString[48] = "";	/* Initialization for AIX compiler */
    CONDITION		cond, rtnCond = SRV_NORMAL;
    DCM_OBJECT		* responseObject;	/* get response object */
    void       		*ctx;
    DCM_ELEMENT		queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), NULL};
    static char 	*allowedQueryLevels[] = {
							DCM_QUERYLEVELPATIENT,
							DCM_QUERYLEVELSTUDY,
							DCM_QUERYLEVELSERIES,
							DCM_QUERYLEVELIMAGE};
    MSG_STATUS_DESCRIPTION	statusDescription;
    char pendingMsg[] = "\
In SRV_CGetResponse, the response message returned by your callback has \n\
a status of pending and data set that is not null.\n";
    MSG_TYPE		messageType;
    void	       *message;
    DUL_PRESENTATIONCONTEXTID	ctxID;
    MSG_C_STORE_REQ				storeRequest;
    char				        classUID[DICOM_UI_LENGTH + 1];

    queryLevelElement.d.string = queryLevelString;

    if (getCallback == NULL) {
    	(void) MSG_Free((void **) getRequest);
    	return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CGetResponse");
    }
    if (getResponse->type != MSG_K_C_GET_RESP) {
    	(void) MSG_Free((void **) getRequest);
    	return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "GET Request", "SRV_CGetResponse");
    }
    (void) strcpy(classUID, (*getRequest)->classUID);

    cond = DCM_CreateObject(&getResponse->identifier, 0);
    if (cond != DCM_NORMAL)	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");

    cond = SRV_ReceiveDataSet(association, getPresentationCtx, DUL_BLOCK, 0, dirName, &(*getRequest)->identifier);
    if (PRVSRV_debug && (cond == SRV_NORMAL)) (void) DCM_DumpElements(&(*getRequest)->identifier, 0);

    if (cond != SRV_NORMAL) {
    	(void) MSG_Free((void **) getRequest);
    	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    }
    ctx = NULL;

    cond = DCM_GetElementValue(&(*getRequest)->identifier, &queryLevelElement, &l, &ctx);
    if (cond != DCM_NORMAL) {
    	(void) MSG_Free((void **) getRequest);
    	(void) COND_PushCondition(SRV_QUERYLEVELATTRIBUTEMISSING, SRV_Message(SRV_QUERYLEVELATTRIBUTEMISSING), "SRV_CGetResponse");
    	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    }
    queryLevelString[l] = '\0';
    if (queryLevelString[l - 1] == ' ')	queryLevelString[l - 1] = '\0';

    for (flag = 0, l = 0; l < DIM_OF(allowedQueryLevels) && !flag; l++){
    	if (strcmp(queryLevelString, allowedQueryLevels[l]) == 0) flag = 1;
    }
    if (!flag) {
    	(void) MSG_Free((void **) getRequest);
    	(void) COND_PushCondition(SRV_ILLEGALQUERYLEVELATTRIBUTE, SRV_Message(SRV_ILLEGALQUERYLEVELATTRIBUTE), queryLevelString, "SRV_CGetResponse");
    	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    }
    getResponse->messageIDRespondedTo = (*getRequest)->messageID;
    getResponse->conditionalFields = 0;
    getResponse->remainingSubOperations = 0;
    getResponse->completedSubOperations = 0;
    getResponse->failedSubOperations = 0;
    getResponse->warningSubOperations = 0;

    /*
     * Fill up the Store request and let the callback routine do the matching
     * and fill the rest of the fields
     */
    storeRequest.type = MSG_K_C_STORE_REQ;
    storeRequest.conditionalFields = 0;
    storeRequest.messageID = SRV_MessageIDOut();
    storeRequest.priority = 0;
    storeRequest.moveMessageID = (*getRequest)->messageID;

    /*
     * We invoke the callback for the first time without any StoreResponse so
     * that the callback can deal with the query and fill the Store Request
     * message and the GET response message. We also pass responseCount as 0
     * when we invoke the callback for the first time
     */
    cond = getCallback(*getRequest, getResponse, &storeRequest, NULL, 0, getPresentationCtx->abstractSyntax, queryLevelString, getCtx);
    if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose");

    if (storeRequest.dataSetType != DCM_CMDDATANULL) {
    	/* Send a Store Request */
    	cond = sendStoreRequest(association, params, &storeRequest);
    	if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED),"sendStoreRequest", "SRV_CGetResponse");
	}else{
		/*
		 * No images are to be transferred as the query may have been
		 * unsuccessful in the call back routine. We expect the callback
		 * routine to have supplied the appropriate values for the various
		 * fields of the getResponse message.
		 *
		 * Send the CGetResponse Message and return from the routine
		 */
		cond = MSG_BuildCommand(getResponse, &responseObject);
		if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "getResponse", "SRV_CGetResponse");

		cond = SRV_SendCommand(association, getPresentationCtx, &responseObject);
		if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED),"SRV_SendCommand", "SRV_CGetResponse");

		if (getResponse->dataSetType != DCM_CMDDATANULL) {
			cond = SRV_SendDataSet(association, getPresentationCtx, &getResponse->identifier, NULL, NULL, 0);
			if (cond != SRV_NORMAL) return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "SRV_SendDataSet", "SRV_CGetResponse");
		}
		return SRV_NORMAL;
    }
    flag = 0;
    while (!flag) {
    	/*
    	 * Now wait for incoming Store Responses or a Cancel Request. If it
    	 * is a Store Response, invoke the callback routine, with the Store
    	 * Response. The callback will update the Get Response message
    	 * accordingly and also fill the Store Request message if any more
    	 * requests are to be made
    	 */
    	cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, NULL, &messageType, (void **) &message);
    	if (cond != SRV_NORMAL) return COND_PushCondition(SRV_RECEIVEFAILED, SRV_Message(SRV_RECEIVEFAILED), "SRV_CGetResponse");

    	switch (messageType) {
			case MSG_K_C_CANCEL_REQ:
											rtnCond = SRV_OPERATIONCANCELLED;
											getResponse->status = MSG_K_CANCEL;
											(void) MSG_Free(&message);

											cond = getCallback(*getRequest, getResponse, NULL, NULL, responseCount, getPresentationCtx->abstractSyntax, queryLevelString, getCtx);
											if (cond != SRV_NORMAL) return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose");

											getResponse->messageIDRespondedTo = (*getRequest)->messageID;
											break;
			case MSG_K_C_STORE_RESP:
											responseCount++;
											getResponse->dataSetType = DCM_CMDDATANULL;
											getResponse->status = 0xffff;

											/*
											 * Fill up the Store request and let the callback routine do the
											 * matching and fill the rest of the fields
											 */
											storeRequest.type = MSG_K_C_STORE_REQ;
											storeRequest.conditionalFields = 0;
											storeRequest.messageID = SRV_MessageIDOut();
											storeRequest.priority = 0;
											storeRequest.moveMessageID = (*getRequest)->messageID;
											cond = getCallback(*getRequest, getResponse, &storeRequest, (MSG_C_STORE_RESP *) message, responseCount,
															   getPresentationCtx->abstractSyntax, queryLevelString, getCtx);
											if (cond != SRV_NORMAL)
												return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CGetRespose");

											if (storeRequest.dataSetType != DCM_CMDDATANULL) {
												/* make the next store request */
												cond = sendStoreRequest(association, params, &storeRequest);
												if (cond != SRV_NORMAL)
													return COND_PushCondition(SRV_SENDFAILED, SRV_Message(SRV_SENDFAILED), "sendStoreRequest", "SRV_CGetResponse");
											}
											break;
			default:
											break;
    	}

    	if (cond == SRV_NORMAL) {
    		cond = MSG_StatusLookup(getResponse->status, MSG_K_C_GET_RESP, &statusDescription);
    		if (cond != MSG_NORMAL)	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");

    		if (statusDescription.statusClass != MSG_K_CLASS_PENDING) flag = 1;

    		/* Consistency check */
    		if ((statusDescription.statusClass == MSG_K_CLASS_PENDING) && (getResponse->dataSetType != DCM_CMDDATANULL)) {

    			if (PRVSRV_debug) fprintf(DEBUG_DEVICE, pendingMsg);
    			rtnCond = COND_PushCondition(SRV_SUSPICIOUSRESPONSE, SRV_Message(SRV_SUSPICIOUSRESPONSE), "C-GET", "pending", "not null", "SRV_CGetResponse");
    		}
    	}else{
    		flag = 1;
    	}

    	strcpy(getResponse->classUID, classUID);
    	getResponse->conditionalFields |= MSG_K_C_GETRESP_CLASSUID;

    	cond = MSG_BuildCommand(getResponse, &responseObject);
    	if (cond != MSG_NORMAL) {
    		(void) MSG_Free((void **) getRequest);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    	}

    	cond = SRV_SendCommand(association, getPresentationCtx, &responseObject);
    	if (cond != SRV_NORMAL) {
    		(void) MSG_Free((void **) getRequest);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    	}

    	if (getResponse->dataSetType != DCM_CMDDATANULL) {
    		cond = SRV_SendDataSet(association, getPresentationCtx, &getResponse->identifier, NULL, NULL, 0);
    		if (cond != SRV_NORMAL) {
    			(void) MSG_Free((void **) getRequest);
    			return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CGetResponse");
    		}
    	}
    }
    (void) MSG_Free((void **) getRequest);
    return rtnCond;
}
Exemple #9
0
/* SRV_NActionResponse
**
** Purpose:
**	SRV_NActionResponse assists an application that wants to be an SCP
**	of a number of SOP classes. When an application receives an N-ACTION
**	request message, it calls this function with the N-ACTION request
**	and other parameters. SRV_NActionResponse checks the caller's
**	parameters and calls the user's callback function. In the callback
**	function, the caller fills in the parameters of the N-ACTION response
**	message and then returns to the SRV function.
**
**	After the callback function returns, SRV_NActionResponse constructs a
**	N-ACTION Response message and sends it to the peer application which
**	sent the request message.
**
**	The arguments to the callback function are:
**		MSG_N_ACTION_REQ	*actionRequest
**		MSG_N_ACTION_RESP	*actionResponse
**		void			*actionCtx
**		DUL_PRESENTATIONCONTEXT	*pc
**
**	The first two arguments are MSG structures that contain the N-ACTION
**	Request and N-ACTION Response messages respectively. The third
**	argument is the caller's context variable that is passed to
**	SRV_NActionResponse.  The presentation context describes the SOP
**	class that was negotiated for this message.
**
**	The callback function should return SRV_NORMAL. Any other return
**	value will cause the SRV facility to abort the Association.
**
** Parameter Dictionary:
**	association	The key which is used for transmitting the N-ACTION
**			response.
**	presentationCtx	Pointer to presentation context to be used when sending
**			the N-ACTION response.
**	actionRequest	Pointer to the structure with the N-ACTION request
**			parameters which was received by the application.
**	actionResponse	Pointer to structure in the caller's area which will be
**			filled with the parameters of the N-ACTION response
**			command. After the parameters are filled in, the
**			N-ACTION response is sent to the peer application
**			which sent the request.
**	actionCallback	Address of user callback function to be called
**			with the N-ACTION response from SCP.
**	actionCtx	Pointer to user context information which will be
**			passed to the callback function. Caller uses this
**			variable to contain any context required for the
**			callback function.
**      dirName         Name of directory where files may be created.
**
**
** Return Values:
**
**	SRV_CALLBACKABORTEDSERVICE
**	SRV_ILLEGALPARAMETER
**	SRV_NOCALLBACK
**	SRV_NORMAL
**	SRV_OBJECTBUILDFAILED
**	SRV_RESPONSEFAILED
**
** Algorithm:
**	Receive a data set, if any, from the peer application
**	Invoke the callback function, if it exists.
**	Build a command and send it to the requesting peer application.
**	Send a data set, if any, to the peer application.
**
** Notes:
**	The callback function is responsible for explicitly setting the
**	following fields in the N-ACTION response message:
**
**	type
**	messageIDRespondedTo
**	classUID
**	dataSetType
**	instanceUID
**	status
**	actionReply (if any)
**
*/
CONDITION
SRV_NActionResponse(DUL_ASSOCIATIONKEY ** association,
		    DUL_PRESENTATIONCONTEXT * presentationCtx,
		    MSG_N_ACTION_REQ ** actionRequest,
		    MSG_N_ACTION_RESP * actionResponse,
	       SRV_N_ACTION_RESP_CALLBACK * actionCallback, void *actionCtx,
		    char *dirName)
{
    CONDITION
	rtnCond = SRV_NORMAL,
	cond;
    DCM_OBJECT
	* responseObject = NULL;

    actionResponse->status = MSG_K_SUCCESS;	/* initialize */
    actionResponse->dataSetType = DCM_CMDDATANULL;
    actionResponse->actionReply = NULL;

    if (actionCallback == NULL) {
	rtnCond = COND_PushCondition(SRV_NOCALLBACK,
			SRV_Message(SRV_NOCALLBACK), "SRV_NActionResponse");
	actionResponse->status = MSG_K_RESOURCELIMITATION;
	goto SEND_RESPONSE;
    }
    /* check if there is any data coming over the network */
    if ((*actionRequest)->dataSetType != DCM_CMDDATANULL) {
	cond = SRV_ReceiveDataSet(association, presentationCtx,
	       DUL_BLOCK, 0, dirName, &(*actionRequest)->actionInformation);
	if (cond != SRV_NORMAL) {
	    rtnCond = COND_PushCondition(SRV_RECEIVEDATASETFAILED,
				      SRV_Message(SRV_RECEIVEDATASETFAILED),
					 "SRV_NActionResponse");
	    actionResponse->status = MSG_K_PROCESSINGFAILURE;
	    goto SEND_RESPONSE;
	}
    }
    /* SRV routine allocates space for the action reply */
    cond = DCM_CreateObject(&actionResponse->actionReply, 0);
    if (cond != DCM_NORMAL) {
	rtnCond = COND_PushCondition(SRV_OBJECTBUILDFAILED,
		 SRV_Message(SRV_OBJECTBUILDFAILED), "SRV_NActionResponse");
	actionResponse->status = MSG_K_PROCESSINGFAILURE;
	goto SEND_RESPONSE;
    }
    cond = actionCallback(*actionRequest, actionResponse, actionCtx,
			  presentationCtx);
    if (cond != SRV_NORMAL) {
	rtnCond = COND_PushCondition(SRV_CALLBACKABORTEDSERVICE,
	     SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NActionRequest");
	goto SEND_RESPONSE;
    }
    if (actionResponse->type != MSG_K_N_ACTION_RESP) {
	rtnCond = COND_PushCondition(SRV_ILLEGALPARAMETER,
	     SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-ACTION Response",
				     "SRV_NActionResponse");
	goto SEND_RESPONSE;
    }
SEND_RESPONSE:
    /* At this point we free the request pointer */
    (void) MSG_Free((void **) actionRequest);

    /*
     * If there are any errors in the following steps, it is necessary for
     * the SRV routine to free the data set object it had created earlier.
     * But we must verify that such a data set creation operation itself was
     * successful before we try to free the data set
     */

    /* send the action reply (if any) only on success status */
    if (actionResponse->status != MSG_K_SUCCESS) {
	actionResponse->dataSetType = DCM_CMDDATANULL;
	if (actionResponse->actionReply)
	    (void) DCM_CloseObject(&actionResponse->actionReply);
	return rtnCond;
    }
    /* build a command object */
    cond = MSG_BuildCommand(actionResponse, &responseObject);
    if (cond != MSG_NORMAL) {
	if (actionResponse->actionReply)
	    (void) DCM_CloseObject(&actionResponse->actionReply);
	return COND_PushCondition(SRV_OBJECTBUILDFAILED,
		    SRV_Message(SRV_OBJECTBUILDFAILED), "N-ACTION Response",
				  "SRV_NActionResponse");
    }
    cond = SRV_SendCommand(association, presentationCtx, &responseObject);
    (void) DCM_CloseObject(&responseObject);
    if (cond != SRV_NORMAL) {
	if (actionResponse->actionReply)
	    (void) DCM_CloseObject(&actionResponse->actionReply);
	return COND_PushCondition(SRV_SENDFAILED,
				  SRV_Message(SRV_SENDFAILED), "Command",
				  "SRV_NActionResponse");
    }
    /*
     * At this point, the response message status is "SUCCESS". This also
     * implies that the "data set" object exists but may be empty (not NULL)
     * Hence if there is any error, we need to close it first before we
     * return.
     */
    if (actionResponse->dataSetType != DCM_CMDDATANULL) {
	cond = SRV_SendDataSet(association, presentationCtx,
			       &actionResponse->actionReply, NULL, NULL, 0);
	if (cond != SRV_NORMAL) {
	    (void) DCM_CloseObject(&actionResponse->actionReply);
	    return COND_PushCondition(SRV_SENDFAILED,
				    SRV_Message(SRV_SENDFAILED), "Data Set",
				      "SRV_NActionResponse");
	}
    }
    (void) DCM_CloseObject(&actionResponse->actionReply);	/* was allocated memory */
    return SRV_NORMAL;		/* everything is successful at this point */
}
Exemple #10
0
CONDITION
HAP_QueryToObject(Query * query, DCM_OBJECT ** object, char *SOPClass,
		  int *elementCount)
{
    CONDITION
	cond,
	returnCondition;
    int
        index;
    DCM_ELEMENT
	e;
    long
        flag;
    static char
        queryLevelString[48];
    DCM_ELEMENT
	queryLevelElement =
    {
	DCM_IDQUERYLEVEL, DCM_CS, "", 1,
	    sizeof(queryLevelString), (void *) queryLevelString
    };

    q = *query;
    *elementCount = 0;

    if (*object == NULL) {
	cond = DCM_CreateObject(object);
	if (cond != DCM_NORMAL)
	    return HAP_OBJECTCREATEFAILED;
    }
    returnCondition = HAP_NORMAL;
    flag = q.QueryState &
	(DB_K_LEVELPAT | DB_K_LEVELSTUDY | DB_K_LEVELSERIES | DB_K_LEVELIMAGE);
    if (flag == 0)
	returnCondition = COND_PushCondition(HAP_INCOMPLETEQUERY, "");
    else {
	for (index = 0; index < DIM_OF(levelMap); index++) {
	    if ((q.QueryState & levelMap[index].flag) != 0) {
		(void) strcpy(queryLevelString, levelMap[index].queryLevel);
		queryLevelElement.length = strlen(queryLevelElement.d.string);
		cond = DCM_ModifyElements(object, &queryLevelElement,
					  1, NULL, 0, NULL);
		if (cond != DCM_NORMAL)
		    return cond;
	    }
	}
    }


    flag = q.QueryState &
	(DB_K_CLASSPAT | DB_K_CLASSSTUDY | DB_K_CLASSPATSTUDY);
    if (flag == 0)
	returnCondition = COND_PushCondition(HAP_INCOMPLETEQUERY, "");
    else {
	for (index = 0; index < DIM_OF(classMap); index++) {
	    if ((q.QueryState & classMap[index].flag) != 0) {
		(void) strcpy(SOPClass, classMap[index].SOPClass);
		cond = DCM_NORMAL;
	    }
	}
    }

    for (index = 0; index < (int) DIM_OF(list); index++) {
	flag = *list[index].flagAddress;
	if ((flag & list[index].flag) != 0) {
	    e = list[index].e;
	    e.length = strlen(e.d.string);
	    cond = DCM_AddElement(object, &e);
	    if (cond != DCM_NORMAL)
		return cond;
	    (*elementCount)++;
	}
    }
    return returnCondition;
}
Exemple #11
0
static void handleSeriesQueries(DUL_ASSOCIATIONKEY** association,
				DUL_ASSOCIATESERVICEPARAMETERS* params,
				MSG_C_FIND_REQ* patientRequest,
				LST_HEAD* patientList,
				const char* queryLevel)
{
  ITEM* item;
  ITEM* studyItem;
  CONDITION cond;
  MSG_C_FIND_RESP response;

  item = (ITEM*)LST_Head(&patientList);
  (void)LST_Position(&patientList, item);
  while (item != 0) {
    char* patientName;
    char* patientID;
    char* studyInstanceUID;
    char* charSet;

    patientName = getString(item->obj, DCM_PATNAME);
    patientID = getString(item->obj, DCM_PATID);
    charSet = getString(patientRequest->identifier, DCM_IDSPECIFICCHARACTER);

    printf("%s %s\n", patientID, patientName);

    studyItem = (ITEM*)LST_Head(&item->lst);
    (void)LST_Position(&item->lst, studyItem);
    while (studyItem != NULL) {
      DCM_OBJECT* q;
      MSG_C_FIND_REQ seriesRequest;

      seriesRequest = *patientRequest;
      seriesRequest.identifier = 0;
      DCM_CreateObject(&q, 0);

      studyInstanceUID = getString(studyItem->obj, DCM_RELSTUDYINSTANCEUID);

      addString(q, DCM_PATID, patientID);
      addString(q, DCM_IDSPECIFICCHARACTER, charSet);
      addString(q, DCM_IDQUERYLEVEL, "SERIES");
      addString(q, DCM_RELSTUDYINSTANCEUID, studyInstanceUID);
      addString(q, DCM_IDMODALITY, "");
      addString(q, DCM_RELSERIESNUMBER, "");
      addString(q, DCM_ACQBODYPARTEXAMINED, "");
      addString(q, DCM_ACQVIEWPOSITION, "");

      seriesRequest.identifier = q;
      seriesRequest.messageID = SRV_MessageIDOut();

      studyItem->lst = LST_Create();

      cond = SRV_CFindRequest(association, params,
			      &seriesRequest, &response,
			      queryCallback, studyItem->lst, "");
      if (!(CTN_SUCCESS(cond))) {
	(void) printf("C-Find Request unsuccessful\n");
	COND_DumpConditions();
      } else {
	
      }

      studyItem = LST_Next(&item->lst);
    }
    item = LST_Next(&patientList);
  }
}