Exemple #1
0
bool C4Network2ClientList::BroadcastMsgToClients(const C4NetIOPacket &rPkt)
{
	// Send a msg to all clients, including clients that are not connected to
	// this computer (will get forwarded by host).

	C4PacketFwd Fwd; Fwd.SetListType(true);
	// lock
	pIO->BeginBroadcast(false);
	// select connections for broadcast
	for (C4Network2Client *pClient = pFirst; pClient; pClient = pClient->getNext())
		if (!pClient->isHost())
			if (pClient->isConnected())
			{
				pClient->getMsgConn()->SetBroadcastTarget(true);
				Fwd.AddClient(pClient->getID());
			}
	// broadcast
	bool fSuccess = pIO->Broadcast(rPkt);
	// unlock
	pIO->EndBroadcast();
	// clients: send forward request to host
	if (!fHost)
	{
		Fwd.SetData(rPkt);
		fSuccess &= SendMsgToHost(MkC4NetIOPacket(PID_FwdReq, Fwd));
	}
	return fSuccess;
}
Exemple #2
0
bool C4Network2ClientList::SendMsgToClient(int32_t iClient, C4NetIOPacket RREF rPkt)
{
	// find client
	C4Network2Client *pClient = GetClientByID(iClient);
	if (!pClient) return false;
	// connected? send directly
	if (pClient->isConnected())
		return pClient->SendMsg(rPkt);
	// forward
	C4PacketFwd Fwd; Fwd.SetListType(false);
	Fwd.AddClient(iClient);
	Fwd.SetData(rPkt);
	return SendMsgToHost(MkC4NetIOPacket(PID_FwdReq, Fwd));
}
/* Function: rt_ExtModeShutdown ================================================
 * Abstract:
 *  Called when target program terminates to enable cleanup of external 
 *  mode.
 */
PUBLIC boolean_T rt_ExtModeShutdown(SimStruct *S)
{
    boolean_T error = EXT_NO_ERROR;

    /*
     * Make sure buffers are flushed so that the final points get to
     * host (this is important for the case of the target reaching tfinal
     * while data is uploading is in progress).
     */
    UploadPrepareForFinalFlush();
    rt_UploadServerWork(S);
    
    UploadLogInfoTerm();
    if (msgBuf != NULL) free(msgBuf);
    
    if (connected) {
        error = SendMsgToHost(EXT_MODEL_SHUTDOWN, 0, NULL);
        if (error != EXT_NO_ERROR) {
            fprintf(stderr,
                "\nError sending 'EXT_MODEL_SHUTDOWN' message to host.\n");
        }
        connected = FALSE;
        commInitialized = FALSE;
        modelStatus = TARGET_STATUS_WAITING_TO_START;        
    }

    ExtShutDown(extUD);
    ExtUserDataDestroy(extUD);

    /* For internal Mathworks testing only */
#ifdef TMW_GRT_TESTING
# ifdef WIN32
    (void)system("del /f batmarker");
# else
    (void)system("rm -f batmarker");
# endif
#endif
        
    return(error);
} /* end rt_ExtModeShutdown */
/* Function: ProcessSetParamMsg ================================================
 * Receive and process the EXT_SETPARAM message.
 */
PRIVATE boolean_T ProcessSetParamMsg(SimStruct *S, const int msgSize)
{
    const char  *msg;
    boolean_T   error = EXT_NO_ERROR;

    /*
     * Receive message and set parameters.
     */
    msg = GetMsg(msgSize);
    if (msg == NULL) {
        error = EXT_ERROR; goto EXIT_POINT;
    }
    SetParam(S, msg);

    /*
     * Send response to host. 
     */
    error = SendMsgToHost(EXT_SETPARAM_RESPONSE, 0, NULL);
    if (error != EXT_NO_ERROR) goto EXIT_POINT;

EXIT_POINT:
    return(error);
} /* end ProcessSetParamMsg */
/* Function: rt_MsgServerWork ==================================================
 * Abstract:
 *  If not connected, establish communication of the message line and the
 *  data upload line.  If connected, send/receive messages and parameters
 *  on the message line.
 */
