Beispiel #1
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;
}
Beispiel #2
0
/*****************************************************************************
  BeeAppInterPanDataIndication

  Process InterPan incoming ZigBee over-the-air messages.
*****************************************************************************/
void BeeAppInterPanDataIndication(void)
{
  InterPanMessage_t *pMsg;
  zbInterPanDataIndication_t *pIndication;
  zbStatus_t status = gZclMfgSpecific_c;

  while(MSG_Pending(&gInterPanAppDataIndicationQueue))
  {
    /* Get a message from a queue */
    pMsg = MSG_DeQueue( &gInterPanAppDataIndicationQueue );

    /* ask ZCL to handle the frame */
    pIndication = &(pMsg->msgData.InterPandataIndication );
    status = ZCL_InterpretInterPanFrame(pIndication);

    /* not handled by ZCL interface, handle cluster here... */
    if(status == gZclMfgSpecific_c)
    {
      /* insert manufacturer specific code here... */	  
    }

    /* Free memory allocated by data indication */
    MSG_Free(pMsg);
  }
}
Beispiel #3
0
/*****************************************************************************
  BeeAppDataConfirm

  Process incoming ZigBee over-the-air data confirms.
*****************************************************************************/
void BeeAppDataConfirm(void)
{
  apsdeToAfMessage_t *pMsg;
  zbApsdeDataConfirm_t *pConfirm;

  while(MSG_Pending(&gAppDataConfirmQueue))
  {
    /* Get a message from a queue */
    pMsg = MSG_DeQueue( &gAppDataConfirmQueue );
    pConfirm = &(pMsg->msgData.dataConfirm);

    /* Action taken when confirmation is received. */
    if( pConfirm->status != gZbSuccess_c )
    {
      /* The data wasn't delivered -- Handle error code here */
    }
    /* Free memory allocated in Call Back function */
    MSG_Free(pMsg);
  }
}
Beispiel #4
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;
}
Beispiel #5
0
CONDITION
SRV_CGetRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params,	MSG_C_GET_REQ * getRequest, MSG_C_GET_RESP * getResponse,
				SRV_C_GET_REQ_CALLBACK * getCallback, void *getCallbackCtx, CONDITION(*storageCallback) (), void *storageCallbackCtx, char *dirName)
{
    DCM_OBJECT					* commandObject;	/* Handle for a command object */
    CONDITION					cond;			/* Return value from function calls */
    DUL_PRESENTATIONCONTEXT		* presentationCtx,	/* Presentation context for GET service */	*storePresentationCtx;	/* for the arriving store request */
    DUL_PRESENTATIONCONTEXTID	ctxID;
    void      					*message;
    MSG_TYPE					messageType;
    CTNBOOLEAN					done = FALSE;
    U32							l;
    unsigned long        		responseCount = 0;
    MSG_C_STORE_REQ				* storeRequest;
    void       					*ctx;
    char        				queryLevelString[48] = "";	/* Initialization for AIX compiler */
    DCM_ELEMENT					queryLevelElement = {DCM_IDQUERYLEVEL, DCM_CS, "", 1, sizeof(queryLevelString), NULL};
    unsigned short		        command;
    CTNBOOLEAN					cancelled = FALSE;
    MSG_C_CANCEL_REQ			cancelRequest = {MSG_K_C_CANCEL_REQ, 0, 0, DCM_CMDDATANULL};

    queryLevelElement.d.string = queryLevelString;

    if ((getCallback == NULL) || (storageCallback == NULL))	return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CGetRequest");
    if (getRequest->type != MSG_K_C_GET_REQ) return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "GET Request", "SRV_CGetRequest");
    if (getRequest->dataSetType == DCM_CMDDATANULL)	return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "GET Request", "SRV_CGetRequest");

    ctx = NULL;
    cond = DCM_GetElementValue(&getRequest->identifier, &queryLevelElement, &l, &ctx);
    if (cond != DCM_NORMAL)	return COND_PushCondition(SRV_OBJECTACCESSFAILED, SRV_Message(SRV_OBJECTACCESSFAILED), "Query Identifier", "SRV_CGetRequest");

    queryLevelString[l] = '\0';
    if (queryLevelString[l - 1] == ' ')	queryLevelString[l - 1] = '\0';

    presentationCtx = SRVPRV_PresentationContext(params, getRequest->classUID);
    if (presentationCtx == NULL) return COND_PushCondition(SRV_NOSERVICEINASSOCIATION, SRV_Message(SRV_NOSERVICEINASSOCIATION), getRequest->classUID, "SRV_CGetRequest");

    cond = MSG_BuildCommand(getRequest, &commandObject);
    if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "GET Request", "SRV_CGetRequest");

    cond = SRV_SendCommand(association, presentationCtx, &commandObject);
    (void) DCM_CloseObject(&commandObject);
    if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest");

    cond = SRV_SendDataSet(association, presentationCtx, &getRequest->identifier, NULL, NULL, 0);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest");

    while (!done) {		/* do until there are no more pending requests */
    	cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message);
    	if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CGetRequest");

    	switch (messageType) {
			case MSG_K_C_GET_RESP:
											cond = processGetResponse(association, presentationCtx, dirName, getRequest, (MSG_C_GET_RESP *) message,
																	  queryLevelString, getCallback, getCallbackCtx, &done, &cancelled, getResponse, &responseCount);
											(void) MSG_Free(&message);
											if ((CTN_FATAL(cond)) || (CTN_ERROR(cond)))	return cond;
											break;
			case MSG_K_C_STORE_REQ:
											storeRequest = (MSG_C_STORE_REQ *) message;
											storePresentationCtx = SRVPRV_PresentationContext(params, storeRequest->classUID);
											if (storePresentationCtx == NULL)
												return COND_PushCondition(SRV_PRESENTATIONCONTEXTERROR, SRV_Message(SRV_PRESENTATIONCONTEXTERROR), "SRV_CGetRequest");

											cond = processStoreRequest(association, storePresentationCtx, storeRequest, storageCallback, storageCallbackCtx);
											if ((CTN_FATAL(cond)) || (CTN_ERROR(cond)))	return cond;
											break;
			default:
											(void) MSG_Free(&message);
											return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_CGetRequest");
    	}
    }
    if (cancelled){
    	return SRV_OPERATIONCANCELLED;
    }else{
    	return SRV_NORMAL;
    }
}
Beispiel #6
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 */
}
Beispiel #7
0
/* SRV_NActionRequest
**
** Purpose:
**	SRV_NActionRequest assists an application that wants to be an SCU of
**	a number of SOP classes. This function constructs an N-ACTION-REQ
**	message and sends it to the peer application which is acting as the
**	SCP for a SOP class. This function waits for the response from the
**	peer application and invokes the caller's callback function.
**
**	The arguments to the callback function are:
**		MSG_N_ACTION_REQ	*actionRequest
**		MSG_N_ACTION_RESP	*actionResponse
**		void			*actionCtx
**
**	The first two arguments are MSG structures that contain the N-ACTION
**	Request and N-ACTION Response messages respectively. The final
**	argument is the caller's context variable that is passed to
**	SRV_NActionRequest.
**
**	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 to access an existing
**			association.
**	params		The list of parameters for the association. This
**			list includes the list of presentation contexts.
**	SOPClass	UID of the SOP class used when the association was
**			negotiated. Since this can be a meta class, it may
**			not be the same as the class UID in the N-ACTION
**			request message.
**	actionRequest	Pointer to the structure with the N-ACTION request
**			parameters.
**	actionResponse	Pointer to caller's pointer to an N-ACTION response.
**			This function will allocate an MSG_N_ACTION_RESP
**			message and return the pointer to the caller.
**	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_REQUESTFAILED
**	SRV_UNEXPECTEDCOMMAND
**	SRV_UNSUPPORTEDSERVICE
**
** Algorithm:
**	Check if the callback function has been provided.
**	Determine the presentation context
**	Encode the N-ACTION request message as a command object and
**		send it to an SCP
**	Send data set, if one exists, to the SCP.
**	Wait for a response message to arrive from the SCP
**	Receive a data set, if one exists, from the SCP
**	Return address of Response message structure to caller.
**
** Notes:
**	The caller is responsible for explicitly setting the following
**	fields in the N-ACTION request message:
**
**	type
**	messageID
**	classUID
**	dataSetType
**	instanceUID
**	actionTypeID
**
**	The caller is also responsible for releasing the Response message
**	structure after the SRV_NActionRequest function returns,
**	using MSG_Free.
*/
CONDITION
SRV_NActionRequest(DUL_ASSOCIATIONKEY ** association,
		   DUL_ASSOCIATESERVICEPARAMETERS * params,
		   char *SOPClass,
		   MSG_N_ACTION_REQ * actionRequest,
		   MSG_N_ACTION_RESP * actionResponse,
		SRV_N_ACTION_REQ_CALLBACK * actionCallback, void *actionCtx,
		   char *dirName)
{
    DCM_OBJECT
	* commandObject;	/* Handle for a command object */
    CONDITION
	cond;			/* Return value from function calls */
    DUL_PRESENTATIONCONTEXT
	* presentationCtx;	/* Presentation context for this service */
    DUL_PRESENTATIONCONTEXTID
	ctxID;
    void
       *message;
    MSG_TYPE
	messageType;
    MSG_N_ACTION_RESP
	* localResponse;
    unsigned short
        command;

    if (actionCallback == NULL)
	return COND_PushCondition(SRV_NOCALLBACK,
			 SRV_Message(SRV_NOCALLBACK), "SRV_NActionRequest");

    presentationCtx = SRVPRV_PresentationContext(params, SOPClass);
    if (presentationCtx == NULL)
	return COND_PushCondition(SRV_UNSUPPORTEDSERVICE,
				  SRV_Message(SRV_UNSUPPORTEDSERVICE),
			     actionRequest->classUID, "SRV_NActionRequest");

    if (actionRequest->type != MSG_K_N_ACTION_REQ)
	return COND_PushCondition(SRV_ILLEGALPARAMETER,
	      SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-ACTION Request",
				  "SRV_NActionRequest");

    cond = MSG_BuildCommand(actionRequest, &commandObject);
    if (cond != MSG_NORMAL)
	return COND_PushCondition(SRV_OBJECTBUILDFAILED,
		     SRV_Message(SRV_OBJECTBUILDFAILED), "N-ACTION Request",
				  "SRV_NActionRequest");

    cond = SRV_SendCommand(association, presentationCtx, &commandObject);
    (void) DCM_CloseObject(&commandObject);
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_REQUESTFAILED,
		      SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest");

    if (actionRequest->dataSetType != DCM_CMDDATANULL) {
	/* application specific action information exists */
	cond = SRV_SendDataSet(association, presentationCtx,
			  &actionRequest->actionInformation, NULL, NULL, 0);
	if (cond != SRV_NORMAL)
	    return COND_PushCondition(SRV_REQUESTFAILED,
		      SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest");

    }
    cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID,
			      &command, &messageType, &message);
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_REQUESTFAILED,
		      SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest");

    if (messageType != MSG_K_N_ACTION_RESP) {
	(void) MSG_Free(&message);
	return COND_PushCondition(SRV_UNEXPECTEDCOMMAND,
			  SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command,
				  "SRV_NActionRequest");
    }
    localResponse = (MSG_N_ACTION_RESP *) message;

    if (localResponse->dataSetType == DCM_CMDDATANULL) {
	localResponse->actionReply = NULL;
    } else {
	/* application specific action reply needs to be received */
	cond = SRV_ReceiveDataSet(association, presentationCtx, DUL_BLOCK,
				  0, dirName, &localResponse->actionReply);
	if (cond != SRV_NORMAL) {
	    (void) MSG_Free(&message);
	    return COND_PushCondition(SRV_REQUESTFAILED,
		      SRV_Message(SRV_REQUESTFAILED), "SRV_NActionRequest");
	}
    }
    cond = actionCallback(actionRequest, localResponse, actionCtx);
    (void) MSG_Free(&message);
    if (localResponse->actionReply != NULL) {
	(void) DCM_CloseObject(&localResponse->actionReply);
	localResponse->actionReply = NULL;
    }
    if (actionResponse != NULL)
	*actionResponse = *localResponse;

    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE,
	     SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NActionRequest");

    return SRV_NORMAL;
}
Beispiel #8
0
/*******************************************************************************
* State machine to send the next report. If it can't get the memory, tries
* again later.
*
* This will concatinate all of the reportable attributes in a single cluster
*******************************************************************************/
void ZCL_SendReport(void)
{
  afDeviceDef_t   *pDevice;
  uint8_t payloadLen;
  uint8_t reportLen;
  afToApsdeMessage_t *pMsg; /* a message for sending the report */
  afAddrInfo_t addrInfo;
  afClusterDef_t *pCluster;
  zclFrame_t  *pFrame;
  uint8_t i;
  zclReportAttr_t *pReportList;
  
  BeeUtilZeroMemory(&addrInfo, sizeof(addrInfo));
  /* starting over? reset indexes */
  if(gfZclReportRestart) {
    gZclReportDeviceIndex = gZclReportClusterIndex = gAsynchronousClusterIndex = 0;
    gfZclReportRestart = FALSE;
  }

  /* get a buffer to build the next report */
  pMsg = AF_MsgAlloc();
  if(!pMsg) {
    gfZclReportRestart = FALSE;
    ZLC_StartShortReportingTimer();
    return;
  }

  /* walk through all devices */
  while(gZclReportDeviceIndex < gNum_EndPoints_c) {

    /* make sure this app endpoint is a ZCL device */
    pDevice = (afDeviceDef_t *) endPointList[gZclReportDeviceIndex].pDevice;
    
    /* report list */
    pReportList = pDevice->pReportList;
    
    if(!pDevice || !pDevice->pfnZCL) {
      ++gZclReportDeviceIndex;
      continue;
    }

    /* Find if any attribute are a asynchronous, then update the attribute */ 
    do
    {
      for(i=0; i<pDevice->reportCount; ++i)
      {
        zclAttrDef_t *pAttrDef;
        zclReportAttr_t *pCurrentReportList = &pReportList[i];
        /* only looking for this one cluster, to see if it's in the reportinglist */
        if(!IsEqual2Bytes(pCurrentReportList->aClusterId, pDevice->pClusterDef[gAsynchronousClusterIndex].aClusterId))
          continue;            
               
        // If the cluster is on the reporting list, find the reporting attribute
        pAttrDef = ZCL_FindAttr(&pDevice->pClusterDef[gAsynchronousClusterIndex], pCurrentReportList->attrId);
        if(pAttrDef)
        {
          /* It's a asynchronous attribute, update before reporting */
          if(ZclAttrIsAsynchronous_c(pAttrDef->flags))
          {
            ++gAsynchronousClusterIndex;
            BeeAppUpdateDevice(0, gZclUI_SendReportingAttributeRequest_c, pAttrDef->id, pCurrentReportList->aClusterId, NULL);
            //Free the message, because we return from here
            MSG_Free(pMsg);
            return;
          }
        }
        
      }
      ++gAsynchronousClusterIndex;
    }while(gAsynchronousClusterIndex < pDevice->clusterCount);

    /* check each cluster for reporting attributes */
    while(gZclReportClusterIndex < pDevice->clusterCount) {

      pCluster = &pDevice->pClusterDef[gZclReportClusterIndex];

      pFrame = (void *)(&((uint8_t *)pMsg)[ApsmeGetAsduOffset()]);

      /* build the report for the next cluster */
      reportLen = ZCL_BuildAttrReport(
        (zclCmdReportAttr_t *)(pFrame + 1),   /* ptr to report frame */
        pDevice,                              /* ptr to device */
        pCluster
        );            

      /* no reporting attributes this cluster */
      if(!reportLen) {
        ++gZclReportClusterIndex;
        continue;
      }

      /* set up the address info */
      addrInfo.dstAddrMode = gZbAddrModeIndirect_c;
      addrInfo.srcEndPoint = endPointList[gZclReportDeviceIndex].pEndpointDesc->pSimpleDesc->endPoint;
      addrInfo.txOptions = gZclTxOptions;
      addrInfo.radiusCounter = afDefaultRadius_c;

      /* determine which cluster to send it to */
      Copy2Bytes(addrInfo.aClusterId, pCluster->aClusterId);

      /* set up frame */
      pFrame->frameControl = gZclFrameControl_FrameTypeGeneral | gZclFrameControl_DisableDefaultRsp;
      pFrame->transactionId = gZclTransactionId++;
      pFrame->command = gZclCmdReportAttr_c;

      /* send the report */
      payloadLen = sizeof(zclFrame_t) + reportLen;
      (void)ZCL_DataRequestNoCopy(&addrInfo, payloadLen, pMsg);

      ++gZclReportClusterIndex;

      /* start a short timer between reporting clusters */
      gfZclReportRestart = FALSE;
      ZLC_StartShortReportingTimer();
      return;
    }
    
    /* try next device */
    ++gZclReportDeviceIndex;
    gZclReportClusterIndex=0;
    gAsynchronousClusterIndex=0;
  } /* end of while(gZclReportDeviceIndex < gNum_EndPoints_c) */

  if(pMsg)
    MSG_Free(pMsg);

  /* start up a new timer if needed */
  if(gZclReportingSetup.reportTimeout != 0 && gZclReportingSetup.reportTimeout != 0xFFFF)
  {
      gZclReportingSetup.reportCounter = gZclReportingSetup.reportTimeout;
      ZLC_StartReportingTimer();
  }
}
Beispiel #9
0
/* SRV_NSetRequest
**
** Purpose:
**	SRV_NSetRequest assists an application that wants to be an SCU of
**	a number of SOP classes. This function constructs an N-SET-REQ
**	message and sends it to the peer application which is acting as the
**	SCP for a SOP class. This function waits for the response from the
**	peer application and invokes the caller's callback function.
**
**	The arguments to the callback function are:
**		MSG_N_SET_REQ	*setRequest
**		MSG_N_SET_RESP	*setResponse
**		void		*setCtx
**
**	The first two arguments are MSG structures that contain the N-SET
**	Request and N-SET Response messages respectively. The final
**	argument is the caller's context variable that is passed to
**	SRV_NSetRequest.
**
**	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 to access an existing
**			association.
**	params		The list of parameters for the association. This
**			list includes the list of presentation contexts.
**	SOPClass	UID of the SOP class used when the association was
**			negotiated. Since this can be a meta class, it may
**			not be the same as the class UID in the N-SET
**			request message.
**	setRequest	Pointer to the structure with the N-SET request
**			parameters.
**	setResponse	Pointer to caller's pointer to an N-SET response.
**			This function will allocate an MSG_N_SET_RESP
**			message and return the pointer to the caller.
**	setCallback	Address of user callback function to be called
**			with the N-SET response from SCP.
**	setCtx		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_REQUESTFAILED
**	SRV_UNEXPECTEDCOMMAND
**	SRV_UNSUPPORTEDSERVICE
**
** Algorithm:
**	Check if the callback function has been provided.
**	Determine the presentation context
**	Encode the N-SET request message as a command object and
**		send it to an SCP
**	Send data set, if one exists, to the SCP.
**	Wait for a response message to arrive from the SCP
**	Receive a data set, if one exists, from the SCP
**	Return address of Response message structure to caller.
**
** Notes:
**	The caller is responsible for explicitly setting the following
**	fields in the N-SET request message:
**
**	type
**	messageID
**	classUID
**	dataSetType
**	dataSet
**	instanceUID
**
**	The caller is also responsible for releasing the Response message
**	structure after the SRV_NSetRequest function returns,
**	using MSG_Free.
*/
CONDITION
SRV_NSetRequest(DUL_ASSOCIATIONKEY ** association,
		DUL_ASSOCIATESERVICEPARAMETERS * params,
		char *SOPClass,
		MSG_N_SET_REQ * setRequest, MSG_N_SET_RESP * setResponse,
	  SRV_N_SET_REQ_CALLBACK * setCallback, void *setCtx, char *dirName)
{
    DCM_OBJECT
	* commandObject;	/* Handle for a command object */
    CONDITION
	cond;			/* Return value from function calls */
    DUL_PRESENTATIONCONTEXT
	* presentationCtx;	/* Presentation context for this service */
    DUL_PRESENTATIONCONTEXTID
	ctxID;
    void
       *message;
    MSG_TYPE
	messageType;
    MSG_N_SET_RESP
	* localResponse;
    unsigned short
        command;

    if (setCallback == NULL)
	return COND_PushCondition(SRV_NOCALLBACK,
			    SRV_Message(SRV_NOCALLBACK), "SRV_NSetRequest");

    presentationCtx = SRVPRV_PresentationContext(params, SOPClass);
    if (presentationCtx == NULL)
	return COND_PushCondition(SRV_UNSUPPORTEDSERVICE,
				  SRV_Message(SRV_UNSUPPORTEDSERVICE),
				  setRequest->classUID, "SRV_NSetRequest");

    if (setRequest->type != MSG_K_N_SET_REQ)
	return COND_PushCondition(SRV_ILLEGALPARAMETER,
		 SRV_Message(SRV_ILLEGALPARAMETER), "type", "N-SET Request",
				  "SRV_NSetRequest");

    cond = MSG_BuildCommand(setRequest, &commandObject);
    if (cond != MSG_NORMAL)
	return COND_PushCondition(SRV_OBJECTBUILDFAILED,
			SRV_Message(SRV_OBJECTBUILDFAILED), "N-SET Request",
				  "SRV_NSetRequest");

    cond = SRV_SendCommand(association, presentationCtx, &commandObject);
    (void) DCM_CloseObject(&commandObject);
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_REQUESTFAILED,
			 SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest");

    if (setRequest->dataSetType == DCM_CMDDATANULL)
	/* sending attribute list is mandatory */
	return COND_PushCondition(SRV_ILLEGALPARAMETER,
	  SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "N-SET Request",
				  "SRV_NSetRequest");

    cond = SRV_SendDataSet(association, presentationCtx,
			   &setRequest->dataSet, NULL, NULL, 0);
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_REQUESTFAILED,
			 SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest");

    cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID,
			      &command, &messageType, &message);
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_REQUESTFAILED,
			 SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest");

    if (messageType != MSG_K_N_SET_RESP) {
	(void) MSG_Free(&message);
	return COND_PushCondition(SRV_UNEXPECTEDCOMMAND,
			  SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command,
				  "SRV_NSetRequest");
    }
    localResponse = (MSG_N_SET_RESP *) message;

    if (localResponse->dataSetType == DCM_CMDDATANULL) {
	localResponse->dataSet = NULL;
    } else {
	cond = SRV_ReceiveDataSet(association, presentationCtx,
			    DUL_BLOCK, 0, dirName, &localResponse->dataSet);
	if (cond != SRV_NORMAL) {
	    (void) MSG_Free(&message);
	    return COND_PushCondition(SRV_REQUESTFAILED,
			 SRV_Message(SRV_REQUESTFAILED), "SRV_NSetRequest");
	}
    }
    cond = setCallback(setRequest, localResponse, setCtx);
    (void) MSG_Free(&message);
    if (localResponse->dataSet != NULL) {
	(void) DCM_CloseObject(&localResponse->dataSet);
	localResponse->dataSet = NULL;
    }
    if (setResponse != NULL)
	*setResponse = *localResponse;
    if (cond != SRV_NORMAL)
	return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE,
		SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_NSetRequest");

    return SRV_NORMAL;
}
Beispiel #10
0
void HcOutgoingZtcTaskEventMonitor(OepOutgoingMessage_t *message) {
  
  
  hcZtcMessage_t* pMsgFromSAPHandler;
  
  /* cleaner access to the 11073 apdu */   
  oepGenericApdu_t *pApdu = (oepGenericApdu_t *)message->pApdu;
  
  uint8_t* pSrcDataPtr;
  uint8_t* pDstDataPtr;
  
  /* first fragment flag is initially set to True */   
  uint8_t firstFragment = TRUE;
  uint16_t apduLen = message->length - MbrSizeof(oepGenericApdu_t, apduLen);
  
  uint8_t dataCopyLen;

  /* iterate the fragments */   
  do
  {
    /* allocate a new buffer as the ZTC frames are quite different from the actual
       11073 frames */   
    pMsgFromSAPHandler = (hcZtcMessage_t *) MSG_Alloc(mSapHandlerMsgTotalLen_c);    

    if (firstFragment) {
    
      oepMsgType_t oepMsgType; 
    
      firstFragment = FALSE;
      
      /* is it a cfg, prst, other kind of frame? */ 
      oepMsgType = GetOepMsgType(pApdu);
    
      /* get ZTC opcode id for the frame */ 
      pMsgFromSAPHandler->msgType = GetMsgZtcOpCode(pApdu);
      
      
      /* frame is an object configuration frame */ 
      if (oepMsgType == msgType_ObjCfgMsg) {
      
        hcZtcObjCfgFrame_t* pHcZtcObjCfgFrame = (hcZtcObjCfgFrame_t *)pMsgFromSAPHandler->data;
        
        apduLen -= MbrSizeof(oepGenericApdu_t, choice);
        
        if (apduLen > mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame)) {
        
          dataCopyLen = mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
          apduLen -= dataCopyLen;
          pHcZtcObjCfgFrame->nextFragmentPresent = TRUE;
          
        }
        else {
        
          dataCopyLen = (uint8_t)apduLen;
          apduLen = 0;
          pHcZtcObjCfgFrame->nextFragmentPresent = FALSE;
          
        }
      
        pMsgFromSAPHandler->msgLen = dataCopyLen + MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
                                     
        pSrcDataPtr = (uint8_t *)pApdu->payload;
        
        pDstDataPtr = (uint8_t *)pHcZtcObjCfgFrame->objCfgFrame; 
        
        pHcZtcObjCfgFrame->endPoint = message->srcEndPoint;
        
      }
      else {
        /* Aarq, Aars, Prst, etc type of frame */
        hcZtcFrame_t* pZtcFrameGeneric = (hcZtcFrame_t *)pMsgFromSAPHandler->data;
        
        if (apduLen > mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcFrame_t, apdu)) {
        
          dataCopyLen = mSapHandlerMsgTotalLen_c - MbrOfs(hcZtcFrame_t, apdu);
          apduLen -= dataCopyLen;
          pZtcFrameGeneric->nextFragmentPresent = TRUE;
          
        } 
        else {

          dataCopyLen = (uint8_t)apduLen;
          apduLen = 0;
          pZtcFrameGeneric->nextFragmentPresent = FALSE;
          
        }
        
        pMsgFromSAPHandler->msgLen = dataCopyLen + MbrOfs(hcZtcFrame_t, apdu);
        
        pSrcDataPtr = (uint8_t *)&pApdu->choice;
        
        pDstDataPtr = (uint8_t *)pZtcFrameGeneric->apdu;
                                
        Copy2Bytes(pZtcFrameGeneric->aSrcDstAddr, message->aDstAddr);
        pZtcFrameGeneric->dstEndPoint = message->dstEndPoint;
        pZtcFrameGeneric->srcEndPoint = message->srcEndPoint;
      }
    }
    else 
    {
      /* this is not the first fragment; */
      
      hcZtcFragmentContinuationFrame_t* pZtcFragmentCont = 
                          (hcZtcFragmentContinuationFrame_t *)pMsgFromSAPHandler->data;
                          
      /* set fragment continuation opcode */
      pMsgFromSAPHandler->msgType = gHcZtcOpcode_FragmentContinuation_d;
      
      if (apduLen > mSapHandlerMsgTotalLen_c - 
          MbrOfs(hcZtcFragmentContinuationFrame_t, fragmentData)) {
        
        dataCopyLen = mSapHandlerMsgTotalLen_c -  
                      MbrOfs(hcZtcFragmentContinuationFrame_t, fragmentData);
        apduLen -= dataCopyLen;
        pZtcFragmentCont->nextFragmentPresent = TRUE;
        
      } 
      else {

        dataCopyLen = (uint8_t)apduLen;
        apduLen = 0;
        pZtcFragmentCont->nextFragmentPresent = FALSE;
        
      }
      
      pMsgFromSAPHandler->msgLen = dataCopyLen +
                           MbrSizeof(hcZtcFragmentContinuationFrame_t, fragmentData);

      pDstDataPtr = (uint8_t *)pZtcFragmentCont->fragmentData;
    }
    
    FLib_MemCpy(pDstDataPtr, pSrcDataPtr, dataCopyLen);
    
    pSrcDataPtr += dataCopyLen;
    
    /* send message to ZTC */
