AJ_Status AJ_BusAddSignalRule(AJ_BusAttachment* bus, const char* signalName, const char* interfaceName, uint8_t rule)
{
    AJ_Status status;
    AJ_Message msg;
    const char* str[5];
    uint32_t msgId = (rule == AJ_BUS_SIGNAL_ALLOW) ? AJ_METHOD_ADD_MATCH : AJ_METHOD_REMOVE_MATCH;

    AJ_InfoPrintf(("AJ_BusAddSignalRule(bus=0x%p, signalName=\"%s\", interfaceName=\"%s\", rule=%d.)\n", bus, signalName, interfaceName, rule));

    str[0] = "type='signal',member='";
    str[1] = signalName;
    str[2] = "'interface='";
    str[3] = interfaceName;
    str[4] = "'";

    status = AJ_MarshalMethodCall(bus, &msg, msgId, AJ_DBusDestination, 0, 0, AJ_METHOD_TIMEOUT);
    if (status == AJ_OK) {
        size_t i;
        uint32_t sz = 0;
        uint8_t nul = 0;
        for (i = 0; i < ArraySize(str); ++i) {
            sz += (uint32_t)strlen(str[i]);
        }
        status = AJ_DeliverMsgPartial(&msg, sz + 5);
        AJ_MarshalRaw(&msg, &sz, 4);
        for (i = 0; i < ArraySize(str); ++i) {
            AJ_MarshalRaw(&msg, str[i], strlen(str[i]));
        }
        AJ_MarshalRaw(&msg, &nul, 1);
    }
    if (status == AJ_OK) {
        status = AJ_DeliverMsg(&msg);
    }
    return status;
}
Beispiel #2
0
AJ_Status AJ_BusSetSignalRuleSerial(AJ_BusAttachment* bus, const char* ruleString, uint8_t rule, uint8_t flags, uint32_t* serialNum)
{
    AJ_Status status;
    AJ_Message msg;
    uint32_t msgId = (rule == AJ_BUS_SIGNAL_ALLOW) ? AJ_METHOD_ADD_MATCH : AJ_METHOD_REMOVE_MATCH;

    AJ_InfoPrintf(("AJ_BusSetSignalRuleSerial(bus=0x%p, ruleString=\"%s\", rule=%d.)\n", bus, ruleString, rule));

    status = AJ_MarshalMethodCall(bus, &msg, msgId, AJ_DBusDestination, 0, flags, AJ_METHOD_TIMEOUT);
    if (status == AJ_OK) {
        uint32_t sz = 0;
        uint8_t nul = 0;
        if (serialNum) {
            *serialNum = msg.hdr->serialNum;
        }
        sz = (uint32_t)strlen(ruleString);
        status = AJ_DeliverMsgPartial(&msg, sz + 5);
        AJ_MarshalRaw(&msg, &sz, 4);
        AJ_MarshalRaw(&msg, ruleString, strlen(ruleString));
        AJ_MarshalRaw(&msg, &nul, 1);
    }
    if (status == AJ_OK) {
        status = AJ_DeliverMsg(&msg);
    }
    return status;
}
void WriteXML(void* context, const char* str, uint32_t len)
{
    WriteContext* wctx = (WriteContext*)context;
    if (wctx->status == AJ_OK) {
        if (!len) {
            len = (uint32_t)strlen(str);
        }
        wctx->status = AJ_MarshalRaw(wctx->reply, str, len);
    }
}
AJ_Status AJ_HandleIntrospectRequest(const AJ_Message* msg, AJ_Message* reply)
{
    AJ_Status status = AJ_OK;
    const AJ_Object* obj = objectLists[AJ_APP_ID_FLAG];
    uint32_t children = 0;
    AJ_Object parent;
    WriteContext context;

    /*
     * Return an error if there are no local objects
     */
    if (!obj) {
        return AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown);
    }
    /*
     * Find out which object we are introspecting. There are two possibilities:
     *
     * - The request has a complete object path to one of the application objects.
     * - The request has a path to a parent object of one or more application objects where the
     *   parent itself is just a place-holder in the object hierarchy.
     */
    for (; obj->path != NULL; ++obj) {
        if (strcmp(msg->objPath, obj->path) == 0) {
            break;
        }
        if (ChildPath(msg->objPath, obj->path, NULL)) {
            ++children;
        }
    }
    /*
     * If there was not a direct match but the requested node has children we create
     * a temporary AJ_Object for the parent and introspect that object.
     */
    if ((obj->path == NULL) && children) {
        parent.flags = 0;
        parent.path = msg->objPath;
        parent.interfaces = NULL;
        obj = &parent;
    }
    /*
     * Skip objects that are hidden or disabled
     */
    if (obj->path && !(obj->flags & (AJ_OBJ_FLAG_HIDDEN | AJ_OBJ_FLAG_DISABLED))) {
        /*
         * First pass computes the size of the XML string
         */
        context.len = 0;
        status = GenXML(SizeXML, &context.len, obj, objectLists[1]);
        if (status != AJ_OK) {
            AJ_ErrPrintf(("AJ_HandleIntrospectRequest(): Failed to generate XML. status=%s", AJ_StatusText(status)));
            return status;
        }
        /*
         * Second pass marshals the XML
         */
        AJ_InfoPrintf(("AJ_HandleIntrospectRequest() %d bytes of XML\n", context.len));
        AJ_MarshalReplyMsg(msg, reply);
        /*
         * Do a partial delivery
         */
        status = AJ_DeliverMsgPartial(reply, context.len + 5);
        /*
         * Marshal the string length
         */
        if (status == AJ_OK) {
            status = AJ_MarshalRaw(reply, &context.len, 4);
        }
        if (status == AJ_OK) {
            uint8_t nul = 0;
            context.status = AJ_OK;
            context.reply = reply;
            GenXML(WriteXML, &context, obj, objectLists[1]);
            status = context.status;
            if (status == AJ_OK) {
                /*
                 * Marshal the terminating NUL
                 */
                status = AJ_MarshalRaw(reply, &nul, 1);
            }
        }
    } else {
        /*
         * Return a ServiceUnknown error response
         */
        AJ_WarnPrintf(("AJ_HandleIntrospectRequest() NO MATCH for %s\n", msg->objPath));
        AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown);
    }
    return status;
}
Beispiel #5
0
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;
}