PUBLIC boolean_T rt_MsgServerWork(SimStruct *S)
{
    MsgHeader  msgHdr;
    boolean_T  hdrAvail;
    boolean_T  error             = EXT_NO_ERROR;
    boolean_T  disconnectOnError = FALSE;
    
    /*
     * If not connected, attempt to make connection to host.
     */
    if (!connected) {
        error = ExtOpenConnection(extUD,&connected);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
    }

    /*
     * If ExtOpenConnection is not blocking and there are no pending
     * requests to open a connection, we'll still be unconnected.
     */
    if (!connected) goto EXIT_POINT; /* nothing do do */
    
    /*
     * Process messages.
     */

    /* Wait for a message. */
    error = GetMsgHdr(&msgHdr, &hdrAvail);
    if (error != EXT_NO_ERROR) {
        printf("\nError occured getting message header.\n");
        disconnectOnError = TRUE;
        goto EXIT_POINT;
    }
    
    if (!hdrAvail) goto EXIT_POINT; /* nothing to do */

    /*
     * This is the first message.  Should contain the string:
     * 'ext-mode'.  Its contents are not important to us.
     * It is used as a flag to start the handshaking process.
     */
    if (!commInitialized) {
        msgHdr.type = EXT_CONNECT;
    }

    /* 
     * At this point we know that we have a message: process it.
     */
    switch(msgHdr.type) {

    case EXT_GET_TIME:
    {
        time_T t = ssGetT(S);

        /* Skip verbosity print out - we get too many of these */
        /*PRINT_VERBOSE(("got EXT_GET_TIME message.\n"));*/

        error = SendMsgToHost(
            EXT_GET_TIME_RESPONSE,sizeof(time_T),(char_T *)&t);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_ARM_TRIGGER:
    {
        PRINT_VERBOSE(("got EXT_ARM_TRIGGER message.\n"));
        UploadArmTrigger();
        break;
    }

    case EXT_SELECT_SIGNALS:
    {
        const char *msg;

        PRINT_VERBOSE(("got EXT_SELECT_SIGNALS message.\n"));

        msg = GetMsg(msgHdr.size);
        if (msg == NULL) {
            error = EXT_ERROR;
            goto EXIT_POINT;
        }

        error = UploadLogInfoInit(S, msg);
        if (error != NO_ERR) {
            printf(
                "\nError in UploadLogInfoInit(). Most likely a memory\n"
                "allocation error or an attempt to re-initialize the\n"
                "signal selection during the data logging process\n"
                "(i.e., multiple EXT_SELECT_SIGNAL messages were received\n"
                "before the logging session terminated or an\n"
                "EXT_CANCEL_LOGGING message was received)");

            goto EXIT_POINT;
        }
        break;
    }

    case EXT_SELECT_TRIGGER: 
    {
        const char *msg;

        PRINT_VERBOSE(("got EXT_SELECT_TRIGGER message.\n"));

        msg = GetMsg(msgHdr.size);
        if (msg == NULL) {
            error = EXT_ERROR;
            goto EXIT_POINT;
        }

        error = UploadInitTrigger(S, msg);
        if (error != EXT_NO_ERROR) {
            printf("\nError in UploadInitTrigger\n");
            goto EXIT_POINT;
        }
        break;
    }

    case EXT_CONNECT:
    {
        PRINT_VERBOSE(("got EXT_CONNECT message.\n"));
        error = ProcessConnectMsg(S);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_SETPARAM:
    {
        PRINT_VERBOSE(("got EXT_SETPARAM message.\n"));
        error = ProcessSetParamMsg(S, msgHdr.size);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_GETPARAMS:
    {
        PRINT_VERBOSE(("got EXT_GETPARAMS message.\n"));
        error = ProcessGetParamsMsg(S);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;
        break;
    }

    case EXT_DISCONNECT_REQUEST:
    {
        PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST message.\n"));
        
        /*
         * Note that from the target's point of view this is
         * more a "notify" than a "request".  The host needs to
         * have this acknowledged before it can begin closing
         * the connection.
         */
        error = SendMsgToHost(EXT_DISCONNECT_REQUEST_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        DisconnectFromHost(S);

        break;
    }

    case EXT_MODEL_START:
        PRINT_VERBOSE(("got EXT_MODEL_START message.\n"));
#ifdef VXWORKS
        {
            extern SEM_ID startStopSem;
            semGive(startStopSem);
        }
#endif
        startModel = TRUE;
        error = SendMsgToHost(EXT_MODEL_START_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_STOP:
        PRINT_VERBOSE(("got EXT_MODEL_STOP message.\n"));
        ssSetStopRequested(S, TRUE);
        break;

    case EXT_MODEL_PAUSE:
        PRINT_VERBOSE(("got EXT_MODEL_PAUSE message.\n"));
        modelStatus = TARGET_STATUS_PAUSED;
        startModel  = FALSE;

        error = SendMsgToHost(EXT_MODEL_PAUSE_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_STEP:
        PRINT_VERBOSE(("got EXT_MODEL_STEP message.\n"));
        if ((modelStatus == TARGET_STATUS_PAUSED) && !startModel) {
            startModel = TRUE;
        }
        
        error = SendMsgToHost(EXT_MODEL_STEP_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_MODEL_CONTINUE:
        PRINT_VERBOSE(("got EXT_MODEL_CONTINUE message.\n"));
        if (modelStatus == TARGET_STATUS_PAUSED) {
            modelStatus = TARGET_STATUS_RUNNING;
            startModel  = FALSE;
        }
        
        error = SendMsgToHost(EXT_MODEL_CONTINUE_RESPONSE, 0, NULL);
        if (error != EXT_NO_ERROR) goto EXIT_POINT;

        break;

    case EXT_CANCEL_LOGGING:
        PRINT_VERBOSE(("got EXT_CANCEL_LOGGING message.\n"));
        UploadCancelLogging();
        break;

    default:
        fprintf(stderr,"received invalid message.\n");
        break;
    } /* end switch */

EXIT_POINT:
    if (error != EXT_NO_ERROR) {
        if (disconnectOnError) {
            fprintf(stderr,
                "Error occured in rt_MsgServerWork.\n"
                "Disconnecting from host!\n");
            DisconnectFromHost(S);
            
            /*
             * Patch by Gopal Santhanam 5/25/2002 (for VXWORKS)
             * If there there was a problem and we have already disconnected
             * from the host, there is no point in returning that error
             * back to rt_MsgServer.  That would cause the task servicing
             * external messages to quit.  Once disconnected, we could
             * just as easily resume by waiting for a new connection.
             */
#ifdef VXWORKS
            error = EXT_NO_ERROR;
#endif            
        }
    }

    return(error);
} /* end rt_MsgServerWork */