#ifndef gHostApp_d        
    ZTC_TaskEventMonitor(gHcApp_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#else
    ZTC_TaskEventMonitor(gpHostAppUart, gHcApp_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#endif     

    /* free the message if ZTC hasn't already done that */
    if (pMsgFromSAPHandler)
      MSG_Free(pMsgFromSAPHandler);
    
  } while (apduLen > 0);
}
Beispiel #11
0
void HcIncomingZtcTaskEventMonitor(OepFragmentedApdu_t *message) {
  
  hcZtcMessage_t* pMsgFromSAPHandler;
  
  /* pCurrentFragment points initially to the fragment in OepFragmentedApdu_t */   
  OepApduFragment_t* pCurrentFragment = &message->fragment;
  
  /* cleaner access to the 11073 apdu */   
  oepGenericApdu_t *pApdu = (oepGenericApdu_t *)pCurrentFragment->data;
  
  
  /* first fragment flag is initially set to True */   
  uint8_t firstFragment = TRUE;

  /* iterate the fragments */   
  do {
  
    uint8_t srcOffset, dstOffset, dataCopyLen;
  
    /* allocate a new buffer as the ZTC frames are quite different from the actual
       11073 frames */   
    pMsgFromSAPHandler = (hcZtcMessage_t *) MSG_Alloc(mSapHandlerMsgTotalLen_c);    

    /* set default values for mem copy offsets and length */
    
    /* by default copy data beginning with the choice member in the apdu */      
    srcOffset = MbrOfs(oepGenericApdu_t, choice);
    
    /* by default copy data to the apdu member in the ztc frame*/          
    dstOffset = MbrOfs(hcZtcFrame_t, apdu);    
    
    /* data copy length adjusted to omit apduLen field */              
    dataCopyLen = pCurrentFragment->len - MbrOfs(oepGenericApdu_t, choice);
    
    if (firstFragment) {
      oepMsgType_t oepMsgType; 
    
      firstFragment = FALSE;
    
      /* is it a cfg, prst, other kind of frame? */ 
      oepMsgType = GetOepMsgType(pApdu);
    
      /* get ZTC opcode id for the frame */ 
      pMsgFromSAPHandler->msgType = GetMsgZtcOpCode(pApdu);
      
      /* frame is an object configuration frame */ 
      if (oepMsgType == msgType_ObjCfgMsg) {
      
        /* msgLen is the length of the ZTC payload; this includes the actual
           apdu payload, without the choice and apduLen as well as the src/dstEndPoint
           and nextFragmentPresent bytes */
        pMsgFromSAPHandler->msgLen = (uint8_t)(pCurrentFragment->len - 
                                     MbrOfs(oepGenericApdu_t, payload) +
                                     MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame));
                                     
        /* adjust source offset for data copy to not include choice */ 
        srcOffset = MbrOfs(oepGenericApdu_t, payload);
        
        /* adjust dst offset for data copy as srcAddress and an endpoint are no longer included */
        dstOffset = MbrOfs(hcZtcObjCfgFrame_t, objCfgFrame);
        
        /* adjust data length for data copy as choice is no longer included */
        dataCopyLen -= MbrSizeof(oepGenericApdu_t, choice);
        
        /* set destination endpoint as second byte in the ZTC
           packet based on frame direction */
        pMsgFromSAPHandler->data[1] = message->dstEndPoint;
                                     
      }
      else {
        /* Aarq, Aars, Prst, etc type of frame */
        hcZtcFrame_t* pZtcFrameGeneric = (hcZtcFrame_t *)pMsgFromSAPHandler->data;
        
        /* msgLen is the length of the ZTC payload; this includes the actual
           apdu payload, without the apduLen as well as the addressing information
           and nextFragmentPresent bytes */
        pMsgFromSAPHandler->msgLen = pCurrentFragment->len -
                                     MbrOfs(oepGenericApdu_t, choice) +
                                     MbrOfs(hcZtcFrame_t, apdu);
                                     
        /* copy addressing info */
        Copy2Bytes(pZtcFrameGeneric->aSrcDstAddr, message->aSrcAddr);
        pZtcFrameGeneric->dstEndPoint = message->dstEndPoint;
        pZtcFrameGeneric->srcEndPoint = message->srcEndPoint;
      }
    }
    else 
    {
      /* this is not the first fragment; */
      
      /* set data copy and copy size accordingly */ 
      srcOffset = 0;
      dstOffset = 1;
      dataCopyLen = pCurrentFragment->len;
      
      pApdu =  (oepGenericApdu_t *)pCurrentFragment->data;
      
      /* set fragment continuation opcode */
      pMsgFromSAPHandler->msgType = gHcZtcOpcode_FragmentContinuation_d;
      
        /* msgLen includes the actualapdu payload and the nextFragmentPresent byte */      
      pMsgFromSAPHandler->msgLen = pCurrentFragment->len +
                                   MbrSizeof(hcZtcFrame_t, nextFragmentPresent);
    }
    
    /* nextFragmentPresent */
    pMsgFromSAPHandler->data[0] = FALSE;
    
    /* set nextFramgentPresent byte in ZTC frame to 1 if there is
       another fragment to be processed */
    if (pCurrentFragment->nextFragment != NULL)
      pMsgFromSAPHandler->data[0] = TRUE;
    
    /* do the fragment iteration */
    pCurrentFragment = pCurrentFragment->nextFragment;

    /* copy payload data */
    FLib_MemCpy((uint8_t*)pMsgFromSAPHandler->data + dstOffset,
                (uint8_t*)pApdu + srcOffset,
                dataCopyLen);
    
    /* send message to ZTC */
#ifndef gHostApp_d        
    ZTC_TaskEventMonitor(gAppHc_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#else
    ZTC_TaskEventMonitor(gpHostAppUart, gAppHc_SAPHandlerId_c, (uint8_t *)pMsgFromSAPHandler, gZbSuccess_c);
#endif     
    /* free the message if ZTC hasn't already done that */
    if (pMsgFromSAPHandler)
      MSG_Free(pMsgFromSAPHandler);
    
  } while (pCurrentFragment != NULL);
}
Beispiel #12
0
/*****************************************************************************
*Mac Application Task event processor.  This function is called to
* process all events for the task. Events include timers, messages and any
* other user defined events
*
* Interface assumptions: None
*
* Return value: None
*****************************************************************************/
void AppTask(event_t events) 
{ 

  /* Pointer for storing the messages from MLME, MCPS, and ASP. */
  void *pMsgIn;
  /* Stores the status code returned by some functions. */
  uint8_t rc;  
  pMsgIn = NULL;
  
  /* Dequeue the MLME message */
  if (events & gAppEvtMessageFromMLME_c)
  {
    /* Get the message from MLME */
    pMsgIn = MSG_DeQueue(&mMlmeNwkInputQueue);
    
    /* Any time a beacon might arrive. Always handle the beacon frame first */
    if (pMsgIn)
    {               
      rc = App_WaitMsg(pMsgIn, gNwkBeaconNotifyInd_c);
      if(rc == errorNoError)
      {
        /* ALWAYS free the beacon frame contained in the beacon notify indication.*/
        /* ALSO the application can use the beacon payload.*/
        MSG_Free(((nwkMessage_t *)pMsgIn)->msgData.beaconNotifyInd.pBufferRoot);
        UartUtil_Print("Received an MLME-Beacon Notify Indication\n\r", gAllowToBlock_d);
      }
    }
  }
  
  /* The application state machine */
  switch(gState)
  {
  case stateInit:    
    /* Print a welcome message to the UART */
    UartUtil_Print("MyWirelessApp Demo Non Beacon End Device application is initialized and ready.\n\r\n\r", gAllowToBlock_d);            
    /* Goto Active Scan state. */
    gState = stateScanActiveStart;
    TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);    
    break;
    
  case stateScanActiveStart:
    /* Start the Active scan, and goto wait for confirm state. */
    UartUtil_Print("Start scanning for a PAN coordinator\n\r", gAllowToBlock_d);
    /*print a message on the LCD also*/
    LCD_ClearDisplay();
    LCD_WriteString(1,"Start scanning");
    LCD_WriteString(2,"for coordinator");  
    rc = App_StartScan(gScanModeActive_c);
    if(rc == errorNoError)
    {
      gState = stateScanActiveWaitConfirm;
    }
    break;
    
  case stateScanActiveWaitConfirm:
    /* Stay in this state until the Scan confirm message
       arrives, and then goto the associate state. */
    if (events & gAppEvtMessageFromMLME_c)
    {
      if (pMsgIn)
      {                     
        rc = App_WaitMsg(pMsgIn, gNwkScanCnf_c);
        if(rc == errorNoError)
        {
          rc = App_HandleScanActiveConfirm(pMsgIn);
          if(rc == errorNoError)
          {
            UartUtil_Print("Found a coordinator with the following properties:\n\r", gAllowToBlock_d);
            UartUtil_Print("----------------------------------------------------", gAllowToBlock_d);
            UartUtil_Print("\n\rAddress...........0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.coordAddress, mCoordInfo.coordAddrMode == gAddrModeShort_c ? 2 : 8, 0);
            UartUtil_Print("\n\rPAN ID............0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.coordPanId, 2, 0);
            UartUtil_Print("\n\rLogical Channel...0x", gAllowToBlock_d); UartUtil_PrintHex(&mCoordInfo.logicalChannel, 1, 0);
            UartUtil_Print("\n\rBeacon Spec.......0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.superFrameSpec, 2, 0);
            UartUtil_Print("\n\rLink Quality......0x", gAllowToBlock_d); UartUtil_PrintHex(&mCoordInfo.linkQuality, 1, 0);
            UartUtil_Print("\n\r\n\r", gAllowToBlock_d);

            gState = stateAssociate;
            TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);
          }
          else
		      {
            UartUtil_Print("Scan did not find a suitable coordinator\n\r", gAllowToBlock_d);
            /*print a message on the LCD also*/
            LCD_ClearDisplay();
            LCD_WriteString(1,"No coordinator");
            LCD_WriteString(2,"found.");
		      }
		    }
      }
    }
    break;

  case stateAssociate:
    /* Associate to the PAN coordinator */
    UartUtil_Print("Associating to PAN coordinator on channel 0x", gAllowToBlock_d);
    UartUtil_PrintHex(&(mCoordInfo.logicalChannel), 1, gPrtHexNewLine_c);
    /*print a message on the LCD also*/
    LCD_ClearDisplay();
    LCD_WriteString(1,"Associating to ");
    LCD_WriteString(2,"PAN coordinator");  
    rc = App_SendAssociateRequest();
    if(rc == errorNoError)
      gState = stateAssociateWaitConfirm;
    break; 

  case stateAssociateWaitConfirm:
    /* Stay in this state until the Associate confirm message
       arrives, and then goto the Listen state. */
    if (events & gAppEvtMessageFromMLME_c)
    {
      if (pMsgIn)
      {   
        rc = App_WaitMsg(pMsgIn, gNwkAssociateCnf_c);
        if(rc == errorNoError)
        {          
          rc = App_HandleAssociateConfirm(pMsgIn);
          if (rc == errorNoError)
          { 
	          UartUtil_Print("Successfully associated with the coordinator.\n\r", gAllowToBlock_d);
	          UartUtil_Print("We were assigned the short address 0x", gAllowToBlock_d);
	          UartUtil_PrintHex(maMyAddress, mAddrMode == gAddrModeShort_c ? 2 : 8, 0);
	          UartUtil_Print("\n\r\n\rReady to send and receive data over the UART.\n\r\n\r", gAllowToBlock_d);
	          /*print a message on the LCD also*/
	          LCD_ClearDisplay();
	          LCD_WriteString(1,"Ready to send");
	          LCD_WriteString(2,"and receive data");    
	          /* Startup the timer */
	          TMR_StartSingleShotTimer(mTimer_c, mPollInterval, AppPollWaitTimeout);
	          /* Go to the listen state */
	          gState = stateListen;
	          TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); 
          }        
          else 
          {
          
	          UartUtil_Print("\n\rAssociate Confirm wasn't successful... \n\r\n\r", gAllowToBlock_d);
	          gState = stateScanActiveStart;
              TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c);
          }
        }
      }
    }
    break; 
    
  case stateListen:
    //WSNProject
    //need to sleep?
    PWR_AllowDeviceToSleep();
    Reason=PWR_EnterLowPower();
    /* Transmit to coordinator data received from UART. */
    if (events & gAppEvtMessageFromMLME_c)
    {  
      if (pMsgIn)
      {  
        /* Process it */
        rc = App_HandleMlmeInput(pMsgIn);
      }
    } 
    
    if (events & gAppEvtRxFromUart_c)
    {      
      /* get byte from UART */
      App_TransmitUartData();
    
    }  
    break;
  }
  
  if (pMsgIn)
  {
    /* Messages must always be freed. */ 
    MSG_Free(pMsgIn);
  }
  
   /* Handle MCPS confirms and transmit data from UART */
  if (events & gAppEvtMessageFromMCPS_c)
  {      
    /* Get the message from MCPS */
    pMsgIn = MSG_DeQueue(&mMcpsNwkInputQueue);
    if (pMsgIn)
    {              
      /* Process it */
      App_HandleMcpsInput(pMsgIn);
      /* Messages from the MCPS must always be freed. */
      MSG_Free(pMsgIn);
    }
  }
  
  /* Check for pending messages in the Queue */ 
  if(MSG_Pending(&mMcpsNwkInputQueue))
    TS_SendEvent(gAppTaskID_c, gAppEvtMessageFromMCPS_c);
  if(MSG_Pending(&mMlmeNwkInputQueue))
    TS_SendEvent(gAppTaskID_c, gAppEvtMessageFromMLME_c);  
}
Beispiel #13
0
CONDITION
SRV_CStoreResponse(DUL_ASSOCIATIONKEY ** association, DUL_PRESENTATIONCONTEXT * ctx, MSG_C_STORE_REQ ** storeRequest, MSG_C_STORE_RESP * storeReply,
				   char *fileName, SRV_C_STORE_RESP_CALLBACK * callback, void *callbackCtx, char *dirName)
{
    int		        	fd, done;
    unsigned long		total, estimatedSize, nextCallback;
    unsigned short      sendStatus = 0x0000;
    DUL_PDV				pdv;
    CONDITION			cond;
    DCM_OBJECT			* object;
    DCM_FILE_META 		fileMeta;
    int 				storeAsPart10 = 0;
    char* 				paramValue;

    storeReply->messageIDRespondedTo = (*storeRequest)->messageID;
    storeReply->type = MSG_K_C_STORE_RESP;
    (void) strcpy(storeReply->classUID, (*storeRequest)->classUID);
    (void) strcpy(storeReply->instanceUID, (*storeRequest)->instanceUID);
    storeReply->conditionalFields = MSG_K_C_STORERESP_CLASSUID | MSG_K_C_STORERESP_INSTANCEUID;
    storeReply->dataSetType = DCM_CMDDATANULL;

    if (strlen(fileName) == 0 || fileName == NULL) {
    	fd = -1;
    }else{
#ifdef _MSC_VER
    	fd = _open(fileName, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, _S_IREAD | _S_IWRITE);
#else
    	fd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666);
#endif
    	if (fd < 0) (void) COND_PushCondition(SRV_FILECREATEFAILED, SRV_Message(SRV_FILECREATEFAILED), fileName, "SRV_CStoreResponse");
    }
    if (strcmp(ctx->acceptedTransferSyntax, DICOM_TRANSFERLITTLEENDIAN) != 0){
    	storeAsPart10 = 1;
    }else{
    	paramValue = UTL_GetConfigParameter("STORAGE/PART10FLAG");
    	if (paramValue != NULL) {
    		if (strcmp(paramValue, "1") == 0) storeAsPart10 = 1;
    	}
    }
    if ((storeAsPart10 == 1) && (fd > 0)){
    	int localStatus = 0;
    	memset(&fileMeta, 0, sizeof(fileMeta));
    	setFileMeta(&fileMeta, *storeRequest, ctx->acceptedTransferSyntax);
    	localStatus = writePart10MetaHeader(fd, &fileMeta);
    	if (localStatus != 0) fd = -1;
    }
    if (fd < 0) {
    	sendStatus = MSG_K_C_STORE_OUTOFRESOURCES;
    	storeReply->conditionalFields |= MSG_K_C_STORERESP_ERRORCOMMENT;
    	strcpy(storeReply->errorComment, "Storage Service unable to create local file");
    	fprintf(stderr,"Storage Service unable to create local file\n");
    }
    done = 0;
    total = 0;
    estimatedSize = genericImageSize((*storeRequest)->classUID);
    nextCallback = estimatedSize / 10;

    while (!done) {
    	cond = SRVPRV_ReadNextPDV(association, DUL_BLOCK, 0, &pdv);
    	if (cond != SRV_NORMAL) {
    		(void) MSG_Free((void **) storeRequest);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse");
    	}

    	if (pdv.pdvType != DUL_DATASETPDV) {
    		(void) MSG_Free((void **) storeRequest);
    		return COND_PushCondition(SRV_UNEXPECTEDPDVTYPE, SRV_Message(SRV_UNEXPECTEDPDVTYPE), (int) pdv.pdvType, "SRV_CStoreResponse");
    	}

    	if (sendStatus == 0) if (write(fd, pdv.data, pdv.fragmentLength) != (int) pdv.fragmentLength) sendStatus = MSG_K_C_STORE_OUTOFRESOURCES;

    	total += pdv.fragmentLength;
    	if (pdv.lastPDV) done++;

    	if (total > nextCallback){
    		cond = callback(*storeRequest, NULL, total, estimatedSize, NULL, callbackCtx, ctx);
    		if (cond != SRV_NORMAL){
    			(void) MSG_Free((void **) storeRequest);
    			return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse");
    		}
    		nextCallback += estimatedSize / 10;
    	}
    }
    if (fd >= 0) (void) close(fd);

    storeReply->status = sendStatus;

    if (sendStatus == 0x0000) {
    	unsigned long options = DCM_ORDERLITTLEENDIAN;
    	if (storeAsPart10 == 1) options = DCM_PART10FILE;

    	cond = DCM_OpenFile(fileName, options, &object);
    	if (cond != DCM_NORMAL) {
    		(void) MSG_Free((void **) storeRequest);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse");
    	}

    	cond = callback(*storeRequest, storeReply, total, estimatedSize, &object, callbackCtx, ctx);
    	if (cond != SRV_NORMAL) {
    		(void) DCM_CloseObject(&object);
    		return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse");
    	}
    	(void) DCM_CloseObject(&object);
    }
    (void) MSG_Free((void **) storeRequest);

    cond = MSG_BuildCommand(storeReply, &object);
    if (cond != MSG_NORMAL) return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "STORE Request", "SRV_CStoreResponse");

    cond = SRV_SendCommand(association, ctx, &object);
    (void) DCM_CloseObject(&object);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_RESPONSEFAILED, SRV_Message(SRV_RESPONSEFAILED), "SRV_CStoreResponse");

    return SRV_NORMAL;
}
Beispiel #14
0
CONDITION
SRV_CStoreRequest(DUL_ASSOCIATIONKEY ** association, DUL_ASSOCIATESERVICEPARAMETERS * params, MSG_C_STORE_REQ * storeRequest, MSG_C_STORE_RESP * storeResponse,
				  SRV_C_STORE_REQ_CALLBACK * callback, void *callbackCtx, char *dirName)
{
    DCM_OBJECT					* commandObject,	/* Handle for a command object */
								*dataSetObject;		/* Handle for a Data Set object */
    CONDITION					cond;				/* Return value from function calls */
    DUL_PRESENTATIONCONTEXT		* presentationCtx;	/* Presentation context for this service */
    DUL_PRESENTATIONCONTEXTID	ctxID;
    void				       *message;
    MSG_TYPE					messageType;
    unsigned long		        objectSize;
    unsigned short		        command;
    STORAGE_CTX					localCtx;
    MSG_C_STORE_RESP			* response;

    localCtx.callback = callback;
    localCtx.storeRequest = storeRequest;
    localCtx.storeResponse = NULL;
    localCtx.userCtx = callbackCtx;

    if (callback == NULL)
    	return COND_PushCondition(SRV_NOCALLBACK, SRV_Message(SRV_NOCALLBACK), "SRV_CStoreRequest");
    if (storeRequest->type != MSG_K_C_STORE_REQ)
    	return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "type", "STORE Request", "SRV_CStoreRequest");
    if (storeRequest->dataSetType == DCM_CMDDATANULL)
    	return COND_PushCondition(SRV_ILLEGALPARAMETER, SRV_Message(SRV_ILLEGALPARAMETER), "dataSetType", "STORE Request", "SRV_CStoreRequest");

    presentationCtx = SRVPRV_PresentationContext(params, storeRequest->classUID);
    if (presentationCtx == NULL)
    	return COND_PushCondition(SRV_NOSERVICEINASSOCIATION, SRV_Message(SRV_NOSERVICEINASSOCIATION), storeRequest->classUID, "SRV_CStoreRequest");

    cond = MSG_BuildCommand(storeRequest, &commandObject);
    if (cond != MSG_NORMAL)	return COND_PushCondition(SRV_OBJECTBUILDFAILED, SRV_Message(SRV_OBJECTBUILDFAILED), "STORE Request", "SRV_CStoreRequest");

    dataSetObject = storeRequest->dataSet;
    if (dataSetObject == NULL) {
    	cond = DCM_OpenFile(storeRequest->fileName, DCM_ORDERLITTLEENDIAN, &dataSetObject);
    	if (cond != DCM_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");
    }

    cond = DCM_GetObjectSize(&dataSetObject, &objectSize);
    if (cond != DCM_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");


    cond = SRV_SendCommand(association, presentationCtx, &commandObject);
    (void) DCM_CloseObject(&commandObject);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");

    cond = callback(storeRequest, NULL, 0, objectSize, callbackCtx);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");

    cond = SRV_SendDataSet(association, presentationCtx, &dataSetObject, localCallback, &localCtx, objectSize);
    if (storeRequest->dataSet == NULL) (void) DCM_CloseObject(&dataSetObject);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");


    cond = SRV_ReceiveCommand(association, params, DUL_BLOCK, 0, &ctxID, &command, &messageType, &message);
    if (cond != SRV_NORMAL) return COND_PushCondition(SRV_REQUESTFAILED, SRV_Message(SRV_REQUESTFAILED), "SRV_CStoreRequest");

    if (messageType != MSG_K_C_STORE_RESP) {
    	(void) MSG_Free(&message);
    	return COND_PushCondition(SRV_UNEXPECTEDCOMMAND, SRV_Message(SRV_UNEXPECTEDCOMMAND), (int) command, "SRV_CStoreRequest");
    }
    response = (MSG_C_STORE_RESP *) message;
    if (storeResponse != NULL) *storeResponse = *response;

    cond = callback(storeRequest, response, objectSize, objectSize, callbackCtx);
    (void) MSG_Free(&message);
    if (cond != SRV_NORMAL)	return COND_PushCondition(SRV_CALLBACKABORTEDSERVICE, SRV_Message(SRV_CALLBACKABORTEDSERVICE), "SRV_CStoreRequest");

    return SRV_NORMAL;
}
void ZDO_NwkManager
(
  nlmeZdoMessage_t *pZdoMsg  /*IN: Message received from ZDO*/
)
{

  nlmeJoinIndication_t  *pJoinIndication;
  uint8_t aNwkAddr[2];
  
  (void)aNwkAddr;
  gMemoryFreedByApplication = FALSE;
  switch (pZdoMsg->msgType)
  {

    /*************************************************************************************
      NLME-Formation.confirm: Formation confirm is only available for PAN Coordinator
      devices or combo devices acting like coordinator.
    **************************************************************************************/
    case gNlmeNetworkFormationConfirm_c:

#if ( gCoordinatorCapability_d || gComboDeviceCapability_d)

#if gComboDeviceCapability_d
      /*
        If a combo device is not acting like a PAN Coordinator should not do any further
        processing.
      */
      if (NlmeGetRequest(gDevType_c) != gCoordinator_c)
      {
        break;
      }
#endif

      /* Send an event to the ZDO state machine informing the fromation status. */
      if (pZdoMsg->msgData.networkFormationConf.status == gZbSuccess_c)
      {
        ZDO_SendEvent(gZdoEvent_FormationSuccess_c);
      }
      else
      {
        ZDO_SendEvent(gZdoEvent_FormationFailure_c);
      }
#endif
    break;

    /*************************************************************************************
      NLME-Discovery.confirm
    **************************************************************************************/
    case gNlmeNetworkDiscoveryConfirm_c:
      /*
        If the device is trying to associate it self to a PAN, the state machine changes
        to be on gZdoDiscoveringNetworksState_c.
      */
      if (ZDO_GetState() == gZdoDiscoveringNetworksState_c)
      {
        ZdoEvent_t event;
        /*
          The discovery information have already been stored by the NWK layer.
          Free up the confirm.
        */
        if(pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL)
        {
          MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor );
        }

        /* send an event to state machine task depending on the confirmation */
        event = (pZdoMsg->msgData.networkDiscoveryConf.status == gZbSuccess_c)? gZdoEvent_DiscoverySuccess_c : gZdoEvent_DiscoveryFailure_c;
        ZDO_SendEvent(event);

        /*
          Setting this variable to FALSE means that ZDO will free the message and not the
          application.
        */
        gMemoryFreedByApplication = FALSE;
        break;
      }

      /***********************************************************************************
        For any of this cases the tables does not need to be arround so lets free
        up the memory. IMPORTANT: The tables need to be freed to avoid memory leaks.
      ************************************************************************************/
      NWK_FreeUpDiscoveryTables();

      /*
        If the device is on running state this means that it may be the application the
        one commanding the discovery.
      */
      if(ZDO_IsRunningState())
      {
        /* Reprot the discovery information to hte application. */
        ( void ) ZDP_APP_SapHandler((zdpToAppMessage_t *)pZdoMsg);

        /*
          Setting this variable to TRUE means that the application is responsible of
          freeing the list inside the discovery message.
        */
        gMemoryFreedByApplication = TRUE;
      }

      /*
        Management commands prevent the ZDO stae machine for doing anything but finishing
        the process of the remote command.
      */
      else if (ZDO_GetState() == gZdoRemoteCommandsState_c)
      {
#if gMgmt_NWK_Disc_rsp_d
        /* Generate the response through zdpmanager */
        Zdp_Mgmt_Send_Nwk_disc_conf( pZdoMsg );
#endif
        ZDO_SendEvent(gZdoEvent_ManagementResponse_c);

        /*
          The information was copied in ZDP so the list inside the packet is no longer
          needed.
        */
        if (pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL)
        {
          MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor );
        }

        /*
          Setting this variable to FALSE means that all the buffers are free, no need to
          re-free it.
        */
        gMemoryFreedByApplication = FALSE;
      }

      
      else
      {
        /* Clean up the discovery tables in the stack */
        NWK_FreeUpDiscoveryTables();
        if (pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL)
        {
          MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor );
        }
        gMemoryFreedByApplication = FALSE;
      }
    break;

    /*************************************************************************************
      NLME-Join.confirm: We have join TO SOME ONE.
    **************************************************************************************/
    case gNlmeJoinConfirm_c:
