AJ_Status AJ_FindBusAndConnect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout)
{
    AJ_Status status;
    AJ_Service service;
    AJ_Time connectionTimer;
    int32_t connectionTime;
    uint8_t finished = FALSE;
    bus->isAuthenticated = FALSE;
    bus->isProbeRequired = TRUE;

    AJ_InfoPrintf(("AJ_FindBusAndConnect(bus=0x%p, serviceName=\"%s\", timeout=%d, selection timeout=%d.)\n", bus, serviceName, timeout, selectionTimeout));

    // Clear the bus struct
    memset(bus, 0, sizeof(AJ_BusAttachment));
    // Clear stale name->GUID mappings
    AJ_GUID_ClearNameMap();

    // Discover a daemon or service to connect to
    if (!serviceName) 
	{
        serviceName = daemonService;
    }
    while (finished == FALSE) 
	{
        finished = TRUE;
        connectionTime = (int32_t) timeout;

#if AJ_CONNECT_LOCALHOST
        service.ipv4port = 9955;
		#if HOST_IS_LITTLE_ENDIAN
			service.ipv4 = 0x0100007F; // 127.0.0.1
		#endif
		#if HOST_IS_BIG_ENDIAN
			service.ipv4 = 0x7f000001; // 127.0.0.1
		#endif
        service.addrTypes = AJ_ADDR_TCP4;
		
#else
        AJ_InitTimer(&connectionTimer);
        printf("AJ_FindBusAndConnect(): Connection timer started\n");
        status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);//aj_disco.c
        if (status != AJ_OK) 
		{
            printf("AJ_FindBusAndConnect(): AJ_Discover status=%s\n", AJ_StatusText(status));
            goto ExitConnect;
        }
#endif

        // this calls into platform code that will decide whether to use UDP or TCP, based on what is available
		printf("TCP connection started \n");
        status = AJ_Net_Connect(bus, &service);
        if (status != AJ_OK)
		 {
            printf("AJ_FindBusAndConnect(): AJ_Net_Connect status=%s\n", AJ_StatusText(status));
            goto ExitConnect;
        }
		
        status = AJ_Authenticate(bus);
        if (status != AJ_OK)
		{
             printf("AJ_FindBusAndConnect(): AJ_Authenticate status=%s\n", AJ_StatusText(status));

#if ((!AJ_CONNECT_LOCALHOST) && (!defined(ARDUINO)) && (!defined(AJ_SERIAL_CONNECTION)))
             printf("AJ_FindBusAndConnect(): Blacklisting routing node\n");
			// какие-то махинации с  данными
            AddRoutingNodeToBlacklist(&service);
            // try again
            finished = FALSE;
            connectionTime -= AJ_GetElapsedTime(&connectionTimer, FALSE);
            // select a new node from the response list
            while (connectionTime > 0) 
			{
				// махинация с данными
                status = AJ_SelectRoutingNodeFromResponseList(&service);
                if (status == AJ_ERR_END_OF_DATA) 
				{
                    status = AJ_ERR_TIMEOUT;
                    //AJ_InfoPrintf(("Exhausted all the retries from the response list\n"));
                    finished = FALSE;
                    break;
                }
                 printf("Retrying with a new selection from the routing node response list\n");
                status = AJ_Net_Connect(bus, &service);
                if (status != AJ_OK) 
				{
                     printf("AJ_FindBusAndConnect(): AJ_Net_Connect status=%s\n", AJ_StatusText(status));
                    goto ExitConnect;
                }
                status = AJ_Authenticate(bus);
                if (status == AJ_OK) 
				{
                    finished = TRUE;
                    break;
                } 
				else
				{
                    connectionTime -= AJ_GetElapsedTime(&connectionTimer, FALSE);
                }
            }
#endif
        }

        if (status != AJ_OK) 
		{
             printf("AJ_FindBusAndConnect(): AJ_Authenticate status=%s\n", AJ_StatusText(status));
            goto ExitConnect;
        }

        status = SetSignalRules(bus);
        if (status != AJ_OK)
		{
             printf("AJ_FindBusAndConnect(): SetSignalRules status=%s\n", AJ_StatusText(status));
            goto ExitConnect;
        }

        AJ_InitRoutingNodeResponselist();
    }

