AJ_Status CPS_StartService(AJ_BusAttachment* bus, const char* busAddress, uint32_t timeout, uint8_t connected)
{
    AJ_Status status = AJ_OK;
    while (TRUE) {
        AJ_InfoPrintf(("Attempting to connect to bus '%s'\n", busAddress));

        status = AJ_Connect(bus, busAddress, timeout);
        if (status != AJ_OK) {
            AJ_ErrPrintf(("Failed to connect to bus '%s', sleeping for %d seconds...\n", busAddress, CPSC_CONNECT_PAUSE / 1000));
            AJ_Sleep(CPSC_CONNECT_PAUSE);
            continue;
        }

        AJ_InfoPrintf(("Connected successfully\n"));
        isBusConnected = TRUE;

        status = AJ_BusSetSignalRule(bus, CPSAnnounceMatch, AJ_BUS_SIGNAL_ALLOW);
        if (status != AJ_OK) {
            AJ_ErrPrintf(("Could not set Announcement Interface AddMatch\n"));
            return status;
        }
        break;
    }
    ;
    return status;
}
示例#2
0
static AJ_Status SetSignalRules(AJ_BusAttachment* bus)
{
    AJ_Status status = AJ_OK;
    /*
     * AJ_GUID needs the NameOwnerChanged signal to clear out entries in
     * its map.  Prior to router version 10 this means we must set a
     * signal rule to receive every NameOwnerChanged signal.  With
     * version 10 the router supports the arg[0,1,...] key in match
     * rules, allowing us to set a signal rule for just the
     * NameOwnerChanged signals of entries in the map.  See aj_guid.c
     * for usage of the arg key.
     */
    if (AJ_GetRoutingProtoVersion() < 11) 
	{
        status = AJ_BusSetSignalRule(bus, "type='signal',member='NameOwnerChanged',interface='org.freedesktop.DBus'", AJ_BUS_SIGNAL_ALLOW);
        if (status == AJ_OK) 
		{
            uint8_t found_reply = FALSE;
            AJ_Message msg;
            AJ_Time timer;
            AJ_InitTimer(&timer);

            while (found_reply == FALSE && AJ_GetElapsedTime(&timer, TRUE) < 3000) 
			{
                status = AJ_UnmarshalMsg(bus, &msg, 3000);
                if (status == AJ_OK) 
				{
                    switch (msg.msgId) 
					{
                    case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH):
                        found_reply = TRUE;
                        break;

                    default:
                        // ignore everything else
                        AJ_BusHandleBusMessage(&msg);
                        break;
                    }

                    AJ_CloseMsg(&msg);
                }
            }
        }
    }

    return status;
}
示例#3
0
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;
}
示例#4
0
AJ_Status AJ_Authenticate(AJ_BusAttachment* bus)
{
    AJ_Status status = AJ_OK;
    AJ_SASL_Context sasl;

    /*
     * Send initial NUL byte
     */
    bus->sock.tx.writePtr[0] = 0;
    bus->sock.tx.writePtr += 1;
    status = bus->sock.tx.send(&bus->sock.tx);
    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Authenticate(): status=%s\n", AJ_StatusText(status)));
        goto ExitConnect;
    }
    AJ_SASL_InitContext(&sasl, mechList, AJ_AUTH_RESPONDER, busAuthPwdFunc, FALSE);
    while (TRUE) {
        status = AuthAdvance(&sasl, &bus->sock.rx, &bus->sock.tx);
        if ((status != AJ_OK) || (sasl.state == AJ_SASL_FAILED)) {
            break;
        }
        if (sasl.state == AJ_SASL_AUTHENTICATED) {
            status = SendHello(bus);
            break;
        }
    }
    if (status == AJ_OK) {
        AJ_Message helloResponse;
        status = AJ_UnmarshalMsg(bus, &helloResponse, 5000);
        if (status == AJ_OK) {
            /*
             * The only error we might get is a timeout
             */
            if (helloResponse.hdr->msgType == AJ_MSG_ERROR) {
                status = AJ_ERR_TIMEOUT;
            } else {
                AJ_Arg arg;
                status = AJ_UnmarshalArg(&helloResponse, &arg);
                if (status == AJ_OK) {
                    if (arg.len >= (sizeof(bus->uniqueName) - 1)) {
                        AJ_ErrPrintf(("AJ_Authenticate(): AJ_ERR_RESOURCES\n"));
                        status = AJ_ERR_RESOURCES;
                    } else {
                        memcpy(bus->uniqueName, arg.val.v_string, arg.len);
                        bus->uniqueName[arg.len] = '\0';
                    }
                }
            }
            AJ_CloseMsg(&helloResponse);

            // 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);

            if (status == AJ_OK) {
                uint8_t found_reply = FALSE;
                AJ_Message msg;
                AJ_Time timer;
                AJ_InitTimer(&timer);

                while (found_reply == FALSE && AJ_GetElapsedTime(&timer, TRUE) < 3000) {
                    status = AJ_UnmarshalMsg(bus, &msg, 3000);
                    if (status == AJ_OK) {
                        switch (msg.msgId) {
                        case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH):
                            found_reply = TRUE;
                            break;

                        default:
                            // ignore everything else
                            AJ_BusHandleBusMessage(&msg);
                            break;
                        }

                        AJ_CloseMsg(&msg);
                    }
                }
            }
        }
    }