#if gRouterCapability_d || gEndDevCapability_d || gComboDeviceCapability_d
      /*
        Make sure that the discovery tables have been freed after join request has been
        processed.
      */
      NWK_FreeUpDiscoveryTables();      

      /* If a combo device is not router or end device should not proceed. */
#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gCoordinator_c)
      {
        break;
      }
#endif

      /*
        If the device is already on running state the node may receive the unsolicited
        rejoin response because of and addressconflict, so ignore the join confirm.
      */
      if (ZDO_IsRunningState())
        break;

      /* If the device is not running then force it to parse the confirm. */
      ZDO_SetState(gZdoJoiningState_c);

      /* Send an event to the ZDO state machine informing about the joining state. */
      if( pZdoMsg->msgData.joinConf.status == gZbSuccess_c )
      {
        ZDO_SendEvent(gZdoEvent_JoinSuccess_c);
      }
      else
      {
        ZDO_SendEvent(gZdoEvent_JoinFailure_c);
      }
#endif
    break;

    /*************************************************************************************
      NLME-Join.indication: A device has join TO US.
    **************************************************************************************/
    case gNlmeJoinIndication_c:
      /*
        Do the casting for the message one time and in one place, Code saving.
      */
      pJoinIndication = &pZdoMsg->msgData.joinIndication;

      /*
        To avoid reject packets when the node join and comunicate multi ple times,
        the devices should flush the APS Duplicate table.
      */
      APS_RemoveEntryFromApsDuplicateTable(pJoinIndication->aShortAddress);

      /* Every child joined to us must be record, to avoid lossing it in case of reset. */
      ZdoNwkMng_SaveToNvm(zdoNvmObject_NeighborTable_c);

