static AJ_Status AppHandleCat(AJ_Message* msg) { #define BUFFER_SIZE 256 const char* string0; const char* string1; char buffer[BUFFER_SIZE]; AJ_Message reply; AJ_Arg replyArg; AJ_UnmarshalArgs(msg, "ss", &string0, &string1); AJ_MarshalReplyMsg(msg, &reply); /* We have the arguments. Now do the concatenation. */ strncpy(buffer, string0, BUFFER_SIZE); buffer[BUFFER_SIZE - 1] = '\0'; strncat(buffer, string1, BUFFER_SIZE - strlen(buffer)); buffer[BUFFER_SIZE - 1] = '\0'; AJ_InitArg(&replyArg, AJ_ARG_STRING, 0, buffer, 0); AJ_MarshalArg(&reply, &replyArg); return AJ_DeliverMsg(&reply); #undef BUFFER_SIZE }
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; }
AJ_Status AJ_MarshalContainer(AJ_Message* msg, AJ_Arg* arg, uint8_t typeId) { AJ_Status status; InitArg(arg, typeId, NULL); status = AJ_MarshalArg(msg, arg); if (status == AJ_OK) { arg->container = msg->outer; msg->outer = arg; } return status; }
AJ_Status AJ_PeerHandleGenSessionKeyReply(AJ_Message* msg) { AJ_Status status; /* * For 12 bytes of verifier, we need at least 12 * 2 characters * to store its representation in hex (24 octets + 1 octet for \0). * However, the KeyGen function demands a bigger buffer * (to store 16 bytes key in addition to the 12 bytes verifier). * Hence we allocate, the maximum of (12 * 2 + 1) and (16 + 12). */ char verifier[VERIFIER_LEN + AES_KEY_LEN]; char* nonce; char* remVerifier; /* * Check we are in an auth conversation with the sender */ status = CheckAuthPeer(msg); if (status != AJ_OK) { return status; } if (msg->hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_SECURITY; } else { AJ_UnmarshalArgs(msg, "ss", &nonce, &remVerifier); status = KeyGen(msg->sender, AJ_ROLE_KEY_INITIATOR, authContext.nonce, nonce, (uint8_t*)verifier, sizeof(verifier)); if (status == AJ_OK) { /* * Check verifier strings match as expected */ if (strcmp(remVerifier, verifier) != 0) { status = AJ_ERR_SECURITY; } } if (status == AJ_OK) { AJ_Arg key; AJ_Message call; uint8_t groupKey[AES_KEY_LEN]; /* * Group keys are exchanged via an encrypted message */ AJ_MarshalMethodCall(msg->bus, &call, AJ_METHOD_EXCHANGE_GROUP_KEYS, msg->sender, 0, AJ_FLAG_ENCRYPTED, CALL_TIMEOUT); AJ_GetGroupKey(NULL, groupKey); AJ_MarshalArg(&call, AJ_InitArg(&key, AJ_ARG_BYTE, AJ_ARRAY_FLAG, groupKey, sizeof(groupKey))); status = AJ_DeliverMsg(&call); } } if (status != AJ_OK) { PeerAuthComplete(status); } return AJ_OK; }
AJ_Status AJ_MarshalVariant(AJ_Message* msg, const char* sig) { AJ_Arg arg; /* * A variant type must be a single complete type */ if (CompleteTypeSigLen(sig) != strlen(sig)) { return AJ_ERR_UNEXPECTED; } InitArg(&arg, AJ_ARG_VARIANT, sig); return AJ_MarshalArg(msg, &arg); }
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); }
AJ_Status AJ_MarshalArgs(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 u8; uint16_t u16; uint32_t u32; uint64_t u64; uint8_t typeId = (uint8_t)*sig++; void* val; if (!IsBasicType(typeId)) { status = AJ_ERR_UNEXPECTED; break; } if (IsScalarType(typeId)) { if (SizeOfType(typeId) == 8) { u64 = va_arg(argp, uint64_t); val = &u64; } else if (SizeOfType(typeId) == 4) { u32 = va_arg(argp, uint32_t); val = &u32; } else if (SizeOfType(typeId) == 2) { u16 = (uint16_t)va_arg(argp, uint32_t); val = &u16; } else { u8 = (uint8_t)va_arg(argp, uint32_t); val = &u8; } } else { val = va_arg(argp, char*); } InitArg(&arg, typeId, val); status = AJ_MarshalArg(msg, &arg); if (status != AJ_OK) { break; } } va_end(argp); return status; }
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; }
AJ_Status AJSVC_PropertyStore_ReadAll(AJ_Message* msg, AJSVC_PropertyStoreCategoryFilter filter, int8_t langIndex) { AJ_Status status = AJ_OK; AJ_Arg array; AJ_Arg array2; AJ_Arg dict; const char* value; AJ_Arg arg; uint8_t rawValue[16]; uint8_t index; const char* ajVersion; AJ_InfoPrintf(("PropertyStore_ReadAll()\n")); status = AJ_MarshalContainer(msg, &array, AJ_ARG_ARRAY); if (status != AJ_OK) { return status; } //AJSVC_PropertyStoreFieldIndices fieldIndex = 0; int fieldIndex = 0; for (; fieldIndex < AJSVC_PROPERTY_STORE_NUMBER_OF_KEYS; fieldIndex++) { #ifdef CONFIG_SERVICE if (propertyStoreProperties[fieldIndex].mode7Public && (filter.bit0About || (filter.bit1Config && propertyStoreProperties[fieldIndex].mode0Write) || (filter.bit2Announce && propertyStoreProperties[fieldIndex].mode1Announce))) { #else if (propertyStoreProperties[fieldIndex].mode7Public && (filter.bit0About || (filter.bit2Announce && propertyStoreProperties[fieldIndex].mode1Announce))) { #endif value = AJSVC_PropertyStore_GetValueForLang((AJSVC_PropertyStoreFieldIndices)fieldIndex, langIndex); if (value == NULL && fieldIndex >= AJSVC_PROPERTY_STORE_NUMBER_OF_MANDATORY_KEYS) { // Non existing values are skipped! AJ_WarnPrintf(("PropertyStore_ReadAll - Failed to get value for field=(name=%s, index=%d) and language=(name=%s, index=%d), skipping.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); } else { if (fieldIndex == AJSVC_PROPERTY_STORE_APP_ID) { if (value == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "ay"); if (status != AJ_OK) { return status; } status = AJ_HexToRaw(value, 0, rawValue, (size_t)sizeof(rawValue)); if (status != AJ_OK) { return status; } status = AJ_MarshalArg(msg, AJ_InitArg(&arg, AJ_ARG_BYTE, AJ_ARRAY_FLAG, rawValue, sizeof(rawValue))); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } #ifdef CONFIG_SERVICE } else if (fieldIndex == AJSVC_PROPERTY_STORE_MAX_LENGTH) { status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "q"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "q", DEVICE_NAME_VALUE_LENGTH); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Has key [%s] runtime Value [%d]\n", propertyStoreProperties[AJSVC_PROPERTY_STORE_MAX_LENGTH].keyName, DEVICE_NAME_VALUE_LENGTH)); #endif } else if (fieldIndex == AJSVC_PROPERTY_STORE_AJ_SOFTWARE_VERSION) { ajVersion = AJ_GetVersion(); if (ajVersion == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "s"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", ajVersion); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Has key [%s] runtime Value [%s]\n", propertyStoreProperties[AJSVC_PROPERTY_STORE_AJ_SOFTWARE_VERSION].keyName, ajVersion)); } else { if (value == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "s"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", value); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } } } } } if (filter.bit0About) { // Add supported languages status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", defaultLanguagesKeyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "as"); if (status != AJ_OK) { return status; } status = AJ_MarshalContainer(msg, &array2, AJ_ARG_ARRAY); if (status != AJ_OK) { return status; } index = AJSVC_PROPERTY_STORE_NO_LANGUAGE_INDEX; for (; index < AJSVC_PROPERTY_STORE_NUMBER_OF_LANGUAGES; index++) { status = AJ_MarshalArgs(msg, "s", propertyStoreDefaultLanguages[index]); if (status != AJ_OK) { return status; } } status = AJ_MarshalCloseContainer(msg, &array2); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } } status = AJ_MarshalCloseContainer(msg, &array); if (status != AJ_OK) { return status; } return status; } #ifdef CONFIG_SERVICE AJ_Status AJSVC_PropertyStore_Update(const char* key, int8_t langIndex, const char* value) { AJSVC_PropertyStoreFieldIndices fieldIndex = AJSVC_PropertyStore_GetFieldIndex(key); if (fieldIndex == AJSVC_PROPERTY_STORE_ERROR_FIELD_INDEX || fieldIndex >= AJSVC_PROPERTY_STORE_NUMBER_OF_CONFIG_KEYS) { return AJ_ERR_INVALID; } if (!UpdateFieldInRAM(fieldIndex, langIndex, value)) { return AJ_ERR_FAILURE; } return AJ_OK; }
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; }