Exemplo n.º 1
0
static AJ_Status AJApp_ConnectedHandler(AJ_BusAttachment* busAttachment)
{
    AJ_Status status = AJ_OK;

    if (AJ_GetUniqueName(busAttachment)) {
        if (currentServicesInitializationState == nextServicesInitializationState) {
            switch (currentServicesInitializationState) {
            case INIT_SERVICES:
                status = AJSVC_ConnectedHandler(busAttachment);
                if (status != AJ_OK) {
                    goto ErrorExit;
                }
                currentServicesInitializationState = nextServicesInitializationState = INIT_SERVICES_PORT;
                break;

            case INIT_SERVICES_PORT:
                status = AJ_BusBindSessionPort(busAttachment, AJ_ABOUT_SERVICE_PORT, NULL, 0);
                if (status != AJ_OK) {
                    goto ErrorExit;
                }
                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 ErrorExit;
                }
                currentServicesInitializationState = nextServicesInitializationState = INIT_ABOUT;
                break;

            case INIT_ABOUT:
                status = AJ_AboutInit(busAttachment, AJ_ABOUT_SERVICE_PORT);
                if (status != AJ_OK) {
                    goto ErrorExit;
                }
                currentServicesInitializationState = nextServicesInitializationState = INIT_CHECK_ANNOUNCE;
                break;

            case INIT_CHECK_ANNOUNCE:
                status = AJ_AboutAnnounce(busAttachment);
                if (status != AJ_OK) {
                    goto ErrorExit;
                }
                break;

            default:
                break;
            }
        }
    }
    return status;

ErrorExit:

    AJ_ErrPrintf(("Application ConnectedHandler returned an error %s\n", (AJ_StatusText(status))));
    return status;
}
Exemplo n.º 2
0
static uint8_t AJRouter_Connect(AJ_BusAttachment* busAttachment, const char* routerName)
{
    AJ_Status status;
    const char* busUniqueName;

    while (TRUE) {
        AJ_InfoPrintf(("Attempting to connect to bus '%s'\n", routerName));
        status = AJ_FindBusAndConnect(busAttachment, routerName, AJAPP_CONNECT_TIMEOUT);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("Failed to connect to bus sleeping for %d seconds\n", AJAPP_CONNECT_PAUSE / 1000));
            AJ_Sleep(AJAPP_CONNECT_PAUSE);
            continue;
        }
        busUniqueName = AJ_GetUniqueName(busAttachment);
        if (busUniqueName == NULL) {
            AJ_ErrPrintf(("Failed to GetUniqueName() from newly connected bus, retrying\n"));
            continue;
        }
        AJ_InfoPrintf(("Connected to router with BusUniqueName=%s\n", busUniqueName));
        break;
    }

    /* Setup password based authentication listener for secured peer to peer connections */
    AJ_BusSetPasswordCallback(busAttachment, PasswordCallback);

    /* Configure timeout for the link to the Router bus */
    AJ_SetBusLinkTimeout(busAttachment, 60);     // 60 seconds

    return TRUE;
}
Exemplo n.º 3
0
static uint8_t IsRelevant(const char* sender)
{
    /*
     * Ignore our own announcements
     */
    return !sessionId && (strcmp(sender, AJ_GetUniqueName(&bus)) != 0);
}
Exemplo n.º 4
0
uint8_t AJRouter_Connect(AJ_BusAttachment* busAttachment, const char* routerName)
{
    while (TRUE) {
        AJ_Status status = AJ_OK;
#ifdef ONBOARDING_SERVICE
        status = AJOBS_EstablishWiFi();
        if (status != AJ_OK) {
            AJ_AlwaysPrintf(("Failed to establish WiFi connectivity with status=%s\n", AJ_StatusText(status)));
            AJ_Sleep(AJAPP_CONNECT_PAUSE);
            return FALSE;
        }
#endif
        AJ_AlwaysPrintf(("Attempting to connect to bus '%s'\n", routerName));
        status = AJ_FindBusAndConnect(busAttachment, routerName, AJAPP_CONNECT_TIMEOUT);
        if (status != AJ_OK) {
            AJ_AlwaysPrintf(("Failed to connect to bus sleeping for %d seconds\n", AJAPP_CONNECT_PAUSE / 1000));
            AJ_Sleep(AJAPP_CONNECT_PAUSE);
#ifdef ONBOARDING_SERVICE
            if (status == AJ_ERR_DHCP) {
                AJOBS_SwitchToRetry();
            }
#endif
            continue;
        }
        const char* busUniqueName = AJ_GetUniqueName(busAttachment);
        if (busUniqueName == NULL) {
            AJ_AlwaysPrintf(("Failed to GetUniqueName() from newly connected bus, retrying\n"));
            continue;
        }
        AJ_AlwaysPrintf(("Connected to router with BusUniqueName=%s\n", busUniqueName));
        break;
    }
    return TRUE;
}
static AJ_Status AJApp_ConnectedHandler(AJ_BusAttachment* busAttachment)
{
    AJ_Status status = AJ_OK;

    if (AJ_GetUniqueName(busAttachment)) {
        if (currentServicesInitializationState == nextServicesInitializationState) {
            switch (currentServicesInitializationState) {
            case INIT_SERVICES:
                status = AJSVC_ConnectedHandler(busAttachment);
                if (status != AJ_OK) {
                    goto ErrorExit;
                }
                currentServicesInitializationState = nextServicesInitializationState = INIT_FINISHED;
                break;

            case INIT_FINISHED:
            default:
                break;
            }
        }
    }
    return status;

ErrorExit:

    AJ_ErrPrintf(("Application ConnectedHandler returned an error %s\n", (AJ_StatusText(status))));
    return status;
}
Exemplo n.º 6
0
AJ_Status AJApp_DisconnectHandler(AJ_BusAttachment* busAttachment, uint8_t restart)
{
    AJ_Status status = AJ_OK;

    if (restart) {
        AJ_BusAdvertiseName(busAttachment, AJ_GetUniqueName(busAttachment), AJ_TRANSPORT_ANY, AJ_BUS_STOP_ADVERTISING, 0);
        AJ_BusUnbindSession(busAttachment, AJ_ABOUT_SERVICE_PORT);
    }

    AJ_About_SetShouldAnnounce(TRUE);
    currentServicesInitializationState = nextServicesInitializationState = INIT_START;
    init_retries = 0;

    return status;
}
Exemplo n.º 7
0
void Do_Connect(AJ_BusAttachment* bus)
{
    while (!connected) {
        AJ_Status status;
        AJ_InfoPrintf(("Attempting to connect to bus\n"));
        status = AJ_FindBusAndConnect(bus, NULL, CONNECT_TIMEOUT);
        if (status != AJ_OK) {
            AJ_InfoPrintf(("Failed to connect to bus sleeping for %lu seconds\n", CONNECT_PAUSE / 1000));
            AJ_Sleep(CONNECT_PAUSE);
            continue;
        }
        connected = TRUE;
        AJ_BusAddSignalRule(bus, "Chat", InterfaceName, AJ_BUS_SIGNAL_ALLOW);
        AJ_InfoPrintf(("AllJoyn service connected to bus\n"));
        AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(bus)));
    }
}
/**
 * Send Notification - see notes in h file
 */
AJ_Status AJNS_Producer_SendNotification(AJ_BusAttachment* busAttachment, AJNS_NotificationContent* content, uint16_t messageType, uint32_t ttl, uint32_t* messageSerialNumber)
{
    AJ_Status status;
    AJNS_Notification notification;
    uint32_t serialNumber;

  //  AJ_InfoPrintf(("In SendNotification\n"));

    notification.version = AJNS_NotificationVersion;
    if (messageType >= AJNS_NUM_MESSAGE_TYPES)
	{
        AJ_ErrPrintf(("Could not Send Notification - MessageType is not valid\n"));
        return AJ_ERR_DISALLOWED;
    }
    notification.messageType = messageType;

    if ((ttl < AJNS_NOTIFICATION_TTL_MIN) || (ttl > AJNS_NOTIFICATION_TTL_MAX)) 
	{      //ttl is mandatory and must be in range
        AJ_ErrPrintf(("TTL '%u' is not a valid TTL value\n", ttl));
        return AJ_ERR_DISALLOWED;
    }

    notification.deviceId = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_DEVICE_ID);
    notification.deviceName = AJSVC_PropertyStore_GetValueForLang(AJSVC_PROPERTY_STORE_DEVICE_NAME, AJSVC_PropertyStore_GetLanguageIndex(""));
    notification.appId = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_APP_ID);
    notification.appName = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_APP_NAME);

    if ((notification.deviceId == 0) || (notification.deviceName == 0) ||
        (notification.appId == 0) || (notification.appName == 0)) 
	{
        AJ_ErrPrintf(("DeviceId/DeviceName/AppId/AppName can not be NULL\n"));
        return AJ_ERR_DISALLOWED;
    }

    if ((strlen(notification.deviceId) == 0) || (strlen(notification.deviceName) == 0) ||
        (strlen(notification.appId) == 0) || (strlen(notification.appName) == 0)) 
	{
        AJ_ErrPrintf(("DeviceId/DeviceName/AppId/AppName can not be empty\n"));
        return AJ_ERR_DISALLOWED;
    }

    if (notification.version > 1) 
	{
        notification.originalSenderName = AJ_GetUniqueName(busAttachment);

        if (notification.originalSenderName == 0) 
		{
            AJ_ErrPrintf(("OriginalSender can not be NULL\n"));
            return AJ_ERR_DISALLOWED;
        }

        if (strlen(notification.originalSenderName) == 0) 
		{
            AJ_ErrPrintf(("OriginalSender can not be empty\n"));
            return AJ_ERR_DISALLOWED;
        }
    }
	else 
	{
        notification.originalSenderName = NULL;
    }

    if (!notificationId)
	{
    //    AJ_InfoPrintf(("Generating random number for notification id\n"));
        AJ_RandBytes((uint8_t*)&notificationId, 4);
    }

    notification.notificationId = notificationId;
    notification.content = content;

    status = AJNS_Producer_SendNotifySignal(busAttachment, &notification, ttl, &serialNumber);

    if (status == AJ_OK) 
	{
        lastSentNotifications[messageType].notificationId = notificationId++;
        lastSentNotifications[messageType].serialNum = serialNumber;
        if (messageSerialNumber != NULL) 
		{
            *messageSerialNumber = serialNumber;
        }
    }

    return status;
}
Exemplo n.º 9
0
int AJ_Main()
{
    AJ_Status status = AJ_OK;
    AJ_BusAttachment bus;
    uint8_t connected = FALSE;
    uint32_t sessionId = 0;

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();

    AJ_PrintXML(AppObjects);
    AJ_RegisterObjects(AppObjects, NULL);

    SetBusAuthPwdCallback(MyBusAuthPwdCB);
    while (TRUE) {
        AJ_Message msg;

        if (!connected) {
            status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServicePort, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE, NULL);
            if (status != AJ_OK) {
                continue;
            }
            AJ_InfoPrintf(("StartService returned AJ_OK\n"));
            AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus)));

            connected = TRUE;
#ifdef SECURE_OBJECT
            status = AJ_SetObjectFlags("/org/alljoyn/alljoyn_test", AJ_OBJ_FLAG_SECURE, 0);
            if (status != AJ_OK) {
                AJ_ErrPrintf(("Error calling AJ_SetObjectFlags.. [%s] \n", AJ_StatusText(status)));
                return -1;
            }
#endif

#if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT)

            /* Register a callback for providing bus authentication password */
            AJ_BusSetPasswordCallback(&bus, PasswordCallback);
            AJ_BusEnableSecurity(&bus, suites, numsuites);
            AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback);
#endif

            /* Configure timeout for the link to the daemon bus */
            AJ_SetBusLinkTimeout(&bus, 60); // 60 seconds
        }

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

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

            case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH):
                if (msg.hdr->msgType == AJ_MSG_ERROR) {
                    AJ_InfoPrintf(("Failed to add match\n"));
                    status = AJ_ERR_FAILURE;
                } else {
                    status = AJ_OK;
                }
                break;

            case AJ_METHOD_ACCEPT_SESSION:
                {
                    uint16_t port;
                    char* joiner;
                    AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner);
                    if (port == ServicePort) {
                        status = AJ_BusReplyAcceptSession(&msg, TRUE);
                        AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", sessionId, joiner));
                    } else {
                        status = AJ_BusReplyAcceptSession(&msg, FALSE);
                        AJ_InfoPrintf(("Accepted rejected session_id=%u joiner=%s\n", sessionId, joiner));
                    }
                }
                break;

            case APP_MY_PING:
                status = AppHandlePing(&msg);
                break;

            case APP_GET_PROP:
                status = AJ_BusPropGet(&msg, PropGetHandler, NULL);
                break;

            case APP_SET_PROP:
                status = AJ_BusPropSet(&msg, PropSetHandler, NULL);
                if (status == AJ_OK) {
                    AJ_InfoPrintf(("Property successfully set to %d.\n", propVal));
                } else {
                    AJ_InfoPrintf(("Property set attempt unsuccessful. Status = 0x%04x.\n", status));
                }
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                {
                    uint32_t id, reason;
                    AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                    AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason));
                    if (CancelAdvertiseName) {
                        status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0);
                    }
                    status = AJ_ERR_SESSION_LOST;
                }
                break;

            case AJ_SIGNAL_SESSION_JOINED:
                if (CancelAdvertiseName) {
                    status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_STOP_ADVERTISING, 0);
                }
                break;

            case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE):
            case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME):
                if (msg.hdr->msgType == AJ_MSG_ERROR) {
                    status = AJ_ERR_FAILURE;
                }
                break;

            case APP_MY_SIGNAL:
                AJ_InfoPrintf(("Received my_signal\n"));
                status = AJ_OK;

                if (ReflectSignal) {
                    AJ_Message out;
                    AJ_MarshalSignal(&bus, &out, APP_MY_SIGNAL, msg.destination, msg.sessionId, 0, 0);
                    AJ_MarshalArgs(&out, "a{ys}", 0, NULL);
                    AJ_DeliverMsg(&out);
                    AJ_CloseMsg(&out);
                }
                break;

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

            // Any received packets indicates the link is active, so call to reinforce the bus link state
            AJ_NotifyLinkActive();
        }
        /*
         * Unarshaled messages must be closed to free resources
         */
        AJ_CloseMsg(&msg);

        if ((status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) {
            AJ_InfoPrintf(("AllJoyn disconnect\n"));
            AJ_InfoPrintf(("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);
        }
    }
    AJ_WarnPrintf(("svclite EXIT %d\n", status));

    return status;
}
Exemplo n.º 10
0
int AJ_Main(void)
{
    AJ_Status status = AJ_OK;
    AJ_BusAttachment bus;
    uint8_t connected = FALSE;
    uint32_t sessionId = 0;
    AJ_Status authStatus = AJ_ERR_NULL;

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();

    AJ_PrintXML(ProxyObjects);
    AJ_RegisterObjects(NULL, ProxyObjects);

    while (TRUE) {
        AJ_Message msg;

        if (!connected) {
            status = AJ_StartClient(&bus, NULL, CONNECT_TIMEOUT, ServiceName, ServicePort, &sessionId, NULL);
            if (status == AJ_OK) {
                AJ_Printf("StartClient returned %d, sessionId=%u\n", status, sessionId);
                AJ_Printf("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus));
                connected = TRUE;
                if (authPeer) {
                    AJ_BusSetPasswordCallback(&bus, PasswordCallback);
                    status = AJ_BusAuthenticatePeer(&bus, ServiceName, AuthCallback, &authStatus);
                    if (status != AJ_OK) {
                        AJ_Printf("AJ_BusAuthenticatePeer returned %d\n", status);
                    }
                } else {
                    authStatus = AJ_OK;
                }
            } else {
                AJ_Printf("StartClient returned %d\n", status);
                break;
            }
        }

        if (authStatus != AJ_ERR_NULL) {
            if (authStatus != AJ_OK) {
                AJ_Disconnect(&bus);
                break;
            }
            authStatus = AJ_ERR_NULL;
        }

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

        if (status == AJ_OK) {
            switch (msg.msgId) {
            case PRX_MY_SIGNAL:
                AJ_Printf("Received my_signal\n");
                status = AJ_OK;
                break;

            case AJ_SIGNAL_SESSION_LOST:
                /*
                 * Force a disconnect
                 */
                status = AJ_ERR_READ;
                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) {
            AJ_Printf("AllJoyn disconnect\n");
            AJ_Printf("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus));
            AJ_Disconnect(&bus);
            connected = FALSE;
        }
    }
    AJ_Printf("clientlite EXIT %d\n", status);

    return status;
}
Exemplo n.º 11
0
int AJ_Main()
#endif
{
    AJ_Status status = AJ_OK;
    AJ_BusAttachment bus;
    uint8_t connected = FALSE;
    uint32_t sessionId = 0;
    AJ_Status authStatus = AJ_ERR_NULL;
#ifdef SECURE_INTERFACE
    uint32_t suites[AJ_AUTH_SUITES_NUM];
    size_t numsuites = 0;
    uint8_t clearkeys = FALSE;
#endif

#ifdef MAIN_ALLOWS_ARGS
#if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT)
    ac--;
    av++;
    /*
     * Enable authentication mechanism by command line
     */
    if (ac) {
        if (0 == strncmp(*av, "-ek", 3)) {
            clearkeys = TRUE;
            ac--;
            av++;
        } else if (0 == strncmp(*av, "-e", 2)) {
            ac--;
            av++;
        }
        if (!ac) {
            AJ_AlwaysPrintf(("-e(k) requires an auth mechanism.\n"));
            return 1;
        }
        while (ac) {
            if (0 == strncmp(*av, "ECDHE_ECDSA", 11)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA;
            } else if (0 == strncmp(*av, "ECDHE_PSK", 9)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_PSK;
            } else if (0 == strncmp(*av, "ECDHE_NULL", 10)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_NULL;
            }
            ac--;
            av++;
        }
    }
#endif
#else
    suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA;
    clearkeys = TRUE;
#endif

#ifdef SECURE_INTERFACE
    if (numsuites == 0) {
        /* Default security to ECDHE_NULL, if not explicit elsewhere */
        suites[numsuites++] = AUTH_SUITE_ECDHE_NULL;
    }
#endif

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();

    AJ_PrintXML(ProxyObjects);
    AJ_RegisterObjects(NULL, ProxyObjects);

    while (TRUE) {
        AJ_Message msg;

        if (!connected) {
#if defined (ANNOUNCE_BASED_DISCOVERY)
            status = AJ_StartClientByPeerDescription(&bus, NULL, CONNECT_TIMEOUT, FALSE, &pingServicePeer, testServicePort, &sessionId, g_peerServiceName, NULL);
#elif defined (NGNS)
            status = AJ_StartClientByInterface(&bus, NULL, CONNECT_TIMEOUT, FALSE, testInterfaceNames, &sessionId, g_peerServiceName, NULL);
#else
            status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, testServiceName, testServicePort, &sessionId, NULL, g_peerServiceName);
#endif
            if (status == AJ_OK) {
                AJ_AlwaysPrintf(("StartClient returned %d, sessionId=%u, serviceName=%s\n", status, sessionId, g_peerServiceName));
                AJ_AlwaysPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus)));
                connected = TRUE;
#if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT)
                AJ_BusEnableSecurity(&bus, suites, numsuites);
                AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback);
                if (clearkeys) {
                    AJ_ClearCredentials(AJ_GENERIC_MASTER_SECRET | AJ_CRED_TYPE_GENERIC);
                    AJ_ClearCredentials(AJ_GENERIC_ECDSA_MANIFEST | AJ_CRED_TYPE_GENERIC);
                    AJ_ClearCredentials(AJ_GENERIC_ECDSA_KEYS | AJ_CRED_TYPE_GENERIC);
                }
                status = AJ_BusAuthenticatePeer(&bus, g_peerServiceName, AuthCallback, &authStatus);
                if (status != AJ_OK) {
                    AJ_AlwaysPrintf(("AJ_BusAuthenticatePeer returned %d\n", status));
                }
#else
                authStatus = AJ_OK;
#endif
            } else {
                AJ_AlwaysPrintf(("StartClient returned %d\n", status));
                break;
            }
        }


        AJ_AlwaysPrintf(("Auth status %d and AllJoyn status %d\n", authStatus, status));

        if (status == AJ_ERR_RESOURCES) {
            AJ_InfoPrintf(("Peer is busy, disconnecting and retrying auth...\n"));
            AJ_Disconnect(&bus);
            connected = FALSE;
            continue;
        }

        if (authStatus != AJ_ERR_NULL) {
            if (authStatus != AJ_OK) {
                AJ_Disconnect(&bus);
                break;
            }
            authStatus = AJ_ERR_NULL;
            AJ_BusSetLinkTimeout(&bus, sessionId, 10 * 1000);
        }

        status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT);
        if (status != AJ_OK) {
            if (status == AJ_ERR_TIMEOUT) {
                AppDoWork(&bus, sessionId, g_peerServiceName);
                continue;
            }
        } else {
            switch (msg.msgId) {

            case AJ_REPLY_ID(AJ_METHOD_SET_LINK_TIMEOUT):
                {
                    uint32_t disposition;
                    uint32_t timeout;
                    status = AJ_UnmarshalArgs(&msg, "uu", &disposition, &timeout);
                    if (disposition == AJ_SETLINKTIMEOUT_SUCCESS) {
                        AJ_AlwaysPrintf(("Link timeout set to %d\n", timeout));
                    } else {
                        AJ_AlwaysPrintf(("SetLinkTimeout failed %d\n", disposition));
                    }
                    SendPing(&bus, sessionId, g_peerServiceName, 1);
                }
                break;

            case AJ_REPLY_ID(AJ_METHOD_BUS_PING):
                {
                    uint32_t disposition;
                    status = AJ_UnmarshalArgs(&msg, "u", &disposition);
                    if (disposition == AJ_PING_SUCCESS) {
                        AJ_AlwaysPrintf(("Bus Ping reply received\n"));
                    } else {
                        AJ_AlwaysPrintf(("Bus Ping failed, disconnecting: %d\n", disposition));
                        status = AJ_ERR_LINK_DEAD;
                    }
                }
                break;

            case AJ_REPLY_ID(PRX_MY_PING):
                {
                    AJ_Arg arg;
                    AJ_UnmarshalArg(&msg, &arg);
                    AJ_AlwaysPrintf(("Got ping reply\n"));
                    AJ_InfoPrintf(("INFO Got ping reply\n"));
                    status = SendGetProp(&bus, sessionId, g_peerServiceName);
                }
                break;

            case AJ_REPLY_ID(PRX_GET_PROP):
                {
                    const char* sig;
                    status = AJ_UnmarshalVariant(&msg, &sig);
                    if (status == AJ_OK) {
                        status = AJ_UnmarshalArgs(&msg, sig, &g_iterCount);
                        AJ_AlwaysPrintf(("Get prop reply %d\n", g_iterCount));

                        if (status == AJ_OK) {
                            g_iterCount = g_iterCount + 1;
                            status = SendSetProp(&bus, sessionId, g_peerServiceName, g_iterCount);
                        }
                    }
                }
                break;

            case AJ_REPLY_ID(PRX_SET_PROP):
                AJ_AlwaysPrintf(("Set prop reply\n"));
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                /*
                 * Force a disconnect
                 */
                {
                    uint32_t id, reason;
                    AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                    AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u\n", id, reason));
                }
                status = AJ_ERR_SESSION_LOST;
                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_SESSION_LOST) || (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);
            break;
        }
    }
    AJ_AlwaysPrintf(("clientlite EXIT %d\n", status));

    return status;
}
Exemplo n.º 12
0
static AJ_Status MarshalMsg(AJ_Message* msg, uint8_t msgType, uint32_t msgId, uint8_t flags)
{
    AJ_Status status = AJ_OK;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;
    uint8_t fieldId;
    uint8_t secure = FALSE;

    /*
     * Use the msgId to lookup information in the object and interface descriptions to
     * initialize the message header fields.
     */
    status = AJ_InitMessageFromMsgId(msg, msgId, msgType, &secure);
    if (status != AJ_OK) {
        return status;
    }

    AJ_IO_BUF_RESET(ioBuf);

    msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart;
    memset(msg->hdr, 0, sizeof(AJ_MsgHeader));
    ioBuf->writePtr += sizeof(AJ_MsgHeader);

    msg->hdr->endianess = HOST_ENDIANESS;
    msg->hdr->msgType = msgType;
    msg->hdr->flags = flags;
    if (secure) {
        msg->hdr->flags |= AJ_FLAG_ENCRYPTED;
    }

    /*
     * The wire-protocol calls this flag NO_AUTO_START we toggle the meaning in the API
     * so the default flags value can be zero.
     */
    msg->hdr->flags ^= AJ_FLAG_AUTO_START;
    /*
     * Serial number cannot be zero (wire-spec wierdness)
     */
    do { msg->hdr->serialNum = msg->bus->serial++; } while (msg->bus->serial == 1);
    /*
     * Marshal the header fields
     */
    for (fieldId = AJ_HDR_OBJ_PATH; fieldId <= AJ_HDR_SESSION_ID; ++fieldId) {
        char typeId = TypeForHdr[fieldId];
        char buf[4];
        const char* fieldSig = &buf[2];
        AJ_Arg hdrVal;
        /*
         * Skip field id's that are not currently used.
         */
        if (typeId == AJ_ARG_INVALID) {
            continue;
        }
        InitArg(&hdrVal, typeId, NULL);
        switch (fieldId) {
        case AJ_HDR_OBJ_PATH:
            if ((msgType == AJ_MSG_METHOD_CALL) || (msgType == AJ_MSG_SIGNAL)) {
                hdrVal.val.v_objPath = msg->objPath;
            }
            break;

        case AJ_HDR_INTERFACE:
            hdrVal.val.v_string = msg->iface;
            break;

        case AJ_HDR_MEMBER:
            if (msgType != AJ_MSG_ERROR) {
                int32_t len = AJ_StringFindFirstOf(msg->member, " ");
                hdrVal.val.v_string = msg->member;
                hdrVal.len = (len >= 0) ? len : 0;
            }
            break;

        case AJ_HDR_ERROR_NAME:
            if (msgType == AJ_MSG_ERROR) {
                hdrVal.val.v_string = msg->error;
            }
            break;

        case AJ_HDR_REPLY_SERIAL:
            if ((msgType == AJ_MSG_METHOD_RET) || (msgType == AJ_MSG_ERROR)) {
                hdrVal.val.v_uint32 = &msg->replySerial;
            }
            break;

        case AJ_HDR_DESTINATION:
            hdrVal.val.v_string = msg->destination;
            break;

        case AJ_HDR_SENDER:
            hdrVal.val.v_string = AJ_GetUniqueName(msg->bus);
            break;

        case AJ_HDR_SIGNATURE:
            hdrVal.val.v_signature = msg->signature;
            break;

        case AJ_HDR_TIMESTAMP:
            if (msg->ttl) {
                AJ_Time timer;
                timer.seconds = 0;
                timer.milliseconds = 0;
                msg->timestamp = AJ_GetElapsedTime(&timer, FALSE);
                hdrVal.val.v_uint32 = &msg->timestamp;
            }
            break;

        case AJ_HDR_TIME_TO_LIVE:
            if (msg->ttl) {
                hdrVal.val.v_uint32 = &msg->ttl;
            }
            break;

        case AJ_HDR_SESSION_ID:
            if (msg->sessionId) {
                hdrVal.val.v_uint32 = &msg->sessionId;
            }
            break;

        case AJ_HDR_HANDLES:
        case AJ_HDR_COMPRESSION_TOKEN:
        default:
            continue;
        }
        /*
         * Ignore empty fields.
         */
        if (!hdrVal.val.v_data) {
            continue;
        }
        /*
         * Custom marshal the header field - signature is "(yv)" so starts off with STRUCT aligment.
         */
        buf[0] = fieldId;
        buf[1] = 1;
        buf[2] = typeId;
        buf[3] = 0;
        WriteBytes(msg, buf, 4, PadForType(AJ_ARG_STRUCT, ioBuf));
        /*
         * Now marshal the field value
         */
        Marshal(msg, &fieldSig, &hdrVal);
    }
    if (status == AJ_OK) {
        /*
         * Write the header length
         */
        msg->hdr->headerLen = (uint32_t)((ioBuf->writePtr - ioBuf->bufStart) - sizeof(AJ_MsgHeader));
        /*
         * Header must be padded to an 8 byte boundary
         */
        status = WritePad(msg, (8 - msg->hdr->headerLen) & 7);
    }
    return status;
}
Exemplo n.º 13
0
int AJ_Main()
#endif
{
    AJ_Status status = AJ_OK;
    AJ_BusAttachment bus;
    uint8_t connected = FALSE;
    uint32_t sessionId = 0;
    AJ_Status authStatus = AJ_ERR_NULL;
    /*
     * Buffer to hold the peer's full service name or unique name.
     */
#if defined (NGNS) || defined (ANNOUNCE_BASED_DISCOVERY)
    char peerServiceName[AJ_MAX_NAME_SIZE + 1];
#else
    char peerServiceName[AJ_MAX_SERVICE_NAME_SIZE];
#endif

#ifdef SECURE_INTERFACE
    uint32_t suites[16];
    size_t numsuites = 0;
    uint8_t clearkeys = FALSE;
    uint8_t enablepwd = FALSE;
    X509CertificateChain* node;
#endif

#ifdef MAIN_ALLOWS_ARGS
#ifdef SECURE_INTERFACE

    ac--;
    av++;
    /*
     * Enable authentication mechanism by command line
     */
    if (ac) {
        if (0 == strncmp(*av, "-ek", 3)) {
            clearkeys = TRUE;
            ac--;
            av++;
        } else if (0 == strncmp(*av, "-e", 2)) {
            ac--;
            av++;
        }
        if (!ac) {
            AJ_AlwaysPrintf(("-e(k) requires an auth mechanism.\n"));
            return 1;
        }
        while (ac) {
            if (0 == strncmp(*av, "ECDHE_ECDSA", 11)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA;
            } else if (0 == strncmp(*av, "ECDHE_PSK", 9)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_PSK;
            } else if (0 == strncmp(*av, "ECDHE_NULL", 10)) {
                suites[numsuites++] = AUTH_SUITE_ECDHE_NULL;
            } else if (0 == strncmp(*av, "PIN", 3)) {
                enablepwd = TRUE;
            }
            ac--;
            av++;
        }
    }
#endif
#endif

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();

    AJ_PrintXML(ProxyObjects);
    AJ_RegisterObjects(NULL, ProxyObjects);

    while (TRUE) {
        AJ_Message msg;

        if (!connected) {
#if defined (NGNS) || defined (ANNOUNCE_BASED_DISCOVERY)
            status = AJ_StartClientByInterface(&bus, NULL, CONNECT_TIMEOUT, FALSE, testInterfaceNames, &sessionId, peerServiceName, NULL);
#else
            status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, testServiceName, testServicePort, &sessionId, NULL, peerServiceName);
#endif
            if (status == AJ_OK) {
                AJ_AlwaysPrintf(("StartClient returned %d, sessionId=%u, serviceName=%s\n", status, sessionId, peerServiceName));
                AJ_AlwaysPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus)));
                connected = TRUE;
#ifdef SECURE_INTERFACE
                if (enablepwd) {
                    AJ_BusSetPasswordCallback(&bus, PasswordCallback);
                }
                AJ_BusEnableSecurity(&bus, suites, numsuites);
                AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback);
                if (clearkeys) {
                    status = AJ_ClearCredentials();
                    AJ_ASSERT(AJ_OK == status);
                }
                status = AJ_BusAuthenticatePeer(&bus, peerServiceName, AuthCallback, &authStatus);
                if (status != AJ_OK) {
                    AJ_AlwaysPrintf(("AJ_BusAuthenticatePeer returned %d\n", status));
                }
#else
                authStatus = AJ_OK;
#endif
                AJ_BusAddSignalRule(&bus, "my_signal", testInterfaceName, AJ_BUS_SIGNAL_ALLOW);

            } else {
                AJ_AlwaysPrintf(("StartClient returned %d\n", status));
                break;
            }
        }

        if (authStatus != AJ_ERR_NULL) {
            if (authStatus != AJ_OK) {
                AJ_Disconnect(&bus);
                break;
            }
            authStatus = AJ_ERR_NULL;
        }

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

        if (status == AJ_OK) {
            switch (msg.msgId) {
            case PRX_MY_SIGNAL:
                AJ_AlwaysPrintf(("Received my_signal\n"));
                status = AJ_OK;
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                /*
                 * Force a disconnect
                 */
                {
                    uint32_t id, reason;
                    AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                    AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason));
                }
                status = AJ_ERR_SESSION_LOST;
                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_SESSION_LOST) || (status == AJ_ERR_READ) || (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;
        }
    }
    AJ_AlwaysPrintf(("clientlite EXIT %d\n", status));

    // Clean up certificate chain
    while (chain) {
        node = chain;
        chain = chain->next;
        AJ_Free(node->certificate.der.data);
        AJ_Free(node);
    }

    return status;
}
int AJ_Main(void)
{
    AJ_Status status = AJ_OK;
    AJ_BusAttachment bus;
    uint8_t connected = FALSE;
    uint32_t sessionId = 0;
    AJ_Status authStatus = AJ_ERR_NULL;

    /*
     * One time initialization before calling any other AllJoyn APIs
     */
    AJ_Initialize();

    AJ_PrintXML(ProxyObjects);
    AJ_RegisterObjects(NULL, ProxyObjects);

    while (TRUE) {
        AJ_Message msg;

        if (!connected) {
            status = AJ_StartClient(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServiceName, ServicePort, &sessionId, NULL);
            if (status == AJ_OK) {
                AJ_Printf("StartClient returned %d, sessionId=%u\n", status, sessionId);
                AJ_Printf("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus));
                connected = TRUE;
#ifdef SECURE_INTERFACE
                AJ_BusSetPasswordCallback(&bus, PasswordCallback);
                status = AJ_BusAuthenticatePeer(&bus, ServiceName, AuthCallback, &authStatus);
                if (status != AJ_OK) {
                    AJ_Printf("AJ_BusAuthenticatePeer returned %d\n", status);
                }
#else
                authStatus = AJ_OK;
#endif
            } else {
                AJ_Printf("StartClient returned %d\n", status);
                break;
            }
        }

        if (authStatus != AJ_ERR_NULL) {
            if (authStatus != AJ_OK) {
                AJ_Disconnect(&bus);
                break;
            }
            authStatus = AJ_ERR_NULL;
            AJ_BusSetLinkTimeout(&bus, sessionId, 10 * 1000);
        }

        status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT);
        if (status != AJ_OK) {
            if (status == AJ_ERR_TIMEOUT) {
                AppDoWork(&bus, sessionId);
                continue;
            }
        } else {
            switch (msg.msgId) {

            case AJ_REPLY_ID(AJ_METHOD_SET_LINK_TIMEOUT):
                {
                    uint32_t disposition;
                    uint32_t timeout;
                    status = AJ_UnmarshalArgs(&msg, "uu", &disposition, &timeout);
                    if (disposition == AJ_SETLINKTIMEOUT_SUCCESS) {
                        AJ_Printf("Link timeout set to %d\n", timeout);
                    } else {
                        AJ_Printf("SetLinkTimeout failed %d\n", disposition);
                    }
                    SendPing(&bus, sessionId, 1);
                }
                break;

            case AJ_REPLY_ID(PRX_MY_PING):
                {
                    AJ_Arg arg;
                    AJ_UnmarshalArg(&msg, &arg);
                    status = SendGetProp(&bus, sessionId);
                }
                break;

            case AJ_REPLY_ID(PRX_GET_PROP):
                {
                    const char* sig;
                    status = AJ_UnmarshalVariant(&msg, &sig);
                    if (status == AJ_OK) {
                        status = AJ_UnmarshalArgs(&msg, sig, &g_iterCount);
                        AJ_Printf("Get prop reply %d\n", g_iterCount);

                        if (status == AJ_OK) {
                            g_iterCount = g_iterCount + 1;
                            status = SendSetProp(&bus, sessionId, g_iterCount);
                        }
                    }
                }
                break;

            case AJ_REPLY_ID(PRX_SET_PROP):
                AJ_Printf("Set prop reply\n");
                break;

            case AJ_SIGNAL_SESSION_LOST_WITH_REASON:
                /*
                 * Force a disconnect
                 */
                {
                    uint32_t id, reason;
                    AJ_UnmarshalArgs(&msg, "uu", &id, &reason);
                    AJ_Printf("Session lost. ID = %u, reason = %u", id, reason);
                }
                status = AJ_ERR_SESSION_LOST;
                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_SESSION_LOST) || (status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) {
            AJ_Printf("AllJoyn disconnect\n");
            AJ_Printf("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus));
            AJ_Disconnect(&bus);
            return status;
        }
    }
    AJ_Printf("clientlite EXIT %d\n", status);

    return status;
}
Exemplo n.º 15
0
/*
 * Announcements are processed as follows:
 *
 * 1) First check if there is an existing session for the announcement sender. If not create and
 *    initialize an empty session object. A session object has two properties "info" which is a buffer
 *    that holds state information about the session and an array "anno" which is used to accumulate
 *    announcements from the same sender.
 * 2) Unmarshal the announcement signal and if there is a callback registered for any of the
 *    interfaces add a service object to announcements array. The "interfaces" property on the
 *    service object is an array of all interfaces in the announcement.
 * 3) If there is already a session with the announcement sender make callbacks now, otherwise send
 *    a JOIN_SESSION method call to join the session with the announcement sender. The callbacks are
 *    reevaluated when the JOIN_SESSION reply is received.
 */
AJ_Status AJS_AboutAnnouncement(duk_context* ctx, AJ_Message* msg)
{
    AJ_BusAttachment* aj = msg->bus;
    AJ_Status status;
    uint16_t version;
    duk_idx_t anIdx;
    SessionInfo* sessionInfo;
    AJ_Arg objList;
    const char* sender;

    AJ_InfoPrintf(("AJS_AboutAnnouncement\n"));

    /*
     * Ignore our own announcements
     */
    if (strcmp(msg->sender, AJ_GetUniqueName(msg->bus)) == 0) {
        AJ_InfoPrintf(("Ignoring our own announcement\n"));
        return AJ_OK;
    }
    /*
     * Push the sender string on the stack to stabilize it.
     */
    sender = duk_push_string(ctx, msg->sender);
    /*
     * Announcements are accumulated in a global stash object indexed by peer name
     */
    AJS_GetGlobalStashObject(ctx, "sessions");
    sessionInfo = AllocSessionObject(ctx, sender);
    /*
     * Get the announcements array
     */
    duk_get_prop_string(ctx, -1, "anno");
    anIdx = duk_get_top_index(ctx);
    /*
     * Find out if there are JavaScript handlers for this announcement
     */
    AJ_UnmarshalArgs(msg, "qq", &version, &sessionInfo->port);
    status = AJ_UnmarshalContainer(msg, &objList, AJ_ARG_ARRAY);
    while (status == AJ_OK) {
        int ifcCount = 0;
        uint8_t hasCB = FALSE;
        AJ_Arg obj;
        AJ_Arg interfaces;
        const char* path;

        status = AJ_UnmarshalContainer(msg, &obj, AJ_ARG_STRUCT);
        if (status != AJ_OK) {
            break;
        }
        AJ_UnmarshalArgs(msg, "o", &path);
        /*
         * Array to accumulate interfaces
         */
        duk_push_array(ctx);
        status = AJ_UnmarshalContainer(msg, &interfaces, AJ_ARG_ARRAY);
        while (status == AJ_OK) {
            /*
             * Accumulate interfaces checking
             */
            const char* iface;
            status = AJ_UnmarshalArgs(msg, "s", &iface);
            if (status == AJ_OK) {
                duk_push_string(ctx, iface);
                duk_put_prop_index(ctx, -2, ifcCount++);
            }
            /*
             * We will disard the interface array if no callbacks are registered.
             */
            if (!hasCB && HasServiceCallback(ctx, iface)) {
                hasCB = TRUE;
            }
        }
        if (hasCB) {
            AddServiceObject(ctx, sessionInfo, path, sender);
            /*
             * Append service object to the announcements array for processing later
             */
            duk_put_prop_index(ctx, anIdx, duk_get_length(ctx, anIdx));
        } else {
            /* discard the interface array */
            duk_pop(ctx);
        }
        if (status == AJ_ERR_NO_MORE) {
            status = AJ_UnmarshalCloseContainer(msg, &interfaces);
        }
        if (status == AJ_OK) {
            status = AJ_UnmarshalCloseContainer(msg, &obj);
        }
    }
    if (status == AJ_ERR_NO_MORE) {
        status = AJ_UnmarshalCloseContainer(msg, &objList);
    }
    /*
     * All done with this message - we need to close it now to free up the output buffer before we
     * attempt to call AJ_BusJoinSession() below.
     */
    AJ_CloseMsg(msg);

    /* Pop "anno" and the session object */
    duk_pop_2(ctx);

    if (status != AJ_OK) {
        goto Exit;
    }
    /*
     * If we already have a session with this peer callback with the new service objects
     */
    if (sessionInfo->sessionId) {
        AnnouncementCallbacks(ctx, sender, sessionInfo);
        goto Exit;
    }
    /*
     * If there is a JOIN_SESSION in progress we have nothing more to do
     */
    if (sessionInfo->replySerial != 0) {
        goto Exit;
    }
    /*
     * If announcements were registered attempt to join the session
     */
    if (sessionInfo->refCount) {
        status = AJ_BusJoinSession(aj, sender, sessionInfo->port, NULL);
        if (status == AJ_OK) {
            sessionInfo->replySerial = aj->serial - 1;
        }
    }
    /*
     * At this point if we don't have a JOIN_SESSION in progress we must delete the session object
     */
    if (sessionInfo->replySerial == 0) {
        duk_del_prop_string(ctx, -2, sender);
    }

Exit:

    /* Pop "sessions" and sender string */
    duk_pop_2(ctx);
    return status;
}
Exemplo n.º 16
0
void AJ_Main(void)
{
    uint8_t i = 0;
    AJ_Status status = AJ_ERR_FAILURE; /* the glass is half-empty */
    AJ_BusAttachment bus;

    /* these variables are used when kicking off DHCP */
    uint32_t current_ip_address = 0;
    uint32_t current_subnet_mask = 0;
    uint32_t current_default_gateway = 0;
    AJ_Time dhcpTimer;
    uint32_t timeTakenForDhcp = 0;

    AJ_Initialize();

    AJ_Printf("\nAllJoyn Release: %s\n\n", AJ_GetVersion());

    AJ_Printf("INFO: The parameter RUN_NEGATIVE_TESTS is %s\n", (RUN_NEGATIVE_TESTS ? "true" : "false"));
    AJ_Printf("INFO: The parameter DELAY_BETWEEN_SCANS is %u ms\n", DELAY_BETWEEN_SCANS);
    AJ_Printf("INFO: The parameter DELAY_BETWEEN_ASSOCIATIONS is %u ms\n", DELAY_BETWEEN_ASSOCIATIONS);
    AJ_Printf("INFO: The parameter DHCP_TIMEOUT is %u ms\n", DHCP_TIMEOUT);
    AJ_Printf("INFO: The parameter DISCOVER_TIMEOUT is %u ms\n", DISCOVER_TIMEOUT);

    /* reset the wifi to start with a clean slate */
    status = AJ_ResetWiFi();
    if (AJ_OK != status) {
        AJ_Printf("WARN: AJ_ResetWiFi returned %s (code: %u).\n", AJ_StatusText(status), status);
    }

    /*
     * Repeatedly do the following:
     * a. scan for access points in the vicinity
     * b. For each open access point in the returned results:
     *      i.   associate using AJ_ConnectWiFi
     *      ii.  acquire an ip address using AJ_AcquireIPAddress
     *      iii. perform a short-lived discovery on some random node prefix
     *           using AJ_FindBusAndConnect
     *      iv.  disassociate using AJ_DisconnectWiFi
     * c. For each secured access point in the returned results:
     *      i. Connect to it with intentionally incorrect parameters
     *         (Negative test)
     */
    while (TRUE) {
        AJ_RandBytes(&currentContext, sizeof(currentContext));

        uint8_t currentMaxAps = 0;
        AJ_RandBytes(&currentMaxAps, sizeof(currentMaxAps));

        /* Reset numValidScanEntries, before every scan attempt. */
        numValidScanEntries = 0;

        status = AJ_WiFiScan((void*) (sentinelForWifiScanContext + currentContext), wifiScanResultCallback, currentMaxAps);

        if (AJ_OK != status) {
            if (AJ_ERR_FAILURE == status && 0 != currentMaxAps) {
                scanStats.numFailed++;
            } else if (AJ_ERR_RESOURCES == status) {
                scanStats.numFailed++;
            }

            AJ_Printf("Failed to scan: %s (code: %u)\n", AJ_StatusText(status), status);

            /* No point in attempting to do wifi operations, when scan failed */
            continue;
        } else {
            /*
             * A success was returned from AJ_WiFiScan. Were any results
             * returned after all??
             */
            if (0 < numValidScanEntries) {
                scanStats.numSuccessful++;
            } else {
                AJ_Printf("WARN: AJ_WiFiScan returned %s (code: %u), but returned ZERO scan results...\n", AJ_StatusText(status), status);
                scanStats.numFailed++;

                /* When num of scan results is zero, there is nothing to do */
                continue;
            }
        }

        /* numValidScanEntries is an index into the array. Hence +1. */
        if (currentMaxAps < numValidScanEntries + 1) {
            AJ_Printf("WARN: Scan returned more results (%u) than requested (%u).\n", numValidScanEntries + 1, currentMaxAps);
        } else {
            AJ_Printf("Wifi scan successful (got %u results).\n", numValidScanEntries);
        }

        for (i = 0; i < numValidScanEntries; i++) {
            if (AJ_WIFI_SECURITY_NONE != wifiScanInfo[i].secType) {
                /* On some targets, it is not possible to check for 802.11
                 * authentication failure when security type is WEP.
                 * Hence, run negative tests only for WPA/WPA2-based APs.
                 */
                if (RUN_NEGATIVE_TESTS && AJ_WIFI_SECURITY_WEP != wifiScanInfo[i].secType) {
                    /* Run a negative test for wifi association */
                    AJ_Printf("RUN (negative test): Attempting to associate with %s using a randomly generated passphrase...", wifiScanInfo[i].ssid);
                    char random_passphrase[128 + 1];
                    AJ_RandHex(random_passphrase, sizeof(random_passphrase), (sizeof(random_passphrase) - 1) / 2);

                    /* Set a random passphrase length based on security type */
                    uint8_t randomPassphraseLen = 0;
                    /* WPA / WPA2 - assuming min len is 8 and max is 64 */
                    AJ_RandBytes(&randomPassphraseLen, sizeof(randomPassphraseLen));
                    randomPassphraseLen = 8 + randomPassphraseLen % (64 - 8 + 1);
                    random_passphrase[randomPassphraseLen] = '\0';
                    status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, random_passphrase);
                    if (AJ_OK == status) {
                        /* negative test failed */
                        AJ_Printf("FAIL (negative test): Associated with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) Passphrase: %s RSSI: %u ...\n", wifiScanInfo[i].ssid, wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5], secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType], random_passphrase, wifiScanInfo[i].rssi);

                        /* negative test failed - don't go any further */
                        AJ_ASSERT(0);
                    } else {
                        AJ_Printf("Done (negative test).\n");
                    }
                    status = AJ_DisconnectWiFi();
                    AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS);
                }

                continue;
            } else {
                AJ_Printf("Attempting to associate with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) RSSI: %u ...\n",
                          wifiScanInfo[i].ssid,
                          wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5],
                          secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType],
                          wifiScanInfo[i].rssi);
                status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, "");
                if (AJ_OK != status) {
                    associationStats.numFailed++;
                    AJ_Printf("Failed to associate : %s (code: %u)\n", AJ_StatusText(status), status);
                    /*
                     * No point in proceeding any further when WiFi association
                     * has failed
                     */
                    continue;
                } else {
                    associationStats.numSuccessful++;
                }

                AJ_Printf("Successfully associated. Attempting to get IP Address via DHCP...\n");

                AJ_InitTimer(&dhcpTimer);

                status = AJ_AcquireIPAddress(&current_ip_address, &current_subnet_mask, &current_default_gateway, DHCP_TIMEOUT);

                timeTakenForDhcp = AJ_GetElapsedTime(&dhcpTimer, FALSE);

                if (AJ_OK != status) {
                    if (AJ_ERR_TIMEOUT == status) {
                        dhcpStats.numTimedout++;
                        AJ_Printf("Timedout (%u ms) while trying to get IP Address via DHCP\n", timeTakenForDhcp);
                        /*
                         * Discovery timed out.
                         * Check whether the API returned in a timely manner.
                         * See whether the actual duration is off by +/- 500ms.
                         * Delay beyond that is unusual.
                         */
                        if (500 < abs(DHCP_TIMEOUT - timeTakenForDhcp)) {
                            AJ_Printf("WARN: AJ_AcquireIPAddress API did not return in a timely manner. Timeout parameter: %u Actual time elapsed: %u\n",
                                      DHCP_TIMEOUT,
                                      timeTakenForDhcp);
                        }
                    } else {
                        dhcpStats.numFailed++;
                        AJ_Printf("Failed to get IP Address via DHCP : %s (code: %u)\n", AJ_StatusText(status), status);
                    }
                    /*
                     * No point in proceeding any further when IP address was
                     * not acquired
                     */
                    continue;
                } else {
                    dhcpStats.numSuccessful++;
                    AJ_Printf("Successfully obtained\n");
                    AJ_Printf("\tIP Addresss    : %s\n", TestAddrStr(current_ip_address));
                    AJ_Printf("\tSubnet Mask    : %s\n", TestAddrStr(current_subnet_mask));
                    AJ_Printf("\tDefault Gateway: %s\n", TestAddrStr(current_default_gateway));
                }

                /* Generate a random name using routingNodePrefix */
                char currentRoutingNodeName[32 + 1];
                strncpy(currentRoutingNodeName, routingNodePrefix, sizeof(routingNodePrefix));
                AJ_RandHex(currentRoutingNodeName + strlen(routingNodePrefix), sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix), (sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix) - 1) / 2);
                currentRoutingNodeName[32] = '\0'; /* just to be safe */

                AJ_Printf("Attempting to discover routing node: %s...", currentRoutingNodeName);

                status = AJ_FindBusAndConnect(&bus, currentRoutingNodeName, DISCOVER_TIMEOUT);

                if (AJ_ERR_TIMEOUT == status) {
                    /* this is the expected result */
                    discoverStats.numTimedout++;
                    AJ_Printf("Done (discovery of routing node).\n");
                } else if (AJ_OK != status) {
                    discoverStats.numFailed++;
                    AJ_Printf("Failed to connect to routing node: %s (code: %u)\n", AJ_StatusText(status), status);
                } else if (AJ_OK == status) {
                    /*
                     * the test attempted to discovery a randomly generated
                     * routing node prefix and it worked - highly unlikely event
                     */
                    AJ_Printf("FATAL: Was able to discover and connect to routing node with prefix %s. Got unique address %s.", currentRoutingNodeName, AJ_GetUniqueName(&bus));
                    AJ_ASSERT(0);
                }

                status = AJ_DisconnectWiFi();

                if (AJ_OK != status) {
                    disassociationStats.numFailed++;
                    AJ_Printf("Failed to disassociate: %s (code: %u)\n", AJ_StatusText(status), status);
                } else {
                    disassociationStats.numSuccessful++;
                    AJ_Printf("Disassociated from access point. ");
                }
                AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS);
            }
        }

        PrintStats();

        AJ_Sleep(DELAY_BETWEEN_SCANS);
    }
}
Exemplo n.º 17
0
AJ_Status AJ_UnmarshalMsg(AJ_BusAttachment* bus, AJ_Message* msg, uint32_t timeout)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &bus->sock.rx;
    uint8_t* endOfHeader;
    uint32_t hdrPad;
    /*
     * Clear message then set the bus
     */
    memset(msg, 0, sizeof(AJ_Message));
    msg->msgId = AJ_INVALID_MSG_ID;
    msg->bus = bus;
    /*
     * Move any unconsumed data to the start of the I/O buffer
     */
    AJ_IOBufRebase(ioBuf);
    /*
     * Load the message header
     */
    while (AJ_IO_BUF_AVAIL(ioBuf) < sizeof(AJ_MsgHeader)) {
        //#pragma calls = AJ_Net_Recv
        status = ioBuf->recv(ioBuf, sizeof(AJ_MsgHeader) - AJ_IO_BUF_AVAIL(ioBuf), timeout);
        if (status != AJ_OK) {
            /*
             * If there were no messages to receive check if we have any methods call that have
             * timed-out and if so generate an internal error message to allow the application to
             * proceed.
             */
            if ((status == AJ_ERR_TIMEOUT) && AJ_TimedOutMethodCall(msg)) {
                msg->hdr = (AJ_MsgHeader*)&internalErrorHdr;
                msg->error = AJ_ErrTimeout;
                msg->sender = AJ_GetUniqueName(msg->bus);
                msg->destination = msg->sender;
                status = AJ_OK;
            }

            return status;
        }
    }
    /*
     * Header was unmarsalled directly into the rx buffer
     */
    msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart;
    ioBuf->readPtr += sizeof(AJ_MsgHeader);
    /*
     * Quick sanity check on the header - unrecoverable error if this check fails
     */
    if ((msg->hdr->endianess != AJ_LITTLE_ENDIAN) && (msg->hdr->endianess != AJ_BIG_ENDIAN)) {
        return AJ_ERR_READ;
    }
    /*
     * Endian swap header info - conventiently they are contiguous in the header
     */
    EndianSwap(msg, AJ_ARG_INT32, &msg->hdr->bodyLen, 3);
    msg->bodyBytes = msg->hdr->bodyLen;
    /*
     * The header is null padded to an 8 bytes boundary
     */
    hdrPad = (8 - msg->hdr->headerLen) & 7;
    /*
     * Load the header
     */
    status = LoadBytes(ioBuf, msg->hdr->headerLen + hdrPad, 0);
    if (status != AJ_OK) {
        return status;
    }
#ifndef NDEBUG
    /*
     * Check that messages are getting closed
     */
    AJ_ASSERT(!currentMsg);
    currentMsg = msg;
#endif
    /*
     * Assume an empty signature
     */
    msg->signature = "";
    /*
     * We have the header in the buffer now we can unmarshal the header fields
     */
    endOfHeader = ioBuf->bufStart + sizeof(AJ_MsgHeader) + msg->hdr->headerLen;
    while (ioBuf->readPtr < endOfHeader) {
        const char* fieldSig;
        uint8_t fieldId;
        AJ_Arg hdrVal;
        /*
         * Custom unmarshal the header field - signature is "(yv)" so starts off with STRUCT aligment.
         */
        status = LoadBytes(ioBuf, 4, PadForType(AJ_ARG_STRUCT, ioBuf));
        if (status != AJ_OK) {
            break;
        }
        fieldId = ioBuf->readPtr[0];
        fieldSig = (const char*)&ioBuf->readPtr[2];
        ioBuf->readPtr += 4;
        /*
         * Now unmarshal the field value
         */
        status = Unmarshal(msg, &fieldSig, &hdrVal);
        if (status != AJ_OK) {
            break;
        }
        /*
         * Check the field has the type we expect - we ignore fields we don't know
         */
        if ((fieldId <= AJ_HDR_SESSION_ID) && (TypeForHdr[fieldId] != hdrVal.typeId)) {
            status = AJ_ERR_UNMARSHAL;
            break;
        }
        /*
         * Set the field value in the message
         */
        switch (fieldId) {
        case AJ_HDR_OBJ_PATH:
            msg->objPath = hdrVal.val.v_objPath;
            break;

        case AJ_HDR_INTERFACE:
            msg->iface = hdrVal.val.v_string;
            break;

        case AJ_HDR_MEMBER:
            msg->member = hdrVal.val.v_string;
            break;

        case AJ_HDR_ERROR_NAME:
            msg->error = hdrVal.val.v_string;
            break;

        case AJ_HDR_REPLY_SERIAL:
            msg->replySerial = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_DESTINATION:
            msg->destination = hdrVal.val.v_string;
            break;

        case AJ_HDR_SENDER:
            msg->sender = hdrVal.val.v_string;
            break;

        case AJ_HDR_SIGNATURE:
            msg->signature = hdrVal.val.v_signature;
            break;

        case AJ_HDR_TIMESTAMP:
            msg->timestamp = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_TIME_TO_LIVE:
            msg->ttl = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_SESSION_ID:
            msg->sessionId = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_HANDLES:
        case AJ_HDR_COMPRESSION_TOKEN:
        default:
            /* Ignored */
            break;
        }
    }
    if (status == AJ_OK) {
        AJ_ASSERT(ioBuf->readPtr == endOfHeader);
        /*
         * Consume the header pad bytes.
         */
        ioBuf->readPtr += hdrPad;
        /*
         * If the message is encrypted load the entire message body and decrypt it.
         */
        if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) {
            status = LoadBytes(ioBuf, msg->hdr->bodyLen, 0);
            if (status == AJ_OK) {
                status = DecryptMessage(msg);
            }
        }
        /*
         * Toggle the AUTO_START flag so in the API no flags == 0
         *
         * Note we must do this after decrypting the message or message authentication will fail.
         */
        msg->hdr->flags ^= AJ_FLAG_AUTO_START;
        /*
         * If the message looks good try to identify it.
         */
        if (status == AJ_OK) {
            status = AJ_IdentifyMessage(msg);
        }
    } else {
        /*
         * Consume entire header
         */
        ioBuf->readPtr = endOfHeader + hdrPad;
    }
    if (status == AJ_OK) {
        AJ_DumpMsg("RECEIVED", msg, FALSE);
    } else {
        /*
         * Silently discard message unless in debug mode
         */
        AJ_ErrPrintf(("Discarding bad message %s\n", AJ_StatusText(status)));
        AJ_DumpMsg("DISCARDING", msg, FALSE);
        AJ_CloseMsg(msg);
    }

    return status;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
AJ_Status AJ_RunAllJoynService(AJ_BusAttachment* bus, AllJoynConfiguration* config)
{
    uint8_t connected = FALSE;
    AJ_Status status = AJ_OK;

    while (TRUE) {
        AJ_Time start = { 0, 0 };
        AJ_Message msg;
        uint32_t now;
        // get the next timeout
        //Timer* timer = GetNextTimeout();
        uint32_t next;
        // wait forever
        uint32_t timeout = (uint32_t) -1;

        if (!connected) {
            status = AJ_StartService2(
                bus,
                config->daemonName, config->connect_timeout, config->connected,
                config->session_port, config->service_name, config->flags, config->opts);
            if (status != AJ_OK) {
                continue;
            }
            AJ_InfoPrintf(("StartService returned AJ_OK\n"));
            AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(bus)));

            connected = TRUE;

            /* Register a callback for providing bus authentication password */
            AJ_BusSetPasswordCallback(bus, config->password_callback);

            /* Configure timeout for the link to the daemon bus */
            AJ_SetBusLinkTimeout(bus, config->link_timeout);

            if (config->connection_handler != NULL) {
                (config->connection_handler)(connected);
            }
        }

        // absolute time in milliseconds
        now = AJ_GetElapsedTime(&start, FALSE);
        next = RunExpiredTimers(now);

        if (next != (uint32_t) -1) {
            // if no timers running, wait forever
            timeout = next;
        }

        status = AJ_UnmarshalMsg(bus, &msg, min(500, timeout));
        if (AJ_ERR_TIMEOUT == status && AJ_ERR_LINK_TIMEOUT == AJ_BusLinkStateProc(bus)) {
            status = AJ_ERR_READ;
        }

        if (status == AJ_ERR_TIMEOUT) {
            // go back around and handle the expired timers
            continue;
        }

        if (status == AJ_OK) {
            uint8_t handled = FALSE;
            const MessageHandlerEntry* message_entry = config->message_handlers;
            const PropHandlerEntry* prop_entry = config->prop_handlers;

            // check the user's handlers first.  ANY message that AllJoyn can handle is override-able.
            while (handled != TRUE && message_entry->msgid != 0) {
                if (message_entry->msgid == msg.msgId) {
                    if (msg.hdr->msgType == AJ_MSG_METHOD_CALL) {
                        // build a method reply
                        AJ_Message reply;
                        status = AJ_MarshalReplyMsg(&msg, &reply);

                        if (status == AJ_OK) {
                            status = (message_entry->handler)(&msg, &reply);
                        }

                        if (status == AJ_OK) {
                            status = AJ_DeliverMsg(&reply);
                        }
                    } else {
                        // call the handler!
                        status = (message_entry->handler)(&msg, NULL);
                    }

                    handled = TRUE;
                }

                ++message_entry;
            }

            // we need to check whether this is a property getter or setter.
            // these are stored in an array because multiple getters and setters can exist if running more than one bus object
            while (handled != TRUE && prop_entry->msgid != 0) {
                if (prop_entry->msgid == msg.msgId) {
                    // extract the method from the ID; GetProperty or SetProperty
                    uint32_t method = prop_entry->msgid & 0x000000FF;
                    if (method == AJ_PROP_GET) {
                        status = AJ_BusPropGet(&msg, prop_entry->callback, prop_entry->context);
                    } else if (method == AJ_PROP_SET) {
                        status = AJ_BusPropSet(&msg, prop_entry->callback, prop_entry->context);
                    } else {
                        // this should never happen!!!
                        AJ_ASSERT(!"Invalid property method");
                    }

                    handled = TRUE;
                }

                ++prop_entry;
            }

            // handler not found!
            if (handled == FALSE) {
                if (msg.msgId == AJ_METHOD_ACCEPT_SESSION) {
                    uint8_t accepted = (config->acceptor)(&msg);
                    status = AJ_BusReplyAcceptSession(&msg, accepted);
                } else {
                    status = AJ_BusHandleBusMessage(&msg);
                }
            }

            // Any received packets indicates the link is active, so call to reinforce the bus link state
            AJ_NotifyLinkActive();
        }
        /*
         * Unarshaled messages must be closed to free resources
         */
        AJ_CloseMsg(&msg);

        if (status == AJ_ERR_READ) {
            AJ_InfoPrintf(("AllJoyn disconnect\n"));
            AJ_InfoPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(bus)));
            AJ_Disconnect(bus);
            connected = FALSE;
            if (config->connection_handler != NULL) {
                (config->connection_handler)(connected);
            }
            /*
             * Sleep a little while before trying to reconnect
             */
            AJ_Sleep(10 * 1000);
        }
    }

    // this will never actually return!
    return AJ_OK;
}
Exemplo n.º 20
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;
}