#if gRnplusCapability_d
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) != gEndDevice_c)
#endif
      {
        /* Remove the old routes to the joining device */
        RemoveRouteEntry(pJoinIndication->aShortAddress);
      }
#endif
#endif


#if gStandardSecurity_d || gHighSecurity_d
      /* If the joining device is associated from scratch erase previous data. */
      if (pJoinIndication->rejoinNetwork == gAssociationJoin_c)
      {
        if (ApsmeGetRequest(gApsDefaultTCKeyType_c) == gTrustCenterLinkKey_c)
        {
          APS_ResetDeviceCounters(pJoinIndication->aExtendedAddress);
        }
        else
        {
          APS_RemoveSecurityMaterialEntry(pJoinIndication->aExtendedAddress);
        }

        /* Setting the last parameter to TRUE will erase APS secure material */
        ZDO_SecClearDeviceData(pJoinIndication->aShortAddress, pJoinIndication->aExtendedAddress, FALSE);
      }
      /*
        If security is active and the joining mode is other that association join,
        no further processing should be done to the join indication.
        Consider the unsecure join.
      */
      //else if ((pJoinIndication->rejoinNetwork == gNwkRejoin_c) && pJoinIndication->secureRejoin)
      //{
        /* Make sure the memory will be freed */
        //gMemoryFreedByApplication = FALSE;

        /* Do not process it further, no transport key will be needed. */
        //return;
      //}
      else if (pJoinIndication->rejoinNetwork == gNwkRejoin_c && !pJoinIndication->secureRejoin)
      {
        /* Reset the Incoming frame counter of the dev that has left. */
        /* Setting the last parameter to TRUE will erase APS secure material */
        if (ApsmeGetRequest(gApsDefaultTCKeyType_c) == gTrustCenterLinkKey_c)
        {
          APS_ResetDeviceCounters(pJoinIndication->aExtendedAddress);
        }
        else
        {
          APS_RemoveSecurityMaterialEntry(pJoinIndication->aExtendedAddress);
        }
        /* Setting the last parameter to TRUE will erase APS secure material */
        ZDO_SecClearDeviceData(pJoinIndication->aShortAddress, pJoinIndication->aExtendedAddress, FALSE);
      }

      /*
        The device must be set as Unauthenticated child in the NT.
      */
      SSP_NwkSetRelationship(pJoinIndication->aExtendedAddress, gUnAuthenticatedChild_c);

      /* Keep the buffer around to be use in the state machine or the application. */
      gMemoryFreedByApplication = TRUE;

