/*
 * Looks for an interface that defines a specific member.
 *
 * TODO - check for ambiguity - same member defined on multiple interfaces
 */
static const char* FindInterfaceForMember(duk_context* ctx, duk_idx_t mbrIdx, const char** member)
{
    const char* iface = NULL;
    uint8_t found = FALSE;
    size_t numInterfaces;
    duk_idx_t listIdx;

    duk_get_prop_string(ctx, -1, "interfaces");
    numInterfaces = duk_get_length(ctx, -1);
    listIdx = AJS_GetAllJoynProperty(ctx, "interfaceDefinition");

    if (duk_is_object(ctx, mbrIdx)) {
        /*
         * Expect an object of form { member:"org.foo.interface" }
         */
        duk_enum(ctx, mbrIdx, DUK_ENUM_OWN_PROPERTIES_ONLY);
        if (!duk_next(ctx, -1, 1)) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "Require object of form { 'member-name':'interface-name' }");
        }
        iface = duk_require_string(ctx, -1);
        if (!AJ_StringFindFirstOf(iface, ".") == -1) {
            duk_error(ctx, DUK_ERR_TYPE_ERROR, "Interface name '%s' is not a dotted name", iface);
        }
        *member = duk_require_string(ctx, -2);
        duk_get_prop_string(ctx, listIdx, iface);
        if (duk_is_undefined(ctx, -1)) {
            duk_error(ctx, DUK_ERR_REFERENCE_ERROR, "Unknown interface: '%s'", iface);
        }
        found = duk_has_prop_string(ctx, -1, *member);
        duk_pop_n(ctx, 4);
    } else {
        size_t i;
        /*
         * Expect a string
         */
        *member = duk_require_string(ctx, mbrIdx);
        for (i = 0; !found && (i < numInterfaces); ++i) {
            duk_get_prop_index(ctx, -2, i);
            iface = duk_require_string(ctx, -1);
            duk_get_prop_string(ctx, listIdx, iface);
            /*
             * See if the requested member exists on this interface
             */
            found = duk_has_prop_string(ctx, -1, *member);
            duk_pop_2(ctx);
        }
    }
    duk_pop_2(ctx);
    if (!found) {
        duk_error(ctx, DUK_ERR_REFERENCE_ERROR, "Unknown member: '%s'", *member);
    }
    return iface;
}
Exemple #2
0
static const AJ_AuthMechanism* SelectAuth(AJ_SASL_Context* context, char* inStr)
{
    const AJ_AuthMechanism* mech = NULL;

    if (!*inStr) {
        return context->mechList[context->nextMech];
    }
    while (!mech && *inStr) {
        int32_t pos = AJ_StringFindFirstOf(inStr, " ");
        if (pos > 0) {
            inStr[pos] = '\0';
        }
        mech = MatchMechanism(context, &inStr);
        inStr += pos;
    }
    return mech;
}
Exemple #3
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;
}