ExitConnect:

    AJ_InitRoutingNodeResponselist();
    if (status != AJ_OK) 
	{
         printf("AJ_FindBusAndConnect(): status=%s\n", AJ_StatusText(status));
		//закрываем соединение
        AJ_Disconnect(bus);
    }

    return status;
}
Exemple #2
0
AJ_Status AJ_FindBusAndConnect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout)
{
    AJ_Status status;
    AJ_Service service;
    AJ_Time connectionTimer;
    int32_t connectionTime;
    uint8_t finished = FALSE;

#ifdef AJ_SERIAL_CONNECTION
    AJ_Time start, now;
    AJ_InitTimer(&start);
#endif

    AJ_InfoPrintf(("AJ_FindBusAndConnect(bus=0x%p, serviceName=\"%s\", timeout=%d, selection timeout=%d.)\n", bus, serviceName, timeout, selectionTimeout));

    /*
     * Clear the bus struct
     */
    memset(bus, 0, sizeof(AJ_BusAttachment));
    bus->isProbeRequired = TRUE;

    /*
     * Clear stale name->GUID mappings
     */
    AJ_GUID_ClearNameMap();

    /*
     * Discover a daemon or service to connect to
     */
    if (!serviceName) {
        serviceName = daemonService;
    }

    while (finished == FALSE) {
        finished = TRUE;
        connectionTime = (int32_t) timeout;

#if AJ_CONNECT_LOCALHOST
        service.ipv4port = 9955;
#if HOST_IS_LITTLE_ENDIAN
        service.ipv4 = 0x0100007F; // 127.0.0.1
#endif
#if HOST_IS_BIG_ENDIAN
        service.ipv4 = 0x7f000001; // 127.0.0.1
#endif
        service.addrTypes = AJ_ADDR_TCP4;
#elif defined(ARDUINO)
        service.ipv4port = 9955;
        service.ipv4 = 0x6501A8C0; // 192.168.1.101
        service.addrTypes = AJ_ADDR_TCP4;
        AJ_InitTimer(&connectionTimer);
        AJ_InfoPrintf(("AJ_FindBusAndConnect(): Connection timer started\n"));
        status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Discover status=%s\n", AJ_StatusText(status)));
            goto ExitConnect;
        }
#elif defined(AJ_SERIAL_CONNECTION)
        // don't bother with discovery, we are connected to a daemon.
        // however, take this opportunity to bring up the serial connection
        status = AJ_Serial_Up();
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Serial_Up status=%s\n", AJ_StatusText(status)));
        }
#else
        AJ_InitTimer(&connectionTimer);
        AJ_InfoPrintf(("AJ_FindBusAndConnect(): Connection timer started\n"));
        status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Discover status=%s\n", AJ_StatusText(status)));
            goto ExitConnect;
        }
#endif

        // this calls into platform code that will decide whether to use UDP or TCP, based on what is available
        status = AJ_Net_Connect(bus, &service);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Net_Connect status=%s\n", AJ_StatusText(status)));
            goto ExitConnect;
        }

#ifdef AJ_SERIAL_CONNECTION
        // run the state machine for long enough to (hopefully) do the SLAP handshake
        do {
            AJ_StateMachine();
            AJ_InitTimer(&now);
        } while (AJ_SerialLinkParams.linkState != AJ_LINK_ACTIVE && AJ_GetTimeDifference(&now, &start) < timeout);

        if (AJ_SerialLinkParams.linkState != AJ_LINK_ACTIVE) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): Failed to establish active SLAP connection in %u msec\n", timeout));
            AJ_SerialShutdown();
            return AJ_ERR_TIMEOUT;
        }
#endif

        status = AJ_Authenticate(bus);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Authenticate status=%s\n", AJ_StatusText(status)));
#if !AJ_CONNECT_LOCALHOST && !defined(ARDUINO) && !defined(AJ_SERIAL_CONNECTION)
            if ((status == AJ_ERR_ACCESS_ROUTING_NODE) || (status == AJ_ERR_OLD_VERSION)) {
                AJ_InfoPrintf(("AJ_FindBusAndConnect(): Blacklisting routing node\n"));
                AddRoutingNodeToBlacklist(&service, AJ_ADDR_TCP4);
            }
            AJ_Disconnect(bus);
            // try again
            finished = FALSE;
            connectionTime -= AJ_GetElapsedTime(&connectionTimer, FALSE);
            // select a new node from the response list
            while (connectionTime > 0) {
                status = AJ_SelectRoutingNodeFromResponseList(&service);
                if (status == AJ_ERR_END_OF_DATA) {
                    status = AJ_ERR_TIMEOUT;
                    AJ_InfoPrintf(("Exhausted all the retries from the response list\n"));
                    finished = FALSE;
                    break;
                }
                AJ_InfoPrintf(("Retrying with a new selection from the routing node response list\n"));
                status = AJ_Net_Connect(bus, &service);
                if (status != AJ_OK) {
                    AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Net_Connect status=%s\n", AJ_StatusText(status)));
                    goto ExitConnect;
                }
                status = AJ_Authenticate(bus);
                if (status == AJ_OK) {
                    finished = TRUE;
                    break;
                }
                if ((status == AJ_ERR_ACCESS_ROUTING_NODE) || (status == AJ_ERR_OLD_VERSION)) {
                    AJ_InfoPrintf(("AJ_FindBusAndConnect(): Blacklisting another routing node\n"));
                    AddRoutingNodeToBlacklist(&service, AJ_ADDR_TCP4);
                }
                AJ_Disconnect(bus);
                connectionTime -= AJ_GetElapsedTime(&connectionTimer, FALSE);
            }
#endif
        }

        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): AJ_Authenticate status=%s\n", AJ_StatusText(status)));
            goto ExitConnect;
        }

        status = SetSignalRules(bus);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("AJ_FindBusAndConnect(): SetSignalRules status=%s\n", AJ_StatusText(status)));
            goto ExitConnect;
        }

        AJ_InitRoutingNodeResponselist();
    }

ExitConnect:

    AJ_InitRoutingNodeResponselist();
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_FindBusAndConnect(): status=%s\n", AJ_StatusText(status)));
        AJ_Disconnect(bus);
    }

    return status;
}