/***************************************************
  Trust center specific join indication processing.
****************************************************/
#if gTrustCenter_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (gTrustCenter)
#endif
      {
        /*
          Keep the information, we are going to start the joining state machine.
        */
        MSG_Queue(&gJoinIndicationQueue, pZdoMsg);

        /*
          Tell the ZDO Task that we got a joining device packet and ready for action.
        */
        TS_SendEvent(gZdoTaskID_c, gJoinIndicationArrive_c);
      }
#endif

#if !gTrustCenter_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (!gTrustCenter)
#endif
      {
        uint8_t joiningType;
        bool_t  isHighSecurity = FALSE;
        /*
          Every other device with joining capabilities should report the joining,
          using an APSME-UPDATE-DEVICE.request.
        */
        isHighSecurity = (pJoinIndication->capabilityInformation & gSecurityCapability_c)? TRUE : FALSE;
        if (pJoinIndication->rejoinNetwork == gAssociationJoin_c)
        {
          joiningType = (isHighSecurity)? gHighSecurityDeviceUnsecuredJoin_c : gStandardDeviceUnsecuredJoin_c;
        }
        else if (pJoinIndication->rejoinNetwork == gNwkRejoin_c)
        {
          if (pJoinIndication->secureRejoin)
          {
            joiningType = (isHighSecurity)? gHighSecurityDeviceSecuredReJoin_c : gStandardDeviceSecuredReJoin_c;
          }
          else
          {
            joiningType = (isHighSecurity)? gHighSecurityDeviceUnsecuredRejoin_c : gStandardDeviceUnsecuredRejoin_c;
          }
        }

        // Always send the update device
        ZDO_APSME_Update_Device_request(pJoinIndication->aExtendedAddress,
                                        pJoinIndication->aShortAddress,
                                        joiningType,
                                        pJoinIndication->secureRejoin);
        (void)ZDP_APP_SapHandler((void *)pZdoMsg);
      }
