Пример #1
0
void AJ_Initialize(void)
{
    AJ_GUID localGuid;
    if (!initialized) {
        initialized = TRUE;
        AJ_NVRAM_Init();
        /*
         * This will seed the random number generator
         */
        AJ_RandBytes(NULL, 0);
        /*
         * This will initialize credentials if needed
         */
        AJ_GetLocalGUID(&localGuid);

        /*
         * Clear the Routing Node black list
         */
        AJ_InitRoutingNodeBlacklist();

        AJ_InitRoutingNodeResponselist();
    }
}
Пример #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;
    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;
}
Пример #3
0
// TODO: deprecate this function; replace it with AJ_FindBusAndConnect
AJ_Status AJ_Connect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout)
{
    AJ_Status status;
    AJ_Service service;
    bus->isAuthenticated = FALSE;

    AJ_InfoPrintf(("AJ_Connect(bus=0x%p, serviceName=\"%s\", timeout=%d, selectionTimeout=%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;
    }
#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
    status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);
    if (status != AJ_OK) 
	{
        AJ_InfoPrintf(("AJ_Connect(): AJ_Discover status=%s\n", AJ_StatusText(status)));
        goto ExitConnect;
    }
#endif
    status = AJ_Net_Connect(bus, &service);
    if (status != AJ_OK)
	{
        AJ_InfoPrintf(("AJ_Connect(): AJ_Net_Connect status=%s\n", AJ_StatusText(status)));
        goto ExitConnect;
    }

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

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

ExitConnect:

    if (status != AJ_OK)
	{
        AJ_InfoPrintf(("AJ_Connect(): status=%s\n", AJ_StatusText(status)));
        AJ_Disconnect(bus);
    }
    AJ_InitRoutingNodeResponselist();
    return status;
}
Пример #4
0
AJ_Status AJ_SelectRoutingNodeFromResponseList(AJ_Service* service)
{
    /*
     * The selection involves choosing the router with the
     * highest protocol version and the lowest service priority
     * (inverse of static rank/score).
     */
    uint8_t i = 1;
    uint8_t selectedIndex = 0;
    uint32_t runningSum = 0;
    uint8_t skip = 0;
    uint32_t priority_idx = 0;
    uint32_t priority_srv = 0;
    uint32_t rand32 = 0;
    if (RNResponseList[0].ipv4 || RNResponseList[0].ipv4Udp) {
        service->ipv4 = RNResponseList[0].ipv4;
        service->ipv4port = RNResponseList[0].ipv4port;
        service->ipv4Udp = RNResponseList[0].ipv4Udp;
        service->ipv4portUdp = RNResponseList[0].ipv4portUdp;
        service->pv = RNResponseList[0].pv;
        service->addrTypes = RNResponseList[0].addrTypes;
        service->priority = RNResponseList[0].priority;
        runningSum = service->priority;
        skip = RNAttemptsList[0];
        if (skip) {
            AJ_InfoPrintf(("Index 0 was previously selected\n"));
        }
        for (; i  < AJ_ROUTING_NODE_RESPONSELIST_SIZE; ++i) {
            if (RNResponseList[i].ipv4 || RNResponseList[i].ipv4Udp) {
                if (RNAttemptsList[i]) {
                    AJ_InfoPrintf(("Index %d was previously selected\n", i));
                    continue;
                }
                if (skip) {
                    service->ipv4 = RNResponseList[i].ipv4;
                    service->ipv4port = RNResponseList[i].ipv4port;
                    service->ipv4Udp = RNResponseList[i].ipv4Udp;
                    service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                    service->pv = RNResponseList[i].pv;
                    service->addrTypes = RNResponseList[i].addrTypes;
                    service->priority = RNResponseList[i].priority;
                    selectedIndex = i;
                    runningSum = service->priority;
                    skip = 0;
                    continue;
                }
                if (RNResponseList[i].pv < service->pv) {
                    continue;
                }
                if (RNResponseList[i].pv > service->pv || (RNResponseList[i].pv == service->pv && RNResponseList[i].priority < service->priority)) {
                    service->ipv4 = RNResponseList[i].ipv4;
                    service->ipv4port = RNResponseList[i].ipv4port;
                    service->ipv4Udp = RNResponseList[i].ipv4Udp;
                    service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                    service->pv = RNResponseList[i].pv;
                    service->addrTypes = RNResponseList[i].addrTypes;
                    service->priority = RNResponseList[i].priority;
                    runningSum = service->priority;
                    selectedIndex = i;
                    AJ_InfoPrintf(("Tentatively selecting routing node %x (pv = %d, port = %d, priority = %d).\n", service->ipv4, service->pv, service->ipv4port, service->priority));
                } else if (RNResponseList[i].priority == service->priority) {
                    /*
                     * Randomly select one of out of all the routing nodes with the same
                     * protocol version and priority with each node given an equal chance
                     * of being selected. To select from a pair of nodes, the first node's
                     * priority is used as its associated sum, while the sum of the two
                     * priorities under consideration is used as the second node's
                     * associated sum. A uniform random number up to the sum of the two
                     * priorities (inclusive) is chosen and the first node whose associated
                     * sum is greater than or equal to the random number is selected.
                     */
                    rand32 = 0;
                    AJ_RandBytes((uint8_t*)&rand32, sizeof(rand32));
                    priority_idx = RNResponseList[i].priority + runningSum;
                    priority_srv = runningSum;
                    runningSum = priority_idx;
                    rand32 %= (runningSum + 1);
                    AJ_InfoPrintf(("P_idx is %u and P_srv is %u and random is %u\n", priority_idx, priority_srv, rand32));
                    if (rand32 > priority_srv) {
                        AJ_InfoPrintf(("Picking index %d on this round\n", i));
                        service->ipv4 = RNResponseList[i].ipv4;
                        service->ipv4port = RNResponseList[i].ipv4port;
                        service->ipv4Udp = RNResponseList[i].ipv4Udp;
                        service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                        service->pv = RNResponseList[i].pv;
                        service->addrTypes = RNResponseList[i].addrTypes;
                        service->priority = RNResponseList[i].priority;
                        selectedIndex = i;
                        AJ_InfoPrintf(("Tentatively selecting routing node 0x%x (pv = %d, port = %d, priority = %d).\n", service->ipv4, service->pv, service->ipv4port, service->priority));
                    }
                }
            } else {
                // break early if list isn't full
                break;
            }
        }
    } else {
        AJ_InitRoutingNodeResponselist();
        return AJ_ERR_TIMEOUT;
    }

    if (skip) {
        AJ_InfoPrintf(("All entries in the response list have been previously selected\n"));
        return AJ_ERR_END_OF_DATA;
    }
    RNAttemptsList[selectedIndex] = 1;
    AJ_InfoPrintf(("Selected routing node 0x%x (pv = %d, port = %d, priority = %d) out of %d responses in the list.\n", service->ipv4, service->pv, service->ipv4port, service->priority, RNResponseListIndex));
    return AJ_OK;
}
Пример #5
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;
}
Пример #6
0
// TODO: deprecate this function; replace it with AJ_FindBusAndConnect
AJ_Status AJ_Connect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout)
{
    AJ_Status status;
    AJ_Service service;
    bus->isAuthenticated = FALSE;

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

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

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

#if !(defined(ARDUINO) || defined(__linux) || defined(_WIN32) || defined(__MACH__))
    /*
     * Get an IP address.  We don't want to break this older version
     * of AJ_Connect, so acquire an IP if we don't already have one.
     *
     * This does not work on non-embedded platforms!
     */
    {
        uint32_t ip, mask, gw;
        status = AJ_AcquireIPAddress(&ip, &mask, &gw, AJ_DHCP_TIMEOUT);

        if (status != AJ_OK) {
            AJ_ErrPrintf(("AJ_Net_Up(): AJ_AcquireIPAddress Failed\n"));
        }
    }
#endif

    /*
     * Discover a daemon or service to connect to
     */
    if (!serviceName) {
        serviceName = daemonService;
    }
#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;
    status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Connect(): 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
    // in a way that depends on the target
    status = AJ_Serial_Up();
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Connect(): AJ_Serial_Up status=%s\n", AJ_StatusText(status)));
    }
#else
    status = AJ_Discover(serviceName, &service, timeout, selectionTimeout);
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Connect(): AJ_Discover status=%s\n", AJ_StatusText(status)));
        goto ExitConnect;
    }
#endif
    status = AJ_Net_Connect(bus, &service);
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Connect(): 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(("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_Connect(): AJ_Authenticate status=%s\n", AJ_StatusText(status)));
        goto ExitConnect;
    }

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


ExitConnect:

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