void AllJoyn_Start() { AJ_Status status = AJ_OK; AJ_AlwaysPrintf(("AllJoyn Version %s\n", AJ_GetVersion())); // status = AJ_WiFiScan(NULL, ScanResult, 32); // if (status != AJ_OK) { // AJ_AlwaysPrintf(("WiFi scan failed\n")); // } // status = ConfigureSoftAP(); esp_init(115200); status = ConfigureWifi(); // esp_serial_proxy(); if (status == AJ_OK) { // AJ_Initialize(); AJ_Main(); } AJ_AlwaysPrintf(("Quitting\n")); while (TRUE) { } }
int AJ_Main(void) { AJ_Status status = AJ_ERR_INVALID; AJ_NVRAM_Init(); AJ_Printf("\nAllJoyn Release: %s\n\n", AJ_GetVersion()); /* * The very first thing the test application does is to follow the trail of * breadcrumbs, if available. */ status = FollowTrailOfBreadcrumbs(); if (AJ_OK == status) { AJ_Printf("PASS: Successfully read the known message from NVRAM and " "it is as expected. Done with the test.\n"); return status; } else { AJ_Printf("INFO: No old remnants of a previous test run found.\n"); } /* * The very last thing the test application does is to create the trail of * breadcrumbs, to be compared upon start. */ status = CreateTrailOfBreadcrumbs(); if (AJ_OK == status) { AJ_Printf("INFO: Successfully wrote the known message to NVRAM.\n"); AJ_Reboot(); /* Reboot the target, if available */ } else { AJ_Printf("ERROR: CreateTrailOfBreadcrumbs failed: %s (code: %u)\n", AJ_StatusText(status), status); } AJ_Printf("INFO: Completed running the test. Exiting...\n"); 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; }
void AJ_Main(void) { uint8_t i = 0; AJ_Status status = AJ_ERR_FAILURE; /* the glass is half-empty */ AJ_BusAttachment bus; /* these variables are used when kicking off DHCP */ uint32_t current_ip_address = 0; uint32_t current_subnet_mask = 0; uint32_t current_default_gateway = 0; AJ_Time dhcpTimer; uint32_t timeTakenForDhcp = 0; AJ_Initialize(); AJ_Printf("\nAllJoyn Release: %s\n\n", AJ_GetVersion()); AJ_Printf("INFO: The parameter RUN_NEGATIVE_TESTS is %s\n", (RUN_NEGATIVE_TESTS ? "true" : "false")); AJ_Printf("INFO: The parameter DELAY_BETWEEN_SCANS is %u ms\n", DELAY_BETWEEN_SCANS); AJ_Printf("INFO: The parameter DELAY_BETWEEN_ASSOCIATIONS is %u ms\n", DELAY_BETWEEN_ASSOCIATIONS); AJ_Printf("INFO: The parameter DHCP_TIMEOUT is %u ms\n", DHCP_TIMEOUT); AJ_Printf("INFO: The parameter DISCOVER_TIMEOUT is %u ms\n", DISCOVER_TIMEOUT); /* reset the wifi to start with a clean slate */ status = AJ_ResetWiFi(); if (AJ_OK != status) { AJ_Printf("WARN: AJ_ResetWiFi returned %s (code: %u).\n", AJ_StatusText(status), status); } /* * Repeatedly do the following: * a. scan for access points in the vicinity * b. For each open access point in the returned results: * i. associate using AJ_ConnectWiFi * ii. acquire an ip address using AJ_AcquireIPAddress * iii. perform a short-lived discovery on some random node prefix * using AJ_FindBusAndConnect * iv. disassociate using AJ_DisconnectWiFi * c. For each secured access point in the returned results: * i. Connect to it with intentionally incorrect parameters * (Negative test) */ while (TRUE) { AJ_RandBytes(¤tContext, sizeof(currentContext)); uint8_t currentMaxAps = 0; AJ_RandBytes(¤tMaxAps, sizeof(currentMaxAps)); /* Reset numValidScanEntries, before every scan attempt. */ numValidScanEntries = 0; status = AJ_WiFiScan((void*) (sentinelForWifiScanContext + currentContext), wifiScanResultCallback, currentMaxAps); if (AJ_OK != status) { if (AJ_ERR_FAILURE == status && 0 != currentMaxAps) { scanStats.numFailed++; } else if (AJ_ERR_RESOURCES == status) { scanStats.numFailed++; } AJ_Printf("Failed to scan: %s (code: %u)\n", AJ_StatusText(status), status); /* No point in attempting to do wifi operations, when scan failed */ continue; } else { /* * A success was returned from AJ_WiFiScan. Were any results * returned after all?? */ if (0 < numValidScanEntries) { scanStats.numSuccessful++; } else { AJ_Printf("WARN: AJ_WiFiScan returned %s (code: %u), but returned ZERO scan results...\n", AJ_StatusText(status), status); scanStats.numFailed++; /* When num of scan results is zero, there is nothing to do */ continue; } } /* numValidScanEntries is an index into the array. Hence +1. */ if (currentMaxAps < numValidScanEntries + 1) { AJ_Printf("WARN: Scan returned more results (%u) than requested (%u).\n", numValidScanEntries + 1, currentMaxAps); } else { AJ_Printf("Wifi scan successful (got %u results).\n", numValidScanEntries); } for (i = 0; i < numValidScanEntries; i++) { if (AJ_WIFI_SECURITY_NONE != wifiScanInfo[i].secType) { /* On some targets, it is not possible to check for 802.11 * authentication failure when security type is WEP. * Hence, run negative tests only for WPA/WPA2-based APs. */ if (RUN_NEGATIVE_TESTS && AJ_WIFI_SECURITY_WEP != wifiScanInfo[i].secType) { /* Run a negative test for wifi association */ AJ_Printf("RUN (negative test): Attempting to associate with %s using a randomly generated passphrase...", wifiScanInfo[i].ssid); char random_passphrase[128 + 1]; AJ_RandHex(random_passphrase, sizeof(random_passphrase), (sizeof(random_passphrase) - 1) / 2); /* Set a random passphrase length based on security type */ uint8_t randomPassphraseLen = 0; /* WPA / WPA2 - assuming min len is 8 and max is 64 */ AJ_RandBytes(&randomPassphraseLen, sizeof(randomPassphraseLen)); randomPassphraseLen = 8 + randomPassphraseLen % (64 - 8 + 1); random_passphrase[randomPassphraseLen] = '\0'; status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, random_passphrase); if (AJ_OK == status) { /* negative test failed */ AJ_Printf("FAIL (negative test): Associated with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) Passphrase: %s RSSI: %u ...\n", wifiScanInfo[i].ssid, wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5], secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType], random_passphrase, wifiScanInfo[i].rssi); /* negative test failed - don't go any further */ AJ_ASSERT(0); } else { AJ_Printf("Done (negative test).\n"); } status = AJ_DisconnectWiFi(); AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS); } continue; } else { AJ_Printf("Attempting to associate with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) RSSI: %u ...\n", wifiScanInfo[i].ssid, wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5], secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType], wifiScanInfo[i].rssi); status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, ""); if (AJ_OK != status) { associationStats.numFailed++; AJ_Printf("Failed to associate : %s (code: %u)\n", AJ_StatusText(status), status); /* * No point in proceeding any further when WiFi association * has failed */ continue; } else { associationStats.numSuccessful++; } AJ_Printf("Successfully associated. Attempting to get IP Address via DHCP...\n"); AJ_InitTimer(&dhcpTimer); status = AJ_AcquireIPAddress(¤t_ip_address, ¤t_subnet_mask, ¤t_default_gateway, DHCP_TIMEOUT); timeTakenForDhcp = AJ_GetElapsedTime(&dhcpTimer, FALSE); if (AJ_OK != status) { if (AJ_ERR_TIMEOUT == status) { dhcpStats.numTimedout++; AJ_Printf("Timedout (%u ms) while trying to get IP Address via DHCP\n", timeTakenForDhcp); /* * Discovery timed out. * Check whether the API returned in a timely manner. * See whether the actual duration is off by +/- 500ms. * Delay beyond that is unusual. */ if (500 < abs(DHCP_TIMEOUT - timeTakenForDhcp)) { AJ_Printf("WARN: AJ_AcquireIPAddress API did not return in a timely manner. Timeout parameter: %u Actual time elapsed: %u\n", DHCP_TIMEOUT, timeTakenForDhcp); } } else { dhcpStats.numFailed++; AJ_Printf("Failed to get IP Address via DHCP : %s (code: %u)\n", AJ_StatusText(status), status); } /* * No point in proceeding any further when IP address was * not acquired */ continue; } else { dhcpStats.numSuccessful++; AJ_Printf("Successfully obtained\n"); AJ_Printf("\tIP Addresss : %s\n", TestAddrStr(current_ip_address)); AJ_Printf("\tSubnet Mask : %s\n", TestAddrStr(current_subnet_mask)); AJ_Printf("\tDefault Gateway: %s\n", TestAddrStr(current_default_gateway)); } /* Generate a random name using routingNodePrefix */ char currentRoutingNodeName[32 + 1]; strncpy(currentRoutingNodeName, routingNodePrefix, sizeof(routingNodePrefix)); AJ_RandHex(currentRoutingNodeName + strlen(routingNodePrefix), sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix), (sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix) - 1) / 2); currentRoutingNodeName[32] = '\0'; /* just to be safe */ AJ_Printf("Attempting to discover routing node: %s...", currentRoutingNodeName); status = AJ_FindBusAndConnect(&bus, currentRoutingNodeName, DISCOVER_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { /* this is the expected result */ discoverStats.numTimedout++; AJ_Printf("Done (discovery of routing node).\n"); } else if (AJ_OK != status) { discoverStats.numFailed++; AJ_Printf("Failed to connect to routing node: %s (code: %u)\n", AJ_StatusText(status), status); } else if (AJ_OK == status) { /* * the test attempted to discovery a randomly generated * routing node prefix and it worked - highly unlikely event */ AJ_Printf("FATAL: Was able to discover and connect to routing node with prefix %s. Got unique address %s.", currentRoutingNodeName, AJ_GetUniqueName(&bus)); AJ_ASSERT(0); } status = AJ_DisconnectWiFi(); if (AJ_OK != status) { disassociationStats.numFailed++; AJ_Printf("Failed to disassociate: %s (code: %u)\n", AJ_StatusText(status), status); } else { disassociationStats.numSuccessful++; AJ_Printf("Disassociated from access point. "); } AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS); } } PrintStats(); AJ_Sleep(DELAY_BETWEEN_SCANS); } }
static AJ_Status AboutPropGetter(AJ_Message* reply, const char* language) { AJ_Status status = AJ_OK; AJ_Arg array; AJ_GUID theAJ_GUID; char machineIdValue[UUID_LENGTH * 2 + 1]; machineIdValue[UUID_LENGTH * 2] = '\0'; if ((language != NULL) && (0 != strcmp(language, "en")) && (0 != strcmp(language, ""))) { /* the language supplied was not supported */ status = AJ_ERR_NO_MATCH; } if (status == AJ_OK) { status = AJ_MarshalContainer(reply, &array, AJ_ARG_ARRAY); if (status == AJ_OK) { status = AJ_GetLocalGUID(&theAJ_GUID); if (status == AJ_OK) { AJ_GUID_ToString(&theAJ_GUID, machineIdValue, UUID_LENGTH * 2 + 1); } if (status == AJ_OK) { status = MarshalAppId(reply, &machineIdValue[0]); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "AppName", "s", "svclite"); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "DeviceId", "s", machineIdValue); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "DeviceName", "s", "Tester"); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "Manufacturer", "s", "QCE"); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "ModelNumber", "s", "1.0"); } //SupportedLanguages if (status == AJ_OK) { AJ_Arg dict; AJ_Arg languageListArray; status = AJ_MarshalContainer(reply, &dict, AJ_ARG_DICT_ENTRY); if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "s", "SupportedLanguages"); } if (status == AJ_OK) { status = AJ_MarshalVariant(reply, "as"); } if (status == AJ_OK) { status = AJ_MarshalContainer(reply, &languageListArray, AJ_ARG_ARRAY); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "s", "en"); } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &languageListArray); } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &dict); } } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "Description", "s", "svclite test app"); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "DefaultLanguage", "s", "en"); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "SoftwareVersion", "s", AJ_GetVersion()); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "AJSoftwareVersion", "s", AJ_GetVersion()); } } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &array); } } return status; }
AJ_Status MyAboutPropGetter(AJ_Message* reply, const char* language) { AJ_Status status = (0 == strcmp(language, "")) ? AJ_OK : AJ_ERR_NO_MATCH; int langIndex = -1; while(languages[++langIndex] && status == AJ_ERR_NO_MATCH){ fflush(stdout); if ((0 != strcmp(language, languages[langIndex]))) continue; status = AJ_OK; } if (status != AJ_OK) { return status; } AJ_Arg array; // char guidStr[16 * 2 + 1]; uint8_t appId[16]; // memset(guidStr, '\0', sizeof(guidStr)); char* propDeviceId = (char*)GetProperty("DeviceId"); // if (propDeviceId){ // strcpy(guidStr, propDeviceId); // } else { // AJ_GUID guid; // status = AJ_GetLocalGUID(&guid); // if (status != AJ_OK) { // return status; // } // AJ_GUID_ToString(&guid, guidStr, sizeof(guidStr)); // } char* propAppId = (char*)GetProperty("AppId"); status = AJ_HexToRaw(propAppId, 0, appId, 16); if (status != AJ_OK) { return status; } status = AJ_MarshalContainer(reply, &array, AJ_ARG_ARRAY); if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "AppId", "ay", appId, 16); } if (status == AJ_OK) { // printf("AppName: %s\n", (char*)GetProperty("AppName")); status = AJ_MarshalArgs(reply, "{sv}", "AppName", "s", (char*)GetProperty("AppName")); } if (status == AJ_OK) { // printf("DeviceId: %s\n", propDeviceId); status = AJ_MarshalArgs(reply, "{sv}", "DeviceId", "s", propDeviceId); } if (status == AJ_OK) { // not mandatory char * DeviceName = (char*)GetProperty("DeviceName"); if (DeviceName){ // printf("DeviceName: %s\n", DeviceName); status = AJ_MarshalArgs(reply, "{sv}", "DeviceName", "s", DeviceName); } } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "Manufacturer", "s", (char*)GetProperty("Manufacturer")); } if (status == AJ_OK) { // not mandatory char * DateOfManufacture = (char*)GetProperty("DateOfManufacture"); if (DateOfManufacture){ status = AJ_MarshalArgs(reply, "{sv}", "DateOfManufacture", "s", DateOfManufacture); } } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "ModelNumber", "s", (char*)GetProperty("ModelNumber")); } if (status == AJ_OK) { // not mandatory char * SupportUrl = (char*)GetProperty("SupportUrl"); if (SupportUrl){ status = AJ_MarshalArgs(reply, "{sv}", "SupportUrl", "s", SupportUrl); } } //SupportedLanguages if (status == AJ_OK) { AJ_Arg dict; AJ_Arg languageListArray; status = AJ_MarshalContainer(reply, &dict, AJ_ARG_DICT_ENTRY); if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "s", "SupportedLanguages"); } if (status == AJ_OK) { status = AJ_MarshalVariant(reply, "as"); } if (status == AJ_OK) { status = AJ_MarshalContainer(reply, &languageListArray, AJ_ARG_ARRAY); } int langIndex = -1; while(languages[++langIndex]){ if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "s", languages[langIndex]); } } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &languageListArray); } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &dict); } } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "Description", "s", (char*)GetProperty("Description")); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "DefaultLanguage", "s", languages[0]); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "SoftwareVersion", "s", AJ_GetVersion()); } if (status == AJ_OK) { status = AJ_MarshalArgs(reply, "{sv}", "AJSoftwareVersion", "s", AJ_GetVersion()); } if (status == AJ_OK) { status = AJ_MarshalCloseContainer(reply, &array); } return status; }