Example #1
0
static AJ_Status MarshalContainer(AJ_Message* msg, const char** sig, AJ_Arg* arg, uint8_t pad)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;

    *sig -= 1;
    arg->sigPtr = *sig + 1;
    if (**sig == AJ_ARG_ARRAY) {
        /*
         * Reserve space for the length and save a pointer to it
         */
        status = WriteBytes(msg, NULL, 0, pad + 4);
        arg->val.v_data = ioBuf->writePtr - 4;
        /*
         * Might need to pad if the elements align on an 8 byte boundary
         */
        if (status == AJ_OK) {
            status = WritePad(msg, PadForType(arg->sigPtr[0], ioBuf));
        }
    } else {
        status = WritePad(msg, pad);
    }
    /*
     * Consume container signature
     */
    *sig += CompleteTypeSigLen(*sig);
    return status;
}
Example #2
0
bool  ZFile::WriteAlignedString(const ZString& str)
{
    int length = str.GetLength() + 1;

    if (Write((void*)(PCC)str, str.GetLength() + 1) != 0) {
        return WritePad(length);
    }

    return false;
}
Example #3
0
AJ_Status AJ_DeliverMsgPartial(AJ_Message* msg, uint32_t bytesRemaining)
{
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;
    uint8_t typeId = msg->signature[msg->sigOffset];
    size_t pad;

    AJ_ASSERT(!msg->outer);

    if (!msg->hdr || !bytesRemaining) {
        return AJ_ERR_UNEXPECTED;
    }
    /*
     * Partial delivery not currently supported for messages that must be encrypted.
     */
    if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) {
        return AJ_ERR_SECURITY;
    }
    /*
     * There must be arguments to marshal
     */
    if (!typeId) {
        return AJ_ERR_SIGNATURE;
    }
    /*
     * Pad to the start of the argument.
     */
    pad = PadForType(typeId, ioBuf);
    if (pad) {
        AJ_Status status = WritePad(msg, pad);
        if (status != AJ_OK) {
            return status;
        }
    }
    /*
     * Set the body length in the header buffer.
     */
    msg->hdr->bodyLen = (uint32_t)(msg->bodyBytes + pad + bytesRemaining);
    AJ_DumpMsg("SENDING(partial)", msg, FALSE);
    /*
     * The buffer space occupied by the header is going to be overwritten
     * so the header is going to become invalid.
     */
    msg->hdr = NULL;
    /*
     * From now on we are going to count down the remaining body bytes
     */
    msg->bodyBytes = (uint32_t)bytesRemaining;
    /*
     * Standard signature matching is now meaningless
     */
    msg->signature = "";
    msg->sigOffset = 0;;

    return AJ_OK;
}
Example #4
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;
}
Example #5
0
static AJ_Status Marshal(AJ_Message* msg, const char** sig, AJ_Arg* arg)
{
    AJ_Status status = AJ_OK;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.tx;
    char typeId = **sig;
    uint32_t pad = PadForType(typeId, ioBuf);
    size_t sz;

    if (!arg) {
        return AJ_ERR_NULL;
    }
    *sig += 1;
    if (IsScalarType(arg->typeId)) {
        if (arg->flags & AJ_ARRAY_FLAG) {
            if ((typeId != AJ_ARG_ARRAY) || (**sig != arg->typeId)) {
                return AJ_ERR_MARSHAL;
            }
            *sig += 1;
            sz = arg->len;
            status = WriteBytes(msg, &sz, 4, pad);
            if (status == AJ_OK) {
                /*
                 * May need to pad if the elements required 8 byte alignment
                 */
                pad = PadForType(arg->typeId, ioBuf);
            }
        } else {
            if (typeId != arg->typeId) {
                return AJ_ERR_MARSHAL;
            }
            sz = SizeOfType(typeId);
        }
        if (status == AJ_OK) {
            status = WriteBytes(msg, arg->val.v_data, sz, pad);
        }
    } else if (TYPE_FLAG(typeId) & (AJ_STRING | AJ_VARIANT)) {
        if (typeId != arg->typeId) {
            return AJ_ERR_MARSHAL;
        }
        sz = arg->len ? arg->len : strlen(arg->val.v_string);
        /*
         * Length field for a signature is 1 byte, for regular strings its 4 bytes
         */
        if (ALIGNMENT(typeId) == 1) {
            uint8_t szu8 = (uint8_t)sz;
            if (sz > 255) {
                return AJ_ERR_MARSHAL;
            }
            status = WriteBytes(msg, &szu8, 1, pad);
        } else {
            status = WriteBytes(msg, &sz, 4, pad);
        }
        if (status == AJ_OK) {
            status = WriteBytes(msg, arg->val.v_string, sz, 0);
            /*
             * String must be NUL terminated on the wire
             */
            if (status == AJ_OK) {
                status = WritePad(msg, 1);
            }
            /*
             * If marshalling a variant store offset to start of signature
             */
            if (typeId == AJ_ARG_VARIANT) {
                msg->varOffset = (uint8_t)(sz + 1);
            }
        }
    } else if (TYPE_FLAG(typeId) & AJ_CONTAINER) {
        if (typeId != arg->typeId) {
            return AJ_ERR_MARSHAL;
        }
        status = MarshalContainer(msg, sig, arg, pad);
    } else {
        return AJ_ERR_MARSHAL;
    }
    return status;
}