ExitConnect:

    if (status != AJ_OK) {
        AJ_InfoPrintf(("AJ_Authenticate(): status=%s\n", AJ_StatusText(status)));
    }
    return status;
}
示例#5
0
文件: aj_helper.c 项目: fonlabs/ajtcl
static
AJ_Status StartClient(AJ_BusAttachment* bus,
                      const char* daemonName,
                      uint32_t timeout,
                      uint8_t connected,
                      const char* name,
                      uint16_t port,
                      const char** interfaces,
                      uint32_t* sessionId,
                      char* serviceName,
                      const AJ_SessionOpts* opts)
{
    AJ_Status status = AJ_OK;
    AJ_Time timer;
    uint8_t found = FALSE;
    uint8_t clientStarted = FALSE;
    uint32_t elapsed = 0;
    char* rule;
    size_t ruleLen;
    const char* base = "interface='org.alljoyn.About',sessionless='t'";
    const char* impl = ",implements='";
    const char** ifaces;

    AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., interface=\"%p\", sessionId=0x%p, serviceName=0x%p, opts=0x%p)\n",
                   bus, daemonName, timeout, connected, interfaces, sessionId, serviceName, opts));

    AJ_InitTimer(&timer);

    if ((name == NULL && interfaces == NULL) ||
        (name != NULL && interfaces != NULL)) {
        return AJ_ERR_INVALID;
    }

    while (elapsed < timeout) {
        if (!connected) {
            status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT);
            elapsed = AJ_GetElapsedTime(&timer, TRUE);
            if (status != AJ_OK) {
                elapsed += AJ_CONNECT_PAUSE;
                if (elapsed > timeout) {
                    break;
                }
                AJ_WarnPrintf(("AJ_StartClient(): Failed to connect to bus, sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000));
                AJ_Sleep(AJ_CONNECT_PAUSE);
                continue;
            }
            AJ_InfoPrintf(("AJ_StartClient(): AllJoyn client connected to bus\n"));
        }
        if (name != NULL) {
            /*
             * Kick things off by finding the service names
             */
            status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING);
            AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n"));
        } else {
            /*
             * Kick things off by finding all services that implement the interface
             */
            ruleLen = strlen(base) + 1;
            ifaces = interfaces;
            while (*ifaces != NULL) {
                ruleLen += strlen(impl) + strlen(*ifaces) + 1;
                ifaces++;
            }
            rule = (char*) AJ_Malloc(ruleLen);
            if (rule == NULL) {
                status = AJ_ERR_RESOURCES;
                break;
            }
            strcpy(rule, base);
            ifaces = interfaces;
            while (*ifaces != NULL) {
                strcat(rule, impl);
                if ((*ifaces)[0] == '$') {
                    strcat(rule, &(*ifaces)[1]);
                } else {
                    strcat(rule, *ifaces);
                }
                strcat(rule, "'");
                ifaces++;
            }
            status = AJ_BusSetSignalRule(bus, rule, AJ_BUS_SIGNAL_ALLOW);
            AJ_InfoPrintf(("AJ_StartClient(): Client SetSignalRule: %s\n", rule));
            AJ_Free(rule);
        }
        if (status == AJ_OK) {
            break;
        }
        if (!connected) {
            AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s.\n", AJ_StatusText(status)));
            AJ_Disconnect(bus);
        }
    }
    if (elapsed > timeout) {
        AJ_WarnPrintf(("AJ_StartClient(): Client timed-out trying to connect to bus: status=%s.\n", AJ_StatusText(status)));
        return AJ_ERR_TIMEOUT;
    }
    timeout -= elapsed;

    if (status != AJ_OK) {
        return status;
    }

    *sessionId = 0;
    if (serviceName != NULL) {
        *serviceName = '\0';
    }

    while (!clientStarted && (status == AJ_OK)) {
        AJ_Message msg;
        status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT);
        if ((status == AJ_ERR_TIMEOUT) && !found) {
            /*
             * Timeouts are expected until we find a name or service
             */
            if (timeout < AJ_UNMARSHAL_TIMEOUT) {
                return status;
            }
            timeout -= AJ_UNMARSHAL_TIMEOUT;
            status = AJ_OK;
            continue;
        }
        if (status == AJ_ERR_NO_MATCH) {
            // Ignore unknown messages
            status = AJ_OK;
            continue;
        }
        if (status != AJ_OK) {
            AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status)));
            break;
        }
        switch (msg.msgId) {

        case AJ_REPLY_ID(AJ_METHOD_FIND_NAME):
        case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT):
            if (msg.hdr->msgType == AJ_MSG_ERROR) {
                AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error));
                status = AJ_ERR_FAILURE;
            } else {
                uint32_t disposition;
                AJ_UnmarshalArgs(&msg, "u", &disposition);
                if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) {
                    AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n"));
                    status = AJ_ERR_FAILURE;
                }
            }
            break;

        case AJ_SIGNAL_FOUND_ADV_NAME:
            {
                AJ_Arg arg;
                AJ_UnmarshalArg(&msg, &arg);
                AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string));
                found = TRUE;
                status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts);
            }
            break;

        case AJ_SIGNAL_ABOUT_ANNOUNCE:
            {
                uint16_t version, port;
                AJ_InfoPrintf(("AJ_StartClient(): AboutAnnounce from (%s)\n", msg.sender));
                if (!found) {
                    found = TRUE;
                    AJ_UnmarshalArgs(&msg, "qq", &version, &port);
                    status = AJ_BusJoinSession(bus, msg.sender, port, opts);
                    if (serviceName != NULL) {
                        strncpy(serviceName, msg.sender, AJ_MAX_NAME_SIZE);
                        serviceName[AJ_MAX_NAME_SIZE] = '\0';
                    }
                    if (status != AJ_OK) {
                        AJ_ErrPrintf(("AJ_StartClient(): BusJoinSession failed (%s)\n", AJ_StatusText(status)));
                    }
                }
            }
            break;

        case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION):
            {
                uint32_t replyCode;

                if (msg.hdr->msgType == AJ_MSG_ERROR) {
                    AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error));
                    status = AJ_ERR_FAILURE;
                } else {
                    status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId);
                    if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) {
                        clientStarted = TRUE;
                    } else {
                        AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION reply (%d)\n", replyCode));
                        status = AJ_ERR_FAILURE;
                    }
                }
            }
            break;

        case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
            /*
             * Force a disconnect
             */
            {
                uint32_t id, reason;
                AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason));
            }
            AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n"));
            status = AJ_ERR_READ;
            break;

        default:
            /*
             * Pass to the built-in bus message handlers
             */
            AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n"));
            status = AJ_BusHandleBusMessage(&msg);
            break;
        }
        AJ_CloseMsg(&msg);
    }
    if (status != AJ_OK && !connected) {
        AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s\n", AJ_StatusText(status)));
        AJ_Disconnect(bus);
    }
    return status;
}
示例#6
0
int AJ_Main(void)
{
    AJ_Status status = AJ_OK;
    uint8_t connected = FALSE;
    uint8_t done = FALSE;

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();
    AJ_RegisterObjects(NULL, proxyObjects);

    while (!done) {
        AJ_Message msg;

        if (!connected) {
            const char* announceRule = "type='signal',sessionless='t',interface='org.alljoyn.About',member='Announce'";
            status = AJ_FindBusAndConnect(&bus, NULL, AJ_CONNECT_TIMEOUT);
            if (status != AJ_OK) {
                AJ_WarnPrintf(("AJ_FindBusAndConnect(): failed - sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000));
                AJ_Sleep(AJ_CONNECT_PAUSE);
                continue;
            }
            AJ_AboutRegisterAnnounceHandlers(peerDescriptions, ArraySize(peerDescriptions));
            AJ_BusSetSignalRule(&bus, announceRule, AJ_BUS_SIGNAL_ALLOW);
            connected = TRUE;
        }

        status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT);
        if (AJ_ERR_TIMEOUT == status) {
            continue;
        }

        if (AJ_OK == status) {
            switch (msg.msgId) {
            case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION):
                if (msg.hdr->msgType != AJ_MSG_ERROR) {
                    uint32_t result;

                    status = AJ_UnmarshalArgs(&msg, "uu", &result, &sessionId);
                    if (status == AJ_OK) {
                        if (result == AJ_JOINSESSION_REPLY_SUCCESS) {
                            AJ_AlwaysPrintf(("joined session %u\n", sessionId));
                            DoCat();
                        } else {
                            AJ_AlwaysPrintf(("joined session rejected %d\n", result));
                        }
                    }
                } else {
                    AJ_ErrPrintf(("JoinSession reply was error: %s\n", msg.error));
                }
                break;

            case AJ_REPLY_ID(BASIC_CLIENT_CAT):
                if (msg.hdr->msgType != AJ_MSG_ERROR) {
                    AJ_Arg arg;
                    status = AJ_UnmarshalArg(&msg, &arg);
                    if (AJ_OK == status) {
                        AJ_AlwaysPrintf(("cat returned \"%s\"\n", arg.val.v_string));
                        if (!waitVar) {
                            done = TRUE;
                        }
                    }
                } else {
                    AJ_ErrPrintf(("Reply was error: %s\n", msg.error));
                }
                break;

            case AJ_SIGNAL_MP_SESSION_CHANGED_WITH_REASON:
                {
                    uint32_t sessId;
                    const char* peer;
                    uint32_t added;
                    uint32_t reason;

                    status = AJ_UnmarshalArgs(&msg, "usbu", &sessId, &peer, &added, &reason);
                    if (added) {
                        AJ_AlwaysPrintf(("Member \"%s\" added to session %u\n", peer, sessId));
                    } else {
                        AJ_AlwaysPrintf(("Member \"%s\" removed from session %u\n", peer, sessId));
                    }
                }
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                AJ_AlwaysPrintf(("Session lost\n"));
                break;

            default:
                /* Pass to the built-in handlers. */
                status = AJ_BusHandleBusMessage(&msg);
                break;
            }
        }

        /* Messages MUST be discarded to free resources. */
        AJ_CloseMsg(&msg);

        if (status == AJ_ERR_READ) {
            AJ_AlwaysPrintf(("Connection lost\n"));
            AJ_Disconnect(&bus);
            exit(0);
        }
    }
    AJ_AlwaysPrintf(("Basic client exiting with status %d.\n", status));
    return status;
}
示例#7
0
int AJ_Main()
{
    AJ_Status status;
    AJ_BusAttachment bus;
    int i;
    AJ_Initialize();
    AJ_PrintXML(AppObjects);
    AJ_RegisterObjects(AppObjects, NULL);

    Do_Connect(&bus);

    if (authenticate) {
        AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback);
    } else {
        authStatus = AJ_OK;
    }
    i = 0;
    while (commands[i] != NULL) {
        AJ_AlwaysPrintf(("%s\n", commands[i]));
        i++;
    }
    i = 0;
    while (TRUE) {
        // check for serial input and dispatch if needed.
        char buf[1024];
        AJ_Message msg;
        // read a line
        if (commands[i] != NULL) {
            char*command;
            strcpy(buf, commands[i]);
            AJ_AlwaysPrintf((">~~~%s\n", buf));
            command = aj_strtok(buf, " \r\n");
            i++;

            if (0 == strcmp("startservice", command)) {
                uint16_t port = 0;
                const char* name;
                AJ_SessionOpts opts;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    name = token;
                } else {
                    name = ServiceName;
                }
                token = aj_strtok(NULL, " \r\n");

                if (token) {
                    port = (uint16_t)atoi(token);
                }
                if (port == 0) {
                    port = ServicePort;
                }
                token = aj_strtok(NULL, " \r\n");

                if (token) {
                    opts.isMultipoint = (0 == strcmp("true", token));
                } else {
                    opts.isMultipoint = 0;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.traffic = atoi(token);
                } else {
                    opts.traffic = 0x1;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.proximity = atoi(token);
                } else {
                    opts.proximity = 0xFF;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.transports = atoi(token);
                } else {
                    opts.transports = 0xFFFF;
                }

                status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, TRUE, port, name, AJ_NAME_REQ_DO_NOT_QUEUE, &opts);
                AJ_BusAddSignalRule(&bus, "Chat", InterfaceName, AJ_BUS_SIGNAL_ALLOW);
            } else if (0 == strcmp("find", command)) {
                char* namePrefix = aj_strtok(NULL, " \r\n");
                if (!namePrefix) {
                    AJ_AlwaysPrintf(("Usage: find <name_prefix>\n"));
                    continue;
                }
                status = AJ_BusFindAdvertisedName(&bus, namePrefix, AJ_BUS_START_FINDING);
            } else if (0 == strcmp("cancelfind", command)) {
                char* namePrefix = aj_strtok(NULL, " \r\n");
                if (!namePrefix) {
                    AJ_AlwaysPrintf(("Usage: cancelfind <name_prefix>\n"));
                    continue;
                }
                status = AJ_BusFindAdvertisedName(&bus, namePrefix, AJ_BUS_STOP_FINDING);
            } else if (0 == strcmp("find2", command)) {
                char* namePrefix = aj_strtok(NULL, " \r\n");
                uint16_t transport = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    transport = (uint16_t)atoi(token);
                }
                if (!namePrefix || !transport) {
                    AJ_AlwaysPrintf(("Usage: find2 <name_prefix> <transport>\n"));
                    continue;
                }
                status = AJ_BusFindAdvertisedNameByTransport(&bus, namePrefix, transport, AJ_BUS_START_FINDING);
            } else if (0 == strcmp("cancelfind2", command)) {
                char* namePrefix = aj_strtok(NULL, " \r\n");
                uint16_t transport = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    transport = (uint16_t)atoi(token);
                }
                if (!namePrefix || !transport) {
                    AJ_AlwaysPrintf(("Usage: cancelfind2 <name_prefix> <transport>\n"));
                    continue;
                }
                status = AJ_BusFindAdvertisedNameByTransport(&bus, namePrefix, transport, AJ_BUS_STOP_FINDING);
            } else if (0 == strcmp("requestname", command)) {
                char* name = aj_strtok(NULL, " \r\n");
                if (!name) {
                    AJ_AlwaysPrintf(("Usage: requestname <name>\n"));
                    continue;
                }
                status = AJ_BusRequestName(&bus, name, AJ_NAME_REQ_DO_NOT_QUEUE);
            } else if (0 == strcmp("releasename", command)) {
                char* name = aj_strtok(NULL, " \r\n");
                if (!name) {
                    AJ_AlwaysPrintf(("Usage: releasename <name>\n"));
                    continue;
                }
                status = AJ_BusReleaseName(&bus, name);
            } else if (0 == strcmp("advertise", command)) {
                uint16_t transport = 0xFFFF;
                char* token = NULL;
                char* name = aj_strtok(NULL, " \r\n");
                if (!name) {
                    AJ_AlwaysPrintf(("Usage: advertise <name> [transports]\n"));
                    continue;
                }
                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    transport = (uint16_t)atoi(token);
                }
                status = AJ_BusAdvertiseName(&bus, name, transport, AJ_BUS_START_ADVERTISING, 0);
            } else if (0 == strcmp("canceladvertise", command)) {
                uint16_t transport = 0xFFFF;
                char* token = NULL;
                char* name = aj_strtok(NULL, " \r\n");
                if (!name) {
                    AJ_AlwaysPrintf(("Usage: canceladvertise <name> [transports]\n"));
                    continue;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    transport = (uint16_t)atoi(token);
                }
                status = AJ_BusAdvertiseName(&bus, name, transport, AJ_BUS_STOP_ADVERTISING, 0);
            } else if (0 == strcmp("bind", command)) {
                AJ_SessionOpts opts;
                uint16_t port = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    port = (uint16_t)atoi(token);
                }
                if (port == 0) {
                    AJ_AlwaysPrintf(("Usage: bind <port> [isMultipoint] [traffic] [proximity] [transports]\n"));
                    continue;
                }
                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.isMultipoint = (0 == strcmp("true", token));
                } else {
                    opts.isMultipoint = 0;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.traffic = atoi(token);
                } else {
                    opts.traffic = 0x1;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.proximity = atoi(token);
                } else {
                    opts.proximity = 0xFF;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.transports = atoi(token);
                } else {
                    opts.transports = 0xFFFF;
                }

                status = AJ_BusBindSessionPort(&bus, port, &opts, 0);
            } else if (0 == strcmp("unbind", command)) {
                uint16_t port = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    port = (uint16_t) atoi(token);
                }

                if (port == 0) {
                    AJ_AlwaysPrintf(("Usage: unbind <port>\n"));
                    continue;
                }
                status = AJ_BusUnbindSession(&bus, port);
            } else if (0 == strcmp("join", command)) {
                AJ_SessionOpts opts;
                uint16_t port = 0;
                char* name = aj_strtok(NULL, " \r\n");
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    port = (uint16_t)atoi(token);
                } else {
                    port = 0;
                }
                if (!name || (port == 0)) {
                    AJ_AlwaysPrintf(("Usage: join <name> <port> [isMultipoint] [traffic] [proximity] [transports]\n"));
                    continue;
                }
                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.isMultipoint = (0 == strcmp("true", token));
                } else {
                    opts.isMultipoint = 0;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.traffic = (uint8_t)atoi(token);
                } else {
                    opts.traffic = 0x1;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.proximity = (uint8_t)atoi(token);
                } else {
                    opts.proximity = 0xFF;
                }

                token = aj_strtok(NULL, " \r\n");
                if (token) {
                    opts.transports = (uint16_t)atoi(token);
                } else {
                    opts.transports = 0xFFFF;
                }

                status = AJ_BusJoinSession(&bus, name, port, &opts);
            } else if (0 == strcmp("leave", command)) {
                uint32_t sessionId = (uint32_t)atoi(aj_strtok(NULL, "\r\n"));
                if (sessionId == 0) {
                    AJ_AlwaysPrintf(("Usage: leave <sessionId>\n"));
                    continue;
                }
                status = AJ_BusLeaveSession(&bus, sessionId);
            } else if (0 == strcmp("addmatch", command)) {
                char* ruleString = aj_strtok(NULL, "\r\n");
                if (!ruleString) {
                    AJ_AlwaysPrintf(("Usage: addmatch <rule>\n"));
                    continue;
                }
                status = AJ_BusSetSignalRule(&bus, ruleString, AJ_BUS_SIGNAL_ALLOW);
            } else if (0 == strcmp("removematch", command)) {
                char* ruleString = aj_strtok(NULL, "\r\n");
                if (!ruleString) {
                    AJ_AlwaysPrintf(("Usage: removematch <rule>\n"));
                    continue;
                }
                status = AJ_BusSetSignalRule(&bus, ruleString, AJ_BUS_SIGNAL_DENY);
            }  else if (0 == strcmp("sendttl", command)) {
                int32_t ttl = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    ttl = atoi(token);
                }
                if (ttl < 0) {
                    AJ_AlwaysPrintf(("Usage: sendttl <ttl>\n"));
                    continue;
                }
                sendTTL = ttl;
            } else if (0 == strcmp("schat", command)) {
                char* chatMsg = aj_strtok(NULL, "\r\n");
                if (!chatMsg) {
                    AJ_AlwaysPrintf(("Usage: schat <msg>\n"));
                    continue;
                }
                status = AppSendChatSignal(&bus, 0, chatMsg, AJ_FLAG_SESSIONLESS, sendTTL);
            } else if (0 == strcmp("chat", command)) {
                char* sessionIdString = aj_strtok(NULL, " \r\n");
                char*chatMsg;

                uint32_t session = g_sessionId;
                if (sessionIdString != NULL) {
                    if (sessionIdString[0] != '#') {
                        session = (long)atoi(sessionIdString);
                    }
                }

                chatMsg = aj_strtok(NULL, "\r\n");
                status = AppSendChatSignal(&bus, session, chatMsg, 0, sendTTL);
            } else if (0 == strcmp("cancelsessionless", command)) {
                uint32_t serialId = 0;
                char* token = aj_strtok(NULL, " \r\n");
                if (token) {
                    serialId = (uint32_t)atoi(token);
                }
                if (serialId == 0) {
                    AJ_AlwaysPrintf(("Invalid serial number\n"));
                    AJ_AlwaysPrintf(("Usage: cancelsessionless <serialNum>\n"));
                    continue;
                }
                status = AJ_BusCancelSessionless(&bus, serialId);
            } else if (0 == strcmp("exit", command)) {
                break;
            } else if (0 == strcmp("help", command)) {
                //AJ_AlwaysPrintf(("debug <module_name> <level>                                   - Set debug level for a module\n"));
                AJ_AlwaysPrintf(("startservice [name] [port] [isMultipoint] [traffic] [proximity] [transports] - Startservice\n"));
                AJ_AlwaysPrintf(("requestname <name>                                            - Request a well-known name\n"));
                AJ_AlwaysPrintf(("releasename <name>                                            - Release a well-known name\n"));
                AJ_AlwaysPrintf(("bind <port> [isMultipoint] [traffic] [proximity] [transports] - Bind a session port\n"));
                AJ_AlwaysPrintf(("unbind <port>                                                 - Unbind a session port\n"));
                AJ_AlwaysPrintf(("advertise <name> [transports]                                 - Advertise a name\n"));
                AJ_AlwaysPrintf(("canceladvertise <name> [transports]                           - Cancel an advertisement\n"));
                AJ_AlwaysPrintf(("find <name_prefix>                                            - Discover names that begin with prefix\n"));
                AJ_AlwaysPrintf(("find2 <name_prefix> <transport>                               - Discover names that begin with prefix by specific transports\n"));
                AJ_AlwaysPrintf(("cancelfind <name_prefix>                                      - Cancel discovering names that begins with prefix\n"));
                AJ_AlwaysPrintf(("cancelfind2 <name_prefix> <transport>                         - Cancel discovering names that begins with prefix by specific transports\n"));
                AJ_AlwaysPrintf(("join <name> <port> [isMultipoint] [traffic] [proximity] [transports] - Join a session\n"));
                AJ_AlwaysPrintf(("leave <sessionId>                                             - Leave a session\n"));
                AJ_AlwaysPrintf(("chat <sessionId> <msg>                                        - Send a message over a given session\n"));
                AJ_AlwaysPrintf(("schat <msg>                                                   - Send a sessionless message\n"));
                AJ_AlwaysPrintf(("cancelsessionless <serialNum>                                 - Cancel a sessionless message\n"));
                AJ_AlwaysPrintf(("addmatch <rule>                                               - Add a DBUS rule\n"));
                AJ_AlwaysPrintf(("removematch <rule>                                            - Remove a DBUS rule\n"));
                AJ_AlwaysPrintf(("sendttl <ttl>                                                 - Set default ttl (in ms) for all chat messages (0 = infinite)\n"));
                AJ_AlwaysPrintf(("exit                                                          - Exit this program\n"));
                AJ_AlwaysPrintf(("\n"));
                continue;
            } else if (0 == strcmp("wait", command)) {
                char* token = aj_strtok(NULL, " \n\r");
                if (token) {
                    AJ_AlwaysPrintf(("Sleeping...\n"));
                    AJ_Sleep((uint16_t)atoi(token));
                    AJ_AlwaysPrintf(("Done\n"));
                }
            } else {
                AJ_AlwaysPrintf(("Unknown command: %s\n", command));
                continue;
            }
        }

        status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT);
        if (status != AJ_OK) {
            if (status == AJ_ERR_TIMEOUT) {
                AppDoWork();
                continue;
            }
        }

        if (status == AJ_OK) {
            switch (msg.msgId) {

            case AJ_METHOD_ACCEPT_SESSION:
                {
                    uint16_t port;
                    char* joiner;
                    AJ_AlwaysPrintf(("Accepting...\n"));
                    AJ_UnmarshalArgs(&msg, "qus", &port, &g_sessionId, &joiner);
                    status = AJ_BusReplyAcceptSession(&msg, TRUE);
                    if (status == AJ_OK) {
                        AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", g_sessionId, joiner));
                    } else {
                        AJ_InfoPrintf(("AJ_BusReplyAcceptSession: error %d\n", status));
                    }
                }
                break;

            case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION):
                {
                    uint32_t replyCode;

                    if (msg.hdr->msgType == AJ_MSG_ERROR) {
                        status = AJ_ERR_FAILURE;
                    } else {
                        status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, &g_sessionId);
                        if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) {
                            AJ_InfoPrintf(("Joined session session_id=%u\n", g_sessionId));
                            AJ_BusAddSignalRule(&bus, "Chat", InterfaceName, AJ_BUS_SIGNAL_ALLOW);
                        } else {
                            AJ_InfoPrintf(("Joined session failed\n"));
                        }
                    }
                }
                break;

            case APP_CHAT_SIGNAL:
                status = AppHandleChatSignal(&msg);
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                /*
                 * don't force a disconnect, be ready to accept another session
                 */
                {
                    uint32_t id, reason;
                    AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                    AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason));
                }
                break;

            case AJ_SIGNAL_FOUND_ADV_NAME:
                {
                    char* name;
                    char* namePrefix;
                    uint16_t transport;
                    AJ_UnmarshalArgs(&msg, "sqs", &name, &transport, &namePrefix);
                    AJ_AlwaysPrintf(("FoundAdvertisedName name=%s, namePrefix=%s\n", name, namePrefix));
                }
                break;

            default:
                /*
                 * Pass to the built-in handlers
                 */
                status = AJ_BusHandleBusMessage(&msg);
                break;
            }
        }
        /*
         * Messages must be closed to free resources
         */
        AJ_CloseMsg(&msg);

        if ((status == AJ_ERR_READ) || (status == AJ_ERR_WRITE) || (status == AJ_ERR_LINK_DEAD)) {
            AJ_AlwaysPrintf(("AllJoyn disconnect\n"));
            AJ_AlwaysPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus)));
            AJ_Disconnect(&bus);
            connected = FALSE;
            /*
             * Sleep a little while before trying to reconnect
             */
            AJ_Sleep(10 * 1000);
            Do_Connect(&bus);
        }
    }

    return 0;
}
AJ_Status AJApp_ConnectedHandler(AJ_BusAttachment* busAttachment)
{
    AJ_Status status = AJ_OK;
    if (AJ_GetUniqueName(busAttachment)) {
        if (currentServicesInitializationState == nextServicesInitializationState) {
            switch (currentServicesInitializationState) {
            case INIT_SERVICES_PORT:
                status = AJ_BusBindSessionPort(busAttachment, AJ_ABOUT_SERVICE_PORT, NULL, 0);
                if (status != AJ_OK) {
                    goto Exit;
                }
                nextServicesInitializationState = INIT_ADVERTISE_NAME;
                break;

            case INIT_ADVERTISE_NAME:
                status = AJ_BusAdvertiseName(busAttachment, AJ_GetUniqueName(busAttachment), AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0);
                if (status != AJ_OK) {
                    goto Exit;
                }
                if (addSessionLessMatch) {
                    nextServicesInitializationState = INIT_ADDSLMATCH;
                } else {
                    nextServicesInitializationState = INIT_FINISHED;
                }
                break;

            case INIT_ADDSLMATCH:
                status = AJ_BusSetSignalRule(busAttachment, SESSIONLESS_MATCH, AJ_BUS_SIGNAL_ALLOW);
                if (status != AJ_OK) {
                    goto Exit;
                }
                nextServicesInitializationState = INIT_FINISHED;
                break;

            case INIT_FINISHED:
                if (AJ_About_IsShouldAnnounce()) {
                    status = AJ_About_Announce(busAttachment);
                    if (status != AJ_OK) {
                        goto Exit;
                    }
                    AJ_About_SetShouldAnnounce(FALSE);
                }
#ifdef ONBOARDING_SERVICE
                if (!AJOBS_IsWiFiConnected()) {
                    status = AJ_ERR_RESTART;
                }
#endif
                break;
            }
        }
    }

Exit:

    if (status == AJ_ERR_RESOURCES) {
        init_retries++;
        if (init_retries > MAX_INIT_RETRIES) {
            status = AJ_ERR_READ; // Force disconnect
        } else {
            AJ_Sleep(AJAPP_SLEEP_TIME);
        }
    }
    return status;
}