#endif

/* #endif gStandardSecurity_d */
#endif
    break; /*break for join indication*/

    /*************************************************************************************
      NLME-StartRouter.confirm: Every time that a Coordinator or a Router starts, genrates
      a start router confirm.
    **************************************************************************************/
    case gNlmeStartRouterConfirm_c:
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

      /* Combo devices acting like ZED don't need this confirm. */
#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

      /* Indicate router has started (or not) */
      if (pZdoMsg->msgData.startRouterConf.status == gZbSuccess_c)
      {
        ZDO_SendEvent(gZdoEvent_StartRouterSuccess_c);
      }
      else
      {
        ZDO_SendEvent(gZdoEvent_StartRouterFailure_c);
      }
#endif
    break;

    /*************************************************************************************
      NLME-Sync.confirm
    **************************************************************************************/
    case gNlmeSyncConfirm_c:
#if gEndDevCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) != gEndDevice_c)
      {
        break;
      }
#endif
      pZdoMsg->msgType = gSyncConf_c;
      ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );
      /* The application is responsible of freen the buffers. */
      gMemoryFreedByApplication = TRUE;
#endif
    break;

    /*************************************************************************************
      NLME-PermitJoining.confirm
    **************************************************************************************/
    case gNlmePermitJoiningConfirm_c:
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

      if(ZDO_IsRunningState())
      {
        /* let application know about the permit join */
        pZdoMsg->msgType = gPermitjoinConf_c;
        ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );

        /* indicate this SAP handler won't be freeing the memory */
        gMemoryFreedByApplication = TRUE;
      }

#endif
      break;

    /*************************************************************************************
      NLME-DirectJoin.confirm
    **************************************************************************************/
    case gNlmeDirectJoinConfirm_c:
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

      /*
        The may come because the network layer start the direct join and the confirm must
        be pass up to the application.
      */
      if (ZDO_IsRunningState())
      {
        /* Send message on to app. Tell this SAP handler not to free it. */
        (void) ZDP_APP_SapHandler( (void *)pZdoMsg );
        gMemoryFreedByApplication = TRUE;
      }

      else if (ZDO_GetState() == gZdoRemoteCommandsState_c)
      {
        ZDO_SendEvent(gZdoEvent_ManagementResponse_c);
#if gMgmt_Direct_Join_rsp_d && (gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d)
#if gComboDeviceCapability_d
        if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
        {
          break;
        }
#endif
        /* Generate the response through zdpmanager */
        Zdp_Mgmt_Direct_Join_conf( pZdoMsg );
        /* Update the global variable to free the menory */
        gMemoryFreedByApplication = TRUE;
#endif
      }

#endif
      break;

    /*************************************************************************************
      NLME-Leave.indication
    **************************************************************************************/
    case gNlmeLeaveIndication_c:

      /* The local node is the one leaving the network. */
      if (Cmp8BytesToZero(pZdoMsg->msgData.leaveIndication.aDeviceAddress))
      {
        /* Only important to the local leave. Pick an appropiated leaving event. */
        ZdoStopMode_t stopMode;

        /*
          Send event to ZDO state machine to initiate the reset procedure (r11, p272, ln31)
          The devices should not set the default mode to stop the node on a leave indication,
          the default mode send another leave.... and we just left.
        */
        stopMode = gZdoStopModeDefault_c | gZdoStopMode;
        if (pZdoMsg->msgData.leaveIndication.rejoin)
        {
          /* We will come back.! */
          stopMode |= gZdoStopMode_StopAndRestart_c;

          /* We are doing rejoin, we should not clear the tables. */
          stopMode &= ~gZdoStopMode_ResetTables_c;

        } /* End of if (pZdoMsg->msgData.leaveIndication.rejoin) */

        /* Tell ZDO to pull the breaks; */
        ZDO_StopEx(stopMode);
        break;
      } /* End of if (Cmp8BytesToZero(pZdoMsg->msgData.leaveIndication.aDeviceAddress)) */

      /* If we got the indiction and we are waiting for it, return to previous state. */
      if (ZDO_GetState() == gZdoRemoteCommandsState_c)
      {
        ZDO_SendEvent(gZdoEvent_ManagementResponse_c);
      }

