AJ_Status AJ_FindBusAndConnect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout) { AJ_Status status; AJ_Service service; #ifdef AJ_SERIAL_CONNECTION AJ_Time start, now; AJ_InitTimer(&start); #endif AJ_InfoPrintf(("AJ_Connect(bus=0x%p, serviceName=\"%s\", timeout=%d.)\n", bus, serviceName, timeout)); /* * 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_IPV4; #elif defined ARDUINO service.ipv4port = 9955; service.ipv4 = 0x6501A8C0; // 192.168.1.101 service.addrTypes = AJ_ADDR_IPV4; status = AJ_Discover(serviceName, &service, timeout); 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 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); if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Connect(): AJ_Discover status=%s\n", AJ_StatusText(status))); goto ExitConnect; } #endif status = AJ_Net_Connect(&bus->sock, service.ipv4port, service.addrTypes & AJ_ADDR_IPV4, &service.ipv4); 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; } // subscribe to the signal NameOwnerChanged and wait for the response status = AJ_BusSetSignalRule(bus, "type='signal',member='NameOwnerChanged',interface='org.freedesktop.DBus'", AJ_BUS_SIGNAL_ALLOW); ExitConnect: if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Connect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
// 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; }
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; }
static AJ_Status ConnectToBus(AJ_BusAttachment* bus) { AJ_Status status; AJ_Service service; uint32_t timeout = AJ_CONNECT_TIMEOUT; #ifdef AJ_SERIAL_CONNECTION AJ_Time start, now; AJ_InitTimer(&start); #endif AJ_InfoPrintf(("AJ_Connect(bus=0x%p, serviceName=\"%s\", timeout=%d.)\n", bus, serviceName, timeout)); /* * Clear the bus struct */ memset(bus, 0, sizeof(AJ_BusAttachment)); /* * Clear stale name->GUID mappings */ AJ_GUID_ClearNameMap(); /* * First we need to discover a routing node. This is done with the function AJ_Discover. * It will store the connection information in the AJ_Service struct. */ #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_IPV4; #elif defined ARDUINO service.ipv4port = 9955; service.ipv4 = 0x6501A8C0; // 192.168.1.101 service.addrTypes = AJ_ADDR_IPV4; status = AJ_Discover(serviceName, &service, timeout); 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 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); if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Connect(): AJ_Discover status=%s\n", AJ_StatusText(status))); goto ExitConnect; } #endif /* * Now that we have discovered a routing node, we can connect to it. This is done with AJ_Net_Connect. */ status = AJ_Net_Connect(&bus->sock, service.ipv4port, service.addrTypes & AJ_ADDR_IPV4, &service.ipv4); if (status != AJ_OK) { // or retry discovery to find another node that will accept our connection 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 /* * We are connected to a routing node! We still need to authenticate with it * before it will route our messages. */ status = AJ_Authenticate(bus); ExitConnect: if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Connect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }