コード例 #1
0
ファイル: SecureService.cpp プロジェクト: CasyWang/Triton
static AJ_Status AppHandlePing(AJ_Message* msg)
{
    AJ_Status status;
    AJ_Message reply;
    AJ_Arg arg;

    status = AJ_UnmarshalArg(msg, &arg);

    if (AJ_OK == status) {

        if (arg.typeId == AJ_ARG_STRING) {
            AJ_Printf("Received ping request '%s'.\n", arg.val.v_string);
        } else {
            AJ_Printf("Unexpected arg type '%d' in ping request.\n", arg.typeId);
        }

        status = AJ_MarshalReplyMsg(msg, &reply);

        if (AJ_OK == status) {
            /*
             * Just return the arg we received
             */
            status = AJ_MarshalArg(&reply, &arg);

            if (AJ_OK == status) {
                status = AJ_DeliverMsg(&reply);
            }
        }
    }

    return status;
}
コード例 #2
0
AJ_Status AJCFG_SetPasscodeHandler(AJ_Message* msg)
{
    AJ_Status status = AJ_OK;
    char* daemonRealm;
    AJ_Arg newPasscode;
    AJ_Message reply;
    uint8_t forceRoutingNodeDisconnect = FALSE;
    uint8_t errorReply = FALSE;

    AJ_InfoPrintf(("Handling SetPasscode request\n"));

    status = AJ_UnmarshalArgs(msg, "s", &daemonRealm);
    if (status != AJ_OK) {
        return status;
    }
    AJ_InfoPrintf(("Realm=%s\n", daemonRealm));
    status = AJ_UnmarshalArg(msg, &newPasscode);
    if (status != AJ_OK) {
        return status;
    }
    AJ_InfoPrintf(("Passcode=%d bytes long\n", newPasscode.len));
    if (newPasscode.len > 0) { // Check passcode is not empty
        if (AppSetPasscode) {
            status = (AppSetPasscode)(daemonRealm, (const uint8_t*)newPasscode.val.v_string, (uint8_t)newPasscode.len);
            if (status == AJ_ERR_RESOURCES) { // Check passcode is too long to persist
                status = AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_MAX_SIZE_EXCEEDED);
                if (status != AJ_OK) {
                    return status;
                }
                errorReply = TRUE;
            }
            forceRoutingNodeDisconnect = (status == AJ_ERR_READ);
        }
    } else {
        AJ_ErrPrintf(("Error - newPasscode cannot be empty!\n"));
        status = AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_INVALID_VALUE);
        if (status != AJ_OK) {
            return status;
        }
        errorReply = TRUE;
    }
    if (!errorReply) {
        status = AJ_MarshalReplyMsg(msg, &reply);
        if (status != AJ_OK) {
            return status;
        }
    }
    status = AJ_DeliverMsg(&reply);

    if (forceRoutingNodeDisconnect) {
        return AJ_ERR_READ;
    }
    return status;
}
コード例 #3
0
ファイル: aj_msg.c プロジェクト: reignme/ajtcl
AJ_Status AJ_UnmarshalVariant(AJ_Message* msg, const char** sig)
{
    AJ_Arg arg;
    AJ_Status status = AJ_UnmarshalArg(msg, &arg);
    if (status == AJ_OK) {
        if (sig) {
            *sig = arg.val.v_string;
        }
    }
    return status;
}
コード例 #4
0
AJ_Status ReceiveNewName(AJ_Message*msg)
{
    AJ_Arg arg;
    AJ_Status status = AJ_UnmarshalArg(msg, &arg);

    if (status == AJ_OK) {
        AJ_AlwaysPrintf(("--==## signalConsumer: Name Changed signal Received ##==--\n"));
        AJ_AlwaysPrintf(("\tNew name: '%s'.\n", arg.val.v_string));
    }

    return status;
}
コード例 #5
0
static AJ_Status AppHandlePing(AJ_Message* msg)
{
    AJ_Message reply;
    AJ_Arg arg;

    AJ_UnmarshalArg(msg, &arg);
    AJ_MarshalReplyMsg(msg, &reply);
    /*
     * Just return the arg we received
     */
    AJ_MarshalArg(&reply, &arg);
    return AJ_DeliverMsg(&reply);
}
コード例 #6
0
uint8_t AJNS_Consumer_IsSuperAgentLost(AJ_Message* msg)
{
    if (msg->msgId == AJ_SIGNAL_LOST_ADV_NAME) {
        AJ_Arg arg;
        AJ_UnmarshalArg(msg, &arg); // <arg name="name" type="s" direction="out"/>
        AJ_SkipArg(msg);            // <arg name="transport" type="q" direction="out"/>
        AJ_SkipArg(msg);            // <arg name="prefix" type="s" direction="out"/>
        AJ_ResetArgs(msg);          // Reset to allow others to re-unmarshal message
        AJ_InfoPrintf(("LostAdvertisedName(%s)\n", arg.val.v_string));
        return (strcmp(arg.val.v_string, currentSuperAgentBusName) == 0);
    }
    return FALSE;
}
コード例 #7
0
/*
 * Push a scalar array as a buffer.
 */
static AJ_Status PushScalarArrayArg(duk_context* ctx, uint8_t typeId, AJ_Message* msg)
{
    AJ_Arg arg;
    AJ_Status status = AJ_UnmarshalArg(msg, &arg);
    void* buf = duk_push_fixed_buffer(ctx, arg.len);

    if (buf) {
        memcpy(buf, arg.val.v_data, arg.len);
    } else {
        status = AJ_ERR_RESOURCES;
    }
    return status;
}
コード例 #8
0
static AJ_Status PushScalarArg(duk_context* ctx, AJ_Message* msg)
{
    AJ_Arg arg;
    AJ_Status status = AJ_UnmarshalArg(msg, &arg);

    if (status == AJ_OK) {
        switch (arg.typeId) {
        case AJ_ARG_BYTE:
            duk_push_uint(ctx, (uint32_t)(*arg.val.v_byte));
            break;

        case AJ_ARG_BOOLEAN:
            duk_push_boolean(ctx, *arg.val.v_bool);
            break;

        case AJ_ARG_UINT32:
            duk_push_uint(ctx, *arg.val.v_uint32);
            break;

        case AJ_ARG_INT32:
            duk_push_int(ctx, *arg.val.v_int32);
            break;

        case AJ_ARG_UINT16:
            duk_push_uint(ctx, *arg.val.v_uint16);
            break;

        case AJ_ARG_INT16:
            duk_push_int(ctx, *arg.val.v_int16);
            break;

        case AJ_ARG_DOUBLE:
            duk_push_number(ctx, *arg.val.v_double);
            break;

        case AJ_ARG_UINT64:
            /* TODO this will lose precision for numbers ~> 2^52*/
            duk_push_number(ctx, (double)*arg.val.v_uint64);
            break;

        case AJ_ARG_INT64:
            /* TODO this will lose precision for numbers ~> 2^52*/
            duk_push_number(ctx, (double)*arg.val.v_int64);
            break;
        }
    }
    return status;
}
コード例 #9
0
ファイル: aj_msg.c プロジェクト: reignme/ajtcl
AJ_Status AJ_UnmarshalArgs(AJ_Message* msg, const char* sig, ...)
{
    AJ_Status status = AJ_OK;
    AJ_Arg arg;
    va_list argp;

    va_start(argp, sig);
    while (*sig) {
        uint8_t typeId = (uint8_t)*sig++;
        void* val = va_arg(argp, void*);

        if (!IsBasicType(typeId)) {
            status = AJ_ERR_UNEXPECTED;
            break;
        }
        status = AJ_UnmarshalArg(msg, &arg);
        if (status != AJ_OK) {
            break;
        }
        if (arg.typeId != typeId) {
            status = AJ_ERR_UNMARSHAL;
            break;
        }
        if (IsScalarType(typeId)) {
            switch (SizeOfType(typeId)) {
            case 1:
                *((uint8_t*)val) = *arg.val.v_byte;
                break;

            case 2:
                *((uint16_t*)val) = *arg.val.v_uint16;
                break;

            case 4:
                *((uint32_t*)val) = *arg.val.v_uint32;
                break;

            case 8:
                *((uint64_t*)val) = *arg.val.v_uint64;
                break;
            }
        } else {
            *((const char**)val) = arg.val.v_string;
        }
    }
    va_end(argp);
    return status;
}
コード例 #10
0
ファイル: aj_msg.c プロジェクト: reignme/ajtcl
AJ_Status AJ_UnmarshalContainer(AJ_Message* msg, AJ_Arg* arg, uint8_t typeId)
{
    AJ_Status status = AJ_ERR_UNMARSHAL;

    if ((TYPE_FLAG(typeId) & AJ_CONTAINER)) {
        status = AJ_UnmarshalArg(msg, arg);
        if (status == AJ_OK) {
            if (arg->typeId == typeId) {
                arg->container = msg->outer;
                msg->outer = arg;
            } else {
                status =  AJ_ERR_UNMARSHAL;
            }
        }
    }
    return status;
}
コード例 #11
0
ファイル: aj_peer.c プロジェクト: bigzero/ajtcl
AJ_Status AJ_PeerHandleAuthChallengeReply(AJ_Message* msg)
{
    AJ_Status status;
    AJ_Arg arg;

    /*
     * Check we are in an auth conversation with the sender
     */
    status = CheckAuthPeer(msg);
    if (status != AJ_OK) {
        return status;
    }
    status = AJ_UnmarshalArg(msg, &arg);
    if (status == AJ_OK) {
        status = AuthResponse(msg, (char*)arg.val.v_string);
    }
    return status;
}
コード例 #12
0
static AJ_Status PushArg(duk_context* ctx, AJ_Message* msg)
{
    AJ_Status status = AJ_ERR_DISALLOWED;
    AJ_Arg arg;
    const char* sig = AJ_NextArgSig(msg);
    uint8_t typeId;

    if (!sig || !*sig) {
        return AJ_ERR_NO_MORE;
    }
    typeId = *sig;

    /*
     * De-variant the argument
     */
    while (typeId == AJ_ARG_VARIANT) {
        status = AJ_UnmarshalVariant(msg, &sig);
        if (status != AJ_OK) {
            return status;
        }
        typeId = *sig;
    }
    if (typeId == ')') {
        status = AJ_ERR_NO_MORE;
    } else if (AJ_IsScalarType(typeId)) {
        status = PushScalarArg(ctx, msg);
    } else if (AJ_IsStringType(typeId)) {
        status = AJ_UnmarshalArg(msg, &arg);
        if (status == AJ_OK) {
            duk_push_string(ctx, arg.val.v_string);
        }
    } else if (typeId == AJ_ARG_STRUCT) {
        status = PushContainerArg(ctx, AJ_ARG_STRUCT, msg);
    } else if (typeId == AJ_ARG_ARRAY) {
        if (sig[1] == AJ_ARG_DICT_ENTRY) {
            status = PushDictionaryArg(ctx, msg);
        } else if (sig[1] == AJ_ARG_BYTE) {
            status = PushScalarArrayArg(ctx, sig[1], msg);
        } else {
            status = PushContainerArg(ctx, AJ_ARG_ARRAY, msg);
        }
    }
    return status;
}
コード例 #13
0
ファイル: aj_peer.c プロジェクト: bigzero/ajtcl
AJ_Status AJ_PeerHandleExchangeGroupKeysReply(AJ_Message* msg)
{
    AJ_Status status;
    AJ_Arg arg;

    /*
     * Check we are in an auth conversation with the sender
     */
    status = CheckAuthPeer(msg);
    if (status != AJ_OK) {
        return status;
    }
    AJ_UnmarshalArg(msg, &arg);
    /*
     * We expect the key to be 16 bytes
     */
    if (arg.len != AES_KEY_LEN) {
        status = AJ_ERR_INVALID;
    } else {
        status = AJ_SetGroupKey(msg->sender, arg.val.v_byte);
    }
    PeerAuthComplete(status);
    return AJ_OK;
}
コード例 #14
0
ファイル: aj_peer.c プロジェクト: bigzero/ajtcl
AJ_Status AJ_PeerHandleExchangeGroupKeys(AJ_Message* msg, AJ_Message* reply)
{
    AJ_Status status;
    AJ_Arg key;

    AJ_UnmarshalArg(msg, &key);
    /*
     * We expect the key to be 16 bytes
     */
    if (key.len != AES_KEY_LEN) {
        status = AJ_ERR_INVALID;
    } else {
        status = AJ_SetGroupKey(msg->sender, key.val.v_byte);
    }
    if (status == AJ_OK) {
        uint8_t groupKey[AES_KEY_LEN];
        AJ_MarshalReplyMsg(msg, reply);
        AJ_GetGroupKey(NULL, groupKey);
        status = AJ_MarshalArg(reply, AJ_InitArg(&key, AJ_ARG_BYTE, AJ_ARRAY_FLAG, groupKey, sizeof(groupKey)));
    } else {
        status = AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected);
    }
    return status;
}
コード例 #15
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;
}
コード例 #16
0
ファイル: aj_connect.cpp プロジェクト: CasyWang/Triton
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;
}
コード例 #17
0
AJ_Status AJ_ARDP_UDP_Connect(AJ_BusAttachment* bus, void* context, const AJ_Service* service, AJ_NetSocket* netSock)
{
    AJ_Message hello;
    AJ_GUID localGuid;
    char guid_buf[33];
    AJ_Status status;
    AJ_Message helloResponse;

    AJ_GetLocalGUID(&localGuid);
    AJ_GUID_ToString(&localGuid, guid_buf, sizeof(guid_buf));

    AJ_MarshalMethodCall(bus, &hello, AJ_METHOD_BUS_SIMPLE_HELLO, AJ_BusDestination, 0, AJ_FLAG_ALLOW_REMOTE_MSG, AJ_UDP_CONNECT_TIMEOUT);
    AJ_MarshalArgs(&hello, "su", guid_buf, 10);
    hello.hdr->bodyLen = hello.bodyBytes;

    status = AJ_ARDP_Connect(bus->sock.tx.readPtr, AJ_IO_BUF_AVAIL(&bus->sock.tx), context, netSock);
    if (status != AJ_OK) 
	{
        return status;
    }

    status = AJ_UnmarshalMsg(bus, &helloResponse, AJ_UDP_CONNECT_TIMEOUT);
    if (status == AJ_OK && helloResponse.msgId == AJ_REPLY_ID(AJ_METHOD_BUS_SIMPLE_HELLO)) 
	{
        if (helloResponse.hdr->msgType == AJ_MSG_ERROR) 
		{
            status = AJ_ERR_CONNECT;
        } 
		else 
		{
            AJ_Arg uniqueName, protoVersion;
            AJ_UnmarshalArg(&helloResponse, &uniqueName);
            AJ_SkipArg(&helloResponse);
            AJ_UnmarshalArg(&helloResponse, &protoVersion);

            /**
			* The two most-significant bits are reserved for the nameType,
			* which we don't currently care about in the thin client
			*/
            routingProtoVersion = (uint8_t) ((*protoVersion.val.v_uint32) & 0x3FFFFFFF);

            if (uniqueName.len >= (sizeof(bus->uniqueName) - 1))
			{
                AJ_ErrPrintf(("AJ_ARDP_Connect(): AJ_ERR_RESOURCES\n"));
                status = AJ_ERR_RESOURCES;
            } 
			else 
			{
                memcpy(bus->uniqueName, uniqueName.val.v_string, uniqueName.len);
                bus->uniqueName[uniqueName.len] = '\0';
            }

           /AJ_InfoPrintf(("Received name: %s and version %u\n", bus->uniqueName, routingProtoVersion));
            if (routingProtoVersion < AJ_GetMinProtoVersion()) 
			{
                AJ_InfoPrintf(("AJ_ARDP_Connect(): Blacklisting routing node, found %u but require >= %u\n",
                               routingProtoVersion, AJ_GetMinProtoVersion()));
                AddRoutingNodeToBlacklist(service);
                status = AJ_ERR_CONNECT;
            }
        }
    } 
コード例 #18
0
AJ_Status AJ_Authenticate(AJ_BusAttachment* bus)
{
    AJ_Status status = AJ_OK;
    AJ_Message helloResponse;

    if (bus->isAuthenticated)
	{
        // ARDP does not do SASL and it sends BusHello as part of the SYN message.
        // Therefore, Hello has already been sent by the time AJ_Net_Connect() returns,
        // *before* AJ_Authenticate is called.
        return AJ_OK;
    }

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

    /* Use SASL Anonymous to connect to routing node */
	//что-то посылается, что-то получается, не особо понятно
    status = AnonymousAuthAdvance(&bus->sock.rx, &bus->sock.tx);
    if (status == AJ_OK) 
	{
        status = SendHello(bus);
    }

    if (status == AJ_OK)
	{
        status = AJ_UnmarshalMsg(bus, &helloResponse, 5000);
    }

    if (status == AJ_OK) 
	{
        if (helloResponse.hdr->msgType == AJ_MSG_ERROR) 
		{
            AJ_ErrPrintf(("AJ_Authenticate(): AJ_ERR_TIMEOUT\n"));
            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);
    }

ExitConnect:

    if (status == AJ_OK) 
	{
        bus->isAuthenticated = TRUE;
    }
    return status;
}
コード例 #19
0
ファイル: aj_helper.cpp プロジェクト: CasyWang/Triton
AJ_Status AJ_StartClient(AJ_BusAttachment* bus,
                         const char* daemonName,
                         uint32_t timeout,
                         uint8_t connected,
                         const char* name,
                         uint16_t port,
                         uint32_t* sessionId,
                         const AJ_SessionOpts* opts)
{
    AJ_Status status = AJ_OK;
    AJ_Time timer;
    uint8_t foundName = FALSE;
    uint8_t clientStarted = FALSE;
    uint32_t elapsed = 0;

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

    AJ_InitTimer(&timer);

    while (elapsed < timeout) {
        if (!connected) {
            AJ_InfoPrintf(("AJ_StartClient(): AJ_FindBusAndConnect()\n"));
            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(("Failed to connect to bus sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000));
                AJ_Sleep(AJ_CONNECT_PAUSE);
                continue;
            }
            AJ_InfoPrintf(("AllJoyn client connected to bus\n"));
        }
        /*
         * Kick things off by finding the service names
         */
        AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n"));
        status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING);
        if (status == AJ_OK) {
            break;
        }
        if (!connected) {
            AJ_WarnPrintf(("AjStartClient2(): AJ_Disconnect(): status=%s.\n", AJ_StatusText(status)));
            AJ_Disconnect(bus);
        }
    }
    if (elapsed > timeout) {
        return AJ_ERR_TIMEOUT;
    }
    timeout -= elapsed;

    *sessionId = 0;

    while (!clientStarted && (status == AJ_OK)) {
        AJ_Message msg;
        status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT);
        if ((status == AJ_ERR_TIMEOUT) && !foundName) {
            /*
             * Timeouts are expected until we find a name
             */
            if (timeout < AJ_UNMARSHAL_TIMEOUT) {
                return status;
            }
            timeout -= AJ_UNMARSHAL_TIMEOUT;
            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));
                foundName = TRUE;
                status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts);
            }
            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_ERR_FAILURE\n"));
                        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) {
        AJ_WarnPrintf(("AJ_StartClient(): AJ_Disconnect(): status=%s\n", AJ_StatusText(status)));
        AJ_Disconnect(bus);
    }
    return status;
}
コード例 #20
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, 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;
}
コード例 #21
0
ファイル: aj_helper.c プロジェクト: reignme/ajtcl
AJ_Status AJ_StartClient2(AJ_BusAttachment* bus,
                          const char* daemonName,
                          uint32_t timeout,
                          uint8_t connected,
                          const char* name,
                          uint16_t port,
                          uint32_t* sessionId,
                          const AJ_SessionOpts* opts
                          )
{
    AJ_Status status = AJ_OK;
    AJ_Time timer;
    AJ_Time unmarshalTimer;
    uint8_t foundName = FALSE;
    uint8_t clientStarted = FALSE;
    uint8_t initial = TRUE;
    AJ_InitTimer(&timer);

    while (TRUE) {
        if (AJ_GetElapsedTime(&timer, TRUE) > timeout) {
            return AJ_ERR_TIMEOUT;
        }
        if (!initial || !connected) {
            initial = FALSE;
            AJ_InfoPrintf(("Attempting to connect to bus\n"));
            status = AJ_Connect(bus, daemonName, CONNECT_TIMEOUT);
            if (status != AJ_OK) {
                AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", CONNECT_PAUSE / 1000));
                AJ_Sleep(CONNECT_PAUSE);
                continue;
            }
            AJ_InfoPrintf(("AllJoyn client connected to bus\n"));
        }
        /*
         * Kick things off by finding the service names
         */
        status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING);
        if (status == AJ_OK) {
            break;
        }
        AJ_WarnPrintf(("FindAdvertisedName failed\n"));
        AJ_Disconnect(bus);
    }

    *sessionId = 0;

    while (!clientStarted && (status == AJ_OK)) {
        AJ_Message msg;

        if (AJ_GetElapsedTime(&timer, TRUE) > timeout) {
            return AJ_ERR_TIMEOUT;
        }
        status = AJ_UnmarshalMsg(bus, &msg, UNMARSHAL_TIMEOUT);
        /*
         * TODO This is a temporary hack to work around buggy select imlpementations
         */
        AJ_InitTimer(&unmarshalTimer);
        if (status == AJ_ERR_TIMEOUT && (AJ_GetElapsedTime(&unmarshalTimer, TRUE) < UNMARSHAL_TIMEOUT || !foundName)) {
            /*
             * Timeouts are expected until we find a name
             */
            status = AJ_OK;
            continue;
        }

        if (status != AJ_OK) {
            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) {
                status = AJ_ERR_FAILURE;
            } else {
                uint32_t disposition;
                AJ_UnmarshalArgs(&msg, "u", &disposition);
                if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) {
                    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));
                foundName = TRUE;
                status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts);
            }
            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, sessionId);
                    if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) {
                        clientStarted = TRUE;
                        AJ_BusSetSignalRule2(bus, "NameOwnerChanged", "org.freedesktop.DBus", AJ_BUS_SIGNAL_ALLOW);
                    } else {
                        status = AJ_ERR_FAILURE;
                    }
                }
            }
            break;

        case AJ_SIGNAL_SESSION_LOST:
            /*
             * Force a disconnect
             */
            status = AJ_ERR_READ;
            break;

        default:
            /*
             * Pass to the built-in bus message handlers
             */
            status = AJ_BusHandleBusMessage(&msg);
            break;
        }
        AJ_CloseMsg(&msg);
    }
    if (status != AJ_OK) {
        AJ_WarnPrintf(("AllJoyn disconnect bus status=%s\n", AJ_StatusText(status)));
        AJ_Disconnect(bus);
    }
    return status;
}
コード例 #22
0
ファイル: aj_connect.c プロジェクト: reignme/ajtcl
AJ_Status AJ_Connect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout)
{
    AJ_Status status;
    AJ_SASL_Context sasl;
    AJ_Service service;
    /*
     * Clear the bus struct
     */
    memset(bus, 0, sizeof(AJ_BusAttachment));
    /*
     * Clear stale name->GUID mappings
     */
    AJ_GUID_ClearNameMap();
    /*
     * Host-specific network bring-up procedure. This includes establishing a connection to the
     * network and initializing the I/O buffers.
     */
    status = AJ_Net_Up();
    if (status != AJ_OK) {
        return status;
    }
    /*
     * 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) {
        goto ExitConnect;
    }
#elif defined AJ_SERIAL_CONNECTION
    // don't bother with discovery, we are connected to a daemon.
#else
    status = AJ_Discover(serviceName, &service, timeout);
    if (status != AJ_OK) {
        goto ExitConnect;
    }
#endif
    status = AJ_Net_Connect(&bus->sock, service.ipv4port, service.addrTypes & AJ_ADDR_IPV4, &service.ipv4);
    if (status != AJ_OK) {
        goto ExitConnect;
    }
    /*
     * 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) {
        goto ExitConnect;
    }
    AJ_SASL_InitContext(&sasl, mechList, AJ_AUTH_RESPONDER, busAuthPwdFunc);
    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)) {
                        status = AJ_ERR_RESOURCES;
                    } else {
                        memcpy(bus->uniqueName, arg.val.v_string, arg.len);
                        bus->uniqueName[arg.len] = '\0';
                    }
                }
            }
            AJ_CloseMsg(&helloResponse);
        }
    }

ExitConnect:

    if (status != AJ_OK) {
        AJ_Printf("AllJoyn connect failed %d\n", status);
        AJ_Disconnect(bus);
    }
    return status;
}
コード例 #23
0
ファイル: aj_peer.c プロジェクト: bigzero/ajtcl
AJ_Status AJ_PeerHandleAuthChallenge(AJ_Message* msg, AJ_Message* reply)
{
    AJ_Status status;
    AJ_Arg arg;
    char* buf = NULL;
    const AJ_GUID* peerGuid = AJ_GUID_Find(msg->sender);

    /*
     * We expect to know the GUID of the sender
     */
    if (!peerGuid) {
        return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected);
    }
    /*
     * Check for an authentication conversation in progress with a different peer
     */
    if (authContext.peerGuid && (authContext.peerGuid != peerGuid)) {
        /*
         * Reject the request if the existing conversation has not expired
         */
        if (AJ_GetElapsedTime(&authContext.timer, TRUE) < MAX_AUTH_TIME) {
            return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected);
        }
        memset(&authContext, 0, sizeof(AuthContext));
    }
    if (authContext.sasl.state == AJ_SASL_IDLE) {
        /*
         * Remember which peer is being authenticated and initialize the timeout timer
         */
        authContext.peerGuid = peerGuid;
        AJ_InitTimer(&authContext.timer);
        /*
         * Initialize SASL state machine
         */
        AJ_SASL_InitContext(&authContext.sasl, authMechanisms, AJ_AUTH_CHALLENGER, msg->bus->pwdCallback);
    }
    if (AJ_UnmarshalArg(msg, &arg) != AJ_OK) {
        goto FailAuth;
    }
    /*
     * Need a short-lived buffer to compose the response
     */
    buf = (char*)AJ_Malloc(AUTH_BUF_LEN);
    if (!buf) {
        status = AJ_ERR_RESOURCES;
        goto FailAuth;
    }
    status = AJ_SASL_Advance(&authContext.sasl, (char*)arg.val.v_string, buf, AUTH_BUF_LEN);
    if (status != AJ_OK) {
        goto FailAuth;
    }
    AJ_MarshalReplyMsg(msg, reply);
    AJ_MarshalArgs(reply, "s", buf);
    AJ_Free(buf);
    if (authContext.sasl.state == AJ_SASL_AUTHENTICATED) {
        status = authContext.sasl.mechanism->Final(peerGuid);
        memset(&authContext, 0, sizeof(AuthContext));
    }
    return status;

FailAuth:

    AJ_Free(buf);
    /*
     * Clear current authentication context then return an error response
     */
    if (authContext.sasl.mechanism) {
        authContext.sasl.mechanism->Final(peerGuid);
    }
    memset(&authContext, 0, sizeof(AuthContext));
    return AJ_MarshalErrorMsg(msg, reply, AJ_ErrSecurityViolation);
}
コード例 #24
0
ファイル: clientlite.c プロジェクト: gwgoliath/learnalljoyn
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;
}
コード例 #25
0
ファイル: SecureClient.c プロジェクト: durake/core-ajtcl
int AJ_Main(void)
{
    int done = FALSE;
    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 (!done) {
        AJ_Message msg;

        if (!connected) {
            status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServiceName, ServicePort, &sessionId, NULL, fullServiceName);
            if (status == AJ_OK) {
                AJ_InfoPrintf(("StartClient returned %d, sessionId=%u\n", status, sessionId));
                connected = TRUE;
                if (authenticate) {
                    AJ_BusSetPasswordCallback(&bus, PasswordCallback);
                    authStatus = AJ_BusAuthenticatePeer(&bus, fullServiceName, AuthCallback, &authStatus);
                } else {
                    authStatus = AJ_OK;
                }
            } else {
                AJ_InfoPrintf(("StartClient returned %d\n", status));
                break;
            }
        }

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

        status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT);

        if (AJ_ERR_TIMEOUT == status) {
            AppDoWork();
            continue;
        }

        if (AJ_OK == status) {
            switch (msg.msgId) {
            case AJ_REPLY_ID(PRX_PING):
                {
                    AJ_Arg arg;

                    if (AJ_OK == AJ_UnmarshalArg(&msg, &arg)) {
                        AJ_AlwaysPrintf(("%s.Ping (path=%s) returned \"%s\".\n", InterfaceName,
                                         ServicePath, arg.val.v_string));

                        if (strcmp(arg.val.v_string, pingString) == 0) {
                            AJ_InfoPrintf(("Ping was successful.\n"));
                        } else {
                            AJ_InfoPrintf(("Ping returned different string.\n"));
                        }
                    } else {
                        AJ_ErrPrintf(("Bad ping response.\n"));
                    }

                    done = TRUE;
                }
                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_READ) {
            AJ_AlwaysPrintf(("AllJoyn disconnect.\n"));
            AJ_Disconnect(&bus);
            exit(0);
        }
    }

    AJ_AlwaysPrintf(("SecureClient EXIT %d.\n", status));

    return status;
}
コード例 #26
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;
}
コード例 #27
0
ファイル: mutter.c プロジェクト: reignme/ajtcl
int AJ_Main()
{
    AJ_Status status;
    AJ_BusAttachment bus;
    AJ_Message txMsg;
    AJ_Message rxMsg;
    AJ_Arg arg;
    AJ_Arg array1;
    AJ_Arg array2;
    AJ_Arg struct1;
    AJ_Arg struct2;
    size_t sz;
    uint32_t i;
    uint32_t j;
    uint32_t k;
    uint32_t key;
    uint32_t len;
    uint32_t u;
    uint32_t v;
    int32_t n;
    int32_t m;
    uint16_t q;
    uint16_t r;
    uint8_t y;
    char* str;
    char* sig;
    void* raw;

    bus.sock.tx.direction = AJ_IO_BUF_TX;
    bus.sock.tx.bufSize = sizeof(txBuffer);
    bus.sock.tx.bufStart = txBuffer;
    bus.sock.tx.readPtr = bus.sock.tx.bufStart;
    bus.sock.tx.writePtr = bus.sock.tx.bufStart;
    bus.sock.tx.send = TxFunc;

    bus.sock.rx.direction = AJ_IO_BUF_RX;
    bus.sock.rx.bufSize = sizeof(rxBuffer);
    bus.sock.rx.bufStart = rxBuffer;
    bus.sock.rx.readPtr = bus.sock.rx.bufStart;
    bus.sock.rx.writePtr = bus.sock.rx.bufStart;
    bus.sock.rx.recv = RxFunc;

    /*
     * Set the hook
     */
#ifndef NDEBUG
    MutterHook = MsgInit;
#else
    AJ_Printf("mutter only works in DEBUG builds\n");
    return -1;
#endif

    for (i = 0; i < ArraySize(testSignature); ++i) {

        status = AJ_MarshalSignal(&bus, &txMsg, i, "mutter.service", 0, 0, 0);
        if (status != AJ_OK) {
            break;
        }

        switch (i) {
        case 0:
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (key = 0; key < ArraySize(Fruits); ++key) {
                AJ_Arg dict;
                CHECK(AJ_MarshalContainer(&txMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_MarshalArgs(&txMsg, "us", key, Fruits[key]));
                CHECK(AJ_MarshalCloseContainer(&txMsg, &dict));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            break;

        case 1:
            CHECK(AJ_MarshalArgs(&txMsg, "u", 11111));
            CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_MarshalArgs(&txMsg, "usu", 22222, "hello", 33333));
            CHECK(AJ_MarshalContainer(&txMsg, &struct2, AJ_ARG_STRUCT));
            CHECK(AJ_MarshalArgs(&txMsg, "ii", -100, -200));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &struct2));
            CHECK(AJ_MarshalArgs(&txMsg, "qsq", 4444, "goodbye", 5555));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            CHECK(AJ_MarshalArgs(&txMsg, "yyy", 1, 2, 3));
            break;

        case 2:
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (u = 0; u < ArraySize(Fruits); ++u) {
                CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
                CHECK(AJ_MarshalArgs(&txMsg, "us", u, Fruits[u]));
                CHECK(AJ_MarshalArg(&txMsg, AJ_InitArg(&arg, AJ_ARG_BYTE, AJ_ARRAY_FLAG, Data8, u)));
                CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            break;

        case 3:
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (j = 0; j < 3; ++j) {
                CHECK(AJ_MarshalContainer(&txMsg, &array2, AJ_ARG_ARRAY));
                for (k = j; k < ArraySize(Fruits); ++k) {
                    CHECK(AJ_MarshalArgs(&txMsg, "s", Fruits[k]));
                }
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array2));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            break;

        case 4:
            CHECK(AJ_MarshalArgs(&txMsg, "i", 987654321));
            CHECK(AJ_MarshalVariant(&txMsg, "a(ii)"));
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (j = 0; j < 16; ++j) {
                CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
                CHECK(AJ_MarshalArgs(&txMsg, "ii", j + 1, (j + 1) * 100));
                CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            CHECK(AJ_MarshalArgs(&txMsg, "i", 123456789));
            break;

        case 5:
            CHECK(AJ_MarshalVariant(&txMsg, "(ivi)"));
            CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_MarshalArgs(&txMsg, "i", 1212121));
            CHECK(AJ_MarshalVariant(&txMsg, "s"));
            CHECK(AJ_MarshalArgs(&txMsg, "s", "inner variant"));
            CHECK(AJ_MarshalArgs(&txMsg, "i", 3434343));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            break;

        case 6:
            CHECK(AJ_MarshalVariant(&txMsg, "v"));
            CHECK(AJ_MarshalVariant(&txMsg, "v"));
            CHECK(AJ_MarshalVariant(&txMsg, "v"));
            CHECK(AJ_MarshalVariant(&txMsg, "v"));
            CHECK(AJ_MarshalVariant(&txMsg, "s"));
            CHECK(AJ_MarshalArgs(&txMsg, "s", "deep variant"));
            break;

        case 7:
            CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_MarshalVariant(&txMsg, "i"));
            CHECK(AJ_MarshalArgs(&txMsg, "i", 1212121));
            CHECK(AJ_MarshalVariant(&txMsg, "s"));
            CHECK(AJ_MarshalArgs(&txMsg, "s", "variant"));
            CHECK(AJ_MarshalVariant(&txMsg, "ay"));
            CHECK(AJ_MarshalArg(&txMsg, AJ_InitArg(&arg, AJ_ARG_BYTE, AJ_ARRAY_FLAG, Data8, sizeof(Data8))));
            CHECK(AJ_MarshalVariant(&txMsg, "aq"));
            CHECK(AJ_MarshalArg(&txMsg, AJ_InitArg(&arg, AJ_ARG_UINT16, AJ_ARRAY_FLAG, Data16, sizeof(Data16))));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            break;

        case 8:
            CHECK(AJ_MarshalArgs(&txMsg, "uq", 0xF00F00F0, 0x0707));
            len = 5000;
            CHECK(AJ_DeliverMsgPartial(&txMsg, len + 4));
            CHECK(AJ_MarshalRaw(&txMsg, &len, 4));
            for (j = 0; j < len; ++j) {
                uint8_t n = (uint8_t)j;
                CHECK(AJ_MarshalRaw(&txMsg, &n, 1));
            }
            break;

        case 9:
            len = 500;
            u = len * sizeof(TestStruct);
            CHECK(AJ_DeliverMsgPartial(&txMsg, u + sizeof(u) + 4));
            CHECK(AJ_MarshalRaw(&txMsg, &u, sizeof(u)));
            /*
             * Structs are always 8 byte aligned
             */
            u = 0;
            CHECK(AJ_MarshalRaw(&txMsg, &u, 4));
            for (j = 0; j < len; ++j) {
                TestStruct ts;
                ts.a = j;
                ts.b = j + 1;
                ts.c = j + 2;
                ts.d = j + 3;
                CHECK(AJ_MarshalRaw(&txMsg, &ts, sizeof(ts)));
            }
            break;

        case 10:
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            break;

        case 11:
            CHECK(AJ_MarshalArgs(&txMsg, "y", 127));
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (key = 0; key < ArraySize(Colors); ++key) {
                AJ_Arg dict;
                CHECK(AJ_MarshalContainer(&txMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_MarshalArgs(&txMsg, "ss", Colors[key], Fruits[key]));
                CHECK(AJ_MarshalCloseContainer(&txMsg, &dict));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            break;

        case 12:
            CHECK(AJ_MarshalArgs(&txMsg, "y", 0x11));
            CHECK(AJ_MarshalArgs(&txMsg, "y", 0x22));
            CHECK(AJ_MarshalArgs(&txMsg, "y", 0x33));
            CHECK(AJ_MarshalArgs(&txMsg, "y", 0x44));
            CHECK(AJ_MarshalArgs(&txMsg, "y", 0x55));
            CHECK(AJ_MarshalContainer(&txMsg, &array1, AJ_ARG_ARRAY));
            for (key = 0; key < ArraySize(Colors); ++key) {
                AJ_Arg dict;
                CHECK(AJ_MarshalContainer(&txMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_MarshalArgs(&txMsg, "ys", (uint8_t)key, Colors[key]));
                CHECK(AJ_MarshalCloseContainer(&txMsg, &dict));
            }
            if (status == AJ_OK) {
                CHECK(AJ_MarshalCloseContainer(&txMsg, &array1));
            }
            break;

        case 13:
            CHECK(AJ_MarshalContainer(&txMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_MarshalArgs(&txMsg, "i", 3434343));
            CHECK(AJ_MarshalArg(&txMsg, AJ_InitArg(&arg, AJ_ARG_BYTE, AJ_ARRAY_FLAG, Data8, sizeof(Data8))));
            CHECK(AJ_MarshalCloseContainer(&txMsg, &struct1));
            break;
        }
        if (status != AJ_OK) {
            AJ_Printf("Failed %d\n", i);
            break;
        }

        AJ_Printf("deliver\n");
        AJ_DeliverMsg(&txMsg);

        status = AJ_UnmarshalMsg(&bus, &rxMsg, 0);
        if (status != AJ_OK) {
            break;
        }

        switch (i) {
        case 0:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (TRUE) {
                char* fruit;
                AJ_Arg dict;
                CHECK(AJ_UnmarshalContainer(&rxMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_UnmarshalArgs(&rxMsg, "us", &key, &fruit));
                AJ_Printf("Unmarshal[%d] = %s\n", key, fruit);
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &dict));
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 1:
            CHECK(AJ_UnmarshalArgs(&rxMsg, "u", &u));
            AJ_Printf("Unmarshal %u\n", u);
            CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "usu", &u, &str, &v));
            AJ_Printf("Unmarshal %u %s %u\n", u, str, v);
            CHECK(AJ_UnmarshalContainer(&rxMsg, &struct2, AJ_ARG_STRUCT));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "ii", &n, &m));
            AJ_Printf("Unmarshal %d %d\n", n, m);
            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct2));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "qsq", &q, &str, &r));
            AJ_Printf("Unmarshal %u %s %u\n", q, str, r);
            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            AJ_Printf("Unmarshal %d\n", y);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            AJ_Printf("Unmarshal %d\n", y);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            AJ_Printf("Unmarshal %d\n", y);
            break;

        case 2:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (status == AJ_OK) {
                CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
                CHECK(AJ_UnmarshalArgs(&rxMsg, "us", &u, &str));
                CHECK(AJ_UnmarshalArg(&rxMsg, &arg));
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 3:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (status == AJ_OK) {
                CHECK(AJ_UnmarshalContainer(&rxMsg, &array2, AJ_ARG_ARRAY));
                while (status == AJ_OK) {
                    CHECK(AJ_UnmarshalArg(&rxMsg, &arg));
                    AJ_Printf("Unmarshal %s\n", arg.val.v_string);
                }
                /*
                 * We expect AJ_ERR_NO_MORE
                 */
                if (status == AJ_ERR_NO_MORE) {
                    CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array2));
                }
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 4:
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &j));
            AJ_Printf("Unmarshal %d\n", j);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (status == AJ_OK) {
                CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
                CHECK(AJ_UnmarshalArgs(&rxMsg, "ii", &j, &k));
                AJ_Printf("Unmarshal[%d] %d\n", j, k);
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status != AJ_ERR_NO_MORE) {
                break;
            }
            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &j));
            AJ_Printf("Unmarshal %d\n", j);
            break;

        case 5:
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &j));
            AJ_Printf("Unmarshal %d\n", j);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "s", &str));
            AJ_Printf("Unmarshal %s\n", str);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &j));
            AJ_Printf("Unmarshal %d\n", j);
            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            break;

        case 6:
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "s", &str));
            AJ_Printf("Unmarshal %s\n", str);
            break;

        case 7:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &j));
            AJ_Printf("Unmarshal %d\n", j);
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArgs(&rxMsg, "s", &str));
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArg(&rxMsg, &arg));
            CHECK(AJ_UnmarshalVariant(&rxMsg, (const char**)&sig));
            AJ_Printf("Unmarshal variant %s\n", sig);
            CHECK(AJ_UnmarshalArg(&rxMsg, &arg));
            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            break;

        case 8:
            CHECK(AJ_UnmarshalArgs(&rxMsg, "uq", &j, &q));
            AJ_Printf("Unmarshal %x\n", j);
            AJ_Printf("Unmarshal %x\n", q);
            CHECK(AJ_UnmarshalRaw(&rxMsg, (const void**)&raw, sizeof(len), &sz));
            len = *((uint32_t*)raw);
            AJ_Printf("UnmarshalRaw %d\n", len);
            for (j = 0; j < len; ++j) {
                uint8_t v;
                CHECK(AJ_UnmarshalRaw(&rxMsg, (const void**)&raw, 1, &sz));
                v = *((uint8_t*)raw);
                if (v != (uint8_t)j) {
                    status = AJ_ERR_FAILURE;
                    break;
                }
            }
            break;

        case 9:
            CHECK(AJ_UnmarshalRaw(&rxMsg, (const void**)&raw, 4, &sz));
            len = *((uint32_t*)raw) / sizeof(TestStruct);
            /*
             * Structs are always 8 byte aligned
             */
            CHECK(AJ_UnmarshalRaw(&rxMsg, (const void**)&raw, 4, &sz));
            for (j = 0; j < len; ++j) {
                TestStruct* ts;
                CHECK(AJ_UnmarshalRaw(&rxMsg, (const void**)&ts, sizeof(TestStruct), &sz));
                if ((ts->a != j) || (ts->b != (j + 1)) || (ts->c != (j + 2)) || (ts->d != (j + 3))) {
                    status = AJ_ERR_FAILURE;
                    break;
                }
            }
            break;

        case 10:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            status = AJ_UnmarshalArg(&rxMsg, &arg);
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 11:
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (TRUE) {
                AJ_Arg dict;
                char* fruit;
                char* color;
                CHECK(AJ_UnmarshalContainer(&rxMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_UnmarshalArgs(&rxMsg, "ss", &color, &fruit));
                AJ_Printf("Unmarshal[%s] = %s\n", color, fruit);
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &dict));
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 12:
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "y", &y));
            CHECK(AJ_UnmarshalContainer(&rxMsg, &array1, AJ_ARG_ARRAY));
            while (TRUE) {
                AJ_Arg dict;
                char* color;
                CHECK(AJ_UnmarshalContainer(&rxMsg, &dict, AJ_ARG_DICT_ENTRY));
                CHECK(AJ_UnmarshalArgs(&rxMsg, "ys", &y, &color));
                AJ_Printf("Unmarshal[%d] = %s\n", y, color);
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &dict));
            }
            /*
             * We expect AJ_ERR_NO_MORE
             */
            if (status == AJ_ERR_NO_MORE) {
                CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &array1));
            }
            break;

        case 13:
            CHECK(AJ_UnmarshalContainer(&rxMsg, &struct1, AJ_ARG_STRUCT));
            CHECK(AJ_UnmarshalArgs(&rxMsg, "i", &n));
            AJ_ASSERT(n == 3434343);

            CHECK(AJ_UnmarshalArg(&rxMsg, &arg));
            for (j = 0; j < arg.len; ++j) {
                uint8_t val = arg.val.v_byte[j];
                AJ_Printf("Unmarhsalled array1[%u] = %u\n", j, val);
                AJ_ASSERT(val == Data8[j]);
            }

            CHECK(AJ_UnmarshalCloseContainer(&rxMsg, &struct1));
            break;
        }

        if (status != AJ_OK) {
            AJ_Printf("Failed %d\n", i);
            break;
        }
        AJ_CloseMsg(&rxMsg);
        AJ_Printf("Passed %d\n", i);

    }
    if (status != AJ_OK) {
        AJ_Printf("Marshal/Unmarshal unit test[%d] failed %d\n", i, status);
    }

    return status;
}