#if gStandardSecurity_d || gHighSecurity_d
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

      /*
        Reset the Incoming frame counter of the dev that has left.
      */
      SSP_NwkResetDeviceFrameCounter( pZdoMsg->msgData.leaveIndication.aDeviceAddress );

      /*
        If the device is Link capable remove the link key information if it exists.
      */
      APS_RemoveSecurityMaterialEntry(pZdoMsg->msgData.leaveIndication.aDeviceAddress);

      /*
        Let the trust center know about the leaving device.
      */
//      if (!IsSelfIeeeAddress(ApsmeGetRequest(gApsTrustCenterAddress_c)))
#if !gTrustCenter_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
       if (!gTrustCenter)
#endif
      
      {
        ZDO_APSME_Update_Device_request(pZdoMsg->msgData.leaveIndication.aDeviceAddress,
                                        APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr),
                                        gDeviceLeft_c, 0x00);
      }
#endif      
#endif
#endif

     /* ZEDs dont porcess the removing of the children and removing of the routes. */
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d
#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

#if gRnplusCapability_d
      /* Remove the old routes for the leaving device */
      RemoveRouteEntry(APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr));
#endif

      /* Clean up address map if there is no bindings referencing address map entry
         consider deleting all bindings first.
       */
      (void)APS_RemoveDeviceFromAddressMap(pZdoMsg->msgData.leaveIndication.aDeviceAddress);

      /* Tells the network layer to remove the leaving device from its tables. */
      NWK_RemoveChildRecords(pZdoMsg->msgData.leaveIndication.aDeviceAddress);
#endif

      /*
        Save the network data, to preserve that the leaving device is gone. Plus the
        counters for security (NWK and APS)that got reset.
      */
      ZdoNwkMng_SaveToNvm(zdoNvmObject_All_c);
    break;

    /*************************************************************************************
      NLME-Leave.confirm
    **************************************************************************************/
    case gNlmeLeaveConfirm_c:
      /* If we have received a management leave request, send the response */
      if (ZDO_GetState() == gZdoRemoteCommandsState_c)
      {
#if gMgmt_Leave_rsp_d
        Zdp_Mgmt_Send_leave_conf(pZdoMsg);
        /* The momery has been handled by the next higher layer. */
        gMemoryFreedByApplication = TRUE;
#endif
        ZDO_SendEvent(gZdoEvent_ManagementResponse_c);
      }

      /* The local node is the one leaving the network. */
      if (Cmp8BytesToZero(pZdoMsg->msgData.leaveConf.aDeviceAddress))
      {
        /* The self leave is handle in the indication. */
        break;
      }

#if gStandardSecurity_d || gHighSecurity_d
#if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d

#if gComboDeviceCapability_d
      if (NlmeGetRequest(gDevType_c) == gEndDevice_c)
      {
        break;
      }
#endif

      /*
        Reset the Incoming frame counter of the dev that has left.
      */
      SSP_NwkResetDeviceFrameCounter( pZdoMsg->msgData.leaveIndication.aDeviceAddress );

      /*
        If the device is Link capable remove the link key information if it exists.
      */
      APS_RemoveSecurityMaterialEntry(pZdoMsg->msgData.leaveIndication.aDeviceAddress);

      /*
        Let the trust center know about the leaving device.
      */
      ZDO_APSME_Update_Device_request(pZdoMsg->msgData.leaveIndication.aDeviceAddress,
                                      APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr),
                                      gDeviceLeft_c, 0x00);

      /*
        Tells the network layer to remove the leaving device from its tables.
      */
      NWK_RemoveChildRecords(pZdoMsg->msgData.leaveIndication.aDeviceAddress);
#endif

/* #endif gStandardSecurity_d */
#endif
    break;

    /*************************************************************************************
      NLME-RouteDiscovery.confirm
    **************************************************************************************/
    case  gNlmeNetworkStatusCnf_c:
    case  gNlmeRouteDiscoveryCnf_c:
      /* This packet will be freed by the application*/
      gMemoryFreedByApplication = TRUE;
      /* Pass the packet to the App */
      ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );
    break;

    /*************************************************************************************
      NLME-EnergyScan.confirm: An Energy Scan Confirm has come back. Was it due to the
      forming process, or due to FA/ZDP.
    **************************************************************************************/
    case  gNlmeEnergyScanConfirm_c:           
      
      if(ZDO_GetState() == gZdoDiscoveringNetworksState_c)
      {
        if (pZdoMsg->msgData.EnergyScanConf.status == gZbSuccess_c)
        {
          ZDO_SendEvent(gZdoEvent_EnergyScanComplete_c);
        }
        else
        {
          ZDO_StopEx(gZdoStopModeDefault_c);
        }
      }

      /* Send to application layer */
      ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );

      /* Update the global variable to free the memory */
      gMemoryFreedByApplication = TRUE;
    break;

    case gNlmeNetworkStatusInd_c:
    case gNlmeTxReport_c:
      /* Send to application layer */
      ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );

      /* Update the global variable to free the memory */
      gMemoryFreedByApplication = TRUE;
    break;

    case gNwkProcessFrameConf_c:
#if gStandardSecurity_d || gHighSecurity_d
      /* Send to application layer */
      ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg );

      /* Update the global variable to free the memory */
      gMemoryFreedByApplication = TRUE;
#else
      gMemoryFreedByApplication = FALSE;
#endif
    break;

    default:
    break;
  } /* End of switch */
}