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; }
AJ_Status AJ_ARDP_UDP_Connect(AJ_BusAttachment* bus, void* context, const AJ_Service* service, AJ_NetSocket* netSock) { AJ_Message hello; AJ_GUID localGuid; char guid_buf[33]; AJ_Status status; AJ_Message helloResponse; AJ_GetLocalGUID(&localGuid); AJ_GUID_ToString(&localGuid, guid_buf, sizeof(guid_buf)); AJ_MarshalMethodCall(bus, &hello, AJ_METHOD_BUS_SIMPLE_HELLO, AJ_BusDestination, 0, AJ_FLAG_ALLOW_REMOTE_MSG, AJ_UDP_CONNECT_TIMEOUT); AJ_MarshalArgs(&hello, "su", guid_buf, 10); hello.hdr->bodyLen = hello.bodyBytes; status = AJ_ARDP_Connect(bus->sock.tx.readPtr, AJ_IO_BUF_AVAIL(&bus->sock.tx), context, netSock); if (status != AJ_OK) { return status; } status = AJ_UnmarshalMsg(bus, &helloResponse, AJ_UDP_CONNECT_TIMEOUT); if (status == AJ_OK && helloResponse.msgId == AJ_REPLY_ID(AJ_METHOD_BUS_SIMPLE_HELLO)) { if (helloResponse.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_CONNECT; } else { AJ_Arg uniqueName, protoVersion; AJ_UnmarshalArg(&helloResponse, &uniqueName); AJ_SkipArg(&helloResponse); AJ_UnmarshalArg(&helloResponse, &protoVersion); /** * The two most-significant bits are reserved for the nameType, * which we don't currently care about in the thin client */ routingProtoVersion = (uint8_t) ((*protoVersion.val.v_uint32) & 0x3FFFFFFF); if (uniqueName.len >= (sizeof(bus->uniqueName) - 1)) { AJ_ErrPrintf(("AJ_ARDP_Connect(): AJ_ERR_RESOURCES\n")); status = AJ_ERR_RESOURCES; } else { memcpy(bus->uniqueName, uniqueName.val.v_string, uniqueName.len); bus->uniqueName[uniqueName.len] = '\0'; } /AJ_InfoPrintf(("Received name: %s and version %u\n", bus->uniqueName, routingProtoVersion)); if (routingProtoVersion < AJ_GetMinProtoVersion()) { AJ_InfoPrintf(("AJ_ARDP_Connect(): Blacklisting routing node, found %u but require >= %u\n", routingProtoVersion, AJ_GetMinProtoVersion())); AddRoutingNodeToBlacklist(service); status = AJ_ERR_CONNECT; } } }
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; }