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 AJCFG_SetPasscodeHandler(AJ_Message* msg) { AJ_Status status = AJ_OK; char* daemonRealm; AJ_Arg newPasscode; AJ_Message reply; uint8_t forceRoutingNodeDisconnect = FALSE; uint8_t errorReply = FALSE; AJ_InfoPrintf(("Handling SetPasscode request\n")); status = AJ_UnmarshalArgs(msg, "s", &daemonRealm); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Realm=%s\n", daemonRealm)); status = AJ_UnmarshalArg(msg, &newPasscode); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Passcode=%d bytes long\n", newPasscode.len)); if (newPasscode.len > 0) { // Check passcode is not empty if (AppSetPasscode) { status = (AppSetPasscode)(daemonRealm, (const uint8_t*)newPasscode.val.v_string, (uint8_t)newPasscode.len); if (status == AJ_ERR_RESOURCES) { // Check passcode is too long to persist status = AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_MAX_SIZE_EXCEEDED); if (status != AJ_OK) { return status; } errorReply = TRUE; } forceRoutingNodeDisconnect = (status == AJ_ERR_READ); } } else { AJ_ErrPrintf(("Error - newPasscode cannot be empty!\n")); status = AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_INVALID_VALUE); if (status != AJ_OK) { return status; } errorReply = TRUE; } if (!errorReply) { status = AJ_MarshalReplyMsg(msg, &reply); if (status != AJ_OK) { return status; } } status = AJ_DeliverMsg(&reply); if (forceRoutingNodeDisconnect) { return AJ_ERR_READ; } return status; }
AJ_Status AJ_UnmarshalVariant(AJ_Message* msg, const char** sig) { AJ_Arg arg; AJ_Status status = AJ_UnmarshalArg(msg, &arg); if (status == AJ_OK) { if (sig) { *sig = arg.val.v_string; } } return status; }
AJ_Status ReceiveNewName(AJ_Message*msg) { AJ_Arg arg; AJ_Status status = AJ_UnmarshalArg(msg, &arg); if (status == AJ_OK) { AJ_AlwaysPrintf(("--==## signalConsumer: Name Changed signal Received ##==--\n")); AJ_AlwaysPrintf(("\tNew name: '%s'.\n", arg.val.v_string)); } return status; }
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); }
uint8_t AJNS_Consumer_IsSuperAgentLost(AJ_Message* msg) { if (msg->msgId == AJ_SIGNAL_LOST_ADV_NAME) { AJ_Arg arg; AJ_UnmarshalArg(msg, &arg); // <arg name="name" type="s" direction="out"/> AJ_SkipArg(msg); // <arg name="transport" type="q" direction="out"/> AJ_SkipArg(msg); // <arg name="prefix" type="s" direction="out"/> AJ_ResetArgs(msg); // Reset to allow others to re-unmarshal message AJ_InfoPrintf(("LostAdvertisedName(%s)\n", arg.val.v_string)); return (strcmp(arg.val.v_string, currentSuperAgentBusName) == 0); } return FALSE; }
/* * Push a scalar array as a buffer. */ static AJ_Status PushScalarArrayArg(duk_context* ctx, uint8_t typeId, AJ_Message* msg) { AJ_Arg arg; AJ_Status status = AJ_UnmarshalArg(msg, &arg); void* buf = duk_push_fixed_buffer(ctx, arg.len); if (buf) { memcpy(buf, arg.val.v_data, arg.len); } else { status = AJ_ERR_RESOURCES; } return status; }
static AJ_Status PushScalarArg(duk_context* ctx, AJ_Message* msg) { AJ_Arg arg; AJ_Status status = AJ_UnmarshalArg(msg, &arg); if (status == AJ_OK) { switch (arg.typeId) { case AJ_ARG_BYTE: duk_push_uint(ctx, (uint32_t)(*arg.val.v_byte)); break; case AJ_ARG_BOOLEAN: duk_push_boolean(ctx, *arg.val.v_bool); break; case AJ_ARG_UINT32: duk_push_uint(ctx, *arg.val.v_uint32); break; case AJ_ARG_INT32: duk_push_int(ctx, *arg.val.v_int32); break; case AJ_ARG_UINT16: duk_push_uint(ctx, *arg.val.v_uint16); break; case AJ_ARG_INT16: duk_push_int(ctx, *arg.val.v_int16); break; case AJ_ARG_DOUBLE: duk_push_number(ctx, *arg.val.v_double); break; case AJ_ARG_UINT64: /* TODO this will lose precision for numbers ~> 2^52*/ duk_push_number(ctx, (double)*arg.val.v_uint64); break; case AJ_ARG_INT64: /* TODO this will lose precision for numbers ~> 2^52*/ duk_push_number(ctx, (double)*arg.val.v_int64); break; } } return status; }
AJ_Status AJ_UnmarshalArgs(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 typeId = (uint8_t)*sig++; void* val = va_arg(argp, void*); if (!IsBasicType(typeId)) { status = AJ_ERR_UNEXPECTED; break; } status = AJ_UnmarshalArg(msg, &arg); if (status != AJ_OK) { break; } if (arg.typeId != typeId) { status = AJ_ERR_UNMARSHAL; break; } if (IsScalarType(typeId)) { switch (SizeOfType(typeId)) { case 1: *((uint8_t*)val) = *arg.val.v_byte; break; case 2: *((uint16_t*)val) = *arg.val.v_uint16; break; case 4: *((uint32_t*)val) = *arg.val.v_uint32; break; case 8: *((uint64_t*)val) = *arg.val.v_uint64; break; } } else { *((const char**)val) = arg.val.v_string; } } va_end(argp); return status; }
AJ_Status AJ_UnmarshalContainer(AJ_Message* msg, AJ_Arg* arg, uint8_t typeId) { AJ_Status status = AJ_ERR_UNMARSHAL; if ((TYPE_FLAG(typeId) & AJ_CONTAINER)) { status = AJ_UnmarshalArg(msg, arg); if (status == AJ_OK) { if (arg->typeId == typeId) { arg->container = msg->outer; msg->outer = arg; } else { status = AJ_ERR_UNMARSHAL; } } } return status; }
AJ_Status AJ_PeerHandleAuthChallengeReply(AJ_Message* msg) { AJ_Status status; AJ_Arg arg; /* * Check we are in an auth conversation with the sender */ status = CheckAuthPeer(msg); if (status != AJ_OK) { return status; } status = AJ_UnmarshalArg(msg, &arg); if (status == AJ_OK) { status = AuthResponse(msg, (char*)arg.val.v_string); } return status; }
static AJ_Status PushArg(duk_context* ctx, AJ_Message* msg) { AJ_Status status = AJ_ERR_DISALLOWED; AJ_Arg arg; const char* sig = AJ_NextArgSig(msg); uint8_t typeId; if (!sig || !*sig) { return AJ_ERR_NO_MORE; } typeId = *sig; /* * De-variant the argument */ while (typeId == AJ_ARG_VARIANT) { status = AJ_UnmarshalVariant(msg, &sig); if (status != AJ_OK) { return status; } typeId = *sig; } if (typeId == ')') { status = AJ_ERR_NO_MORE; } else if (AJ_IsScalarType(typeId)) { status = PushScalarArg(ctx, msg); } else if (AJ_IsStringType(typeId)) { status = AJ_UnmarshalArg(msg, &arg); if (status == AJ_OK) { duk_push_string(ctx, arg.val.v_string); } } else if (typeId == AJ_ARG_STRUCT) { status = PushContainerArg(ctx, AJ_ARG_STRUCT, msg); } else if (typeId == AJ_ARG_ARRAY) { if (sig[1] == AJ_ARG_DICT_ENTRY) { status = PushDictionaryArg(ctx, msg); } else if (sig[1] == AJ_ARG_BYTE) { status = PushScalarArrayArg(ctx, sig[1], msg); } else { status = PushContainerArg(ctx, AJ_ARG_ARRAY, msg); } } return status; }
AJ_Status AJ_PeerHandleExchangeGroupKeysReply(AJ_Message* msg) { AJ_Status status; AJ_Arg arg; /* * Check we are in an auth conversation with the sender */ status = CheckAuthPeer(msg); if (status != AJ_OK) { return status; } AJ_UnmarshalArg(msg, &arg); /* * We expect the key to be 16 bytes */ if (arg.len != AES_KEY_LEN) { status = AJ_ERR_INVALID; } else { status = AJ_SetGroupKey(msg->sender, arg.val.v_byte); } PeerAuthComplete(status); return AJ_OK; }
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; }
static AJ_Status StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, const char** interfaces, uint32_t* sessionId, char* serviceName, const AJ_SessionOpts* opts) { AJ_Status status = AJ_OK; AJ_Time timer; uint8_t found = FALSE; uint8_t clientStarted = FALSE; uint32_t elapsed = 0; char* rule; size_t ruleLen; const char* base = "interface='org.alljoyn.About',sessionless='t'"; const char* impl = ",implements='"; const char** ifaces; AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., interface=\"%p\", sessionId=0x%p, serviceName=0x%p, opts=0x%p)\n", bus, daemonName, timeout, connected, interfaces, sessionId, serviceName, opts)); AJ_InitTimer(&timer); if ((name == NULL && interfaces == NULL) || (name != NULL && interfaces != NULL)) { return AJ_ERR_INVALID; } while (elapsed < timeout) { if (!connected) { status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); elapsed = AJ_GetElapsedTime(&timer, TRUE); if (status != AJ_OK) { elapsed += AJ_CONNECT_PAUSE; if (elapsed > timeout) { break; } AJ_WarnPrintf(("AJ_StartClient(): Failed to connect to bus, sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AJ_StartClient(): AllJoyn client connected to bus\n")); } if (name != NULL) { /* * Kick things off by finding the service names */ status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n")); } else { /* * Kick things off by finding all services that implement the interface */ ruleLen = strlen(base) + 1; ifaces = interfaces; while (*ifaces != NULL) { ruleLen += strlen(impl) + strlen(*ifaces) + 1; ifaces++; } rule = (char*) AJ_Malloc(ruleLen); if (rule == NULL) { status = AJ_ERR_RESOURCES; break; } strcpy(rule, base); ifaces = interfaces; while (*ifaces != NULL) { strcat(rule, impl); if ((*ifaces)[0] == '$') { strcat(rule, &(*ifaces)[1]); } else { strcat(rule, *ifaces); } strcat(rule, "'"); ifaces++; } status = AJ_BusSetSignalRule(bus, rule, AJ_BUS_SIGNAL_ALLOW); AJ_InfoPrintf(("AJ_StartClient(): Client SetSignalRule: %s\n", rule)); AJ_Free(rule); } if (status == AJ_OK) { break; } if (!connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } } if (elapsed > timeout) { AJ_WarnPrintf(("AJ_StartClient(): Client timed-out trying to connect to bus: status=%s.\n", AJ_StatusText(status))); return AJ_ERR_TIMEOUT; } timeout -= elapsed; if (status != AJ_OK) { return status; } *sessionId = 0; if (serviceName != NULL) { *serviceName = '\0'; } while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if ((status == AJ_ERR_TIMEOUT) && !found) { /* * Timeouts are expected until we find a name or service */ if (timeout < AJ_UNMARSHAL_TIMEOUT) { return status; } timeout -= AJ_UNMARSHAL_TIMEOUT; status = AJ_OK; continue; } if (status == AJ_ERR_NO_MATCH) { // Ignore unknown messages status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); found = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_SIGNAL_ABOUT_ANNOUNCE: { uint16_t version, port; AJ_InfoPrintf(("AJ_StartClient(): AboutAnnounce from (%s)\n", msg.sender)); if (!found) { found = TRUE; AJ_UnmarshalArgs(&msg, "qq", &version, &port); status = AJ_BusJoinSession(bus, msg.sender, port, opts); if (serviceName != NULL) { strncpy(serviceName, msg.sender, AJ_MAX_NAME_SIZE); serviceName[AJ_MAX_NAME_SIZE] = '\0'; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): BusJoinSession failed (%s)\n", AJ_StatusText(status))); } } } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; } else { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION reply (%d)\n", replyCode)); status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n")); status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK && !connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
AJ_Status AJ_Authenticate(AJ_BusAttachment* bus) { AJ_Status status = AJ_OK; AJ_SASL_Context sasl; /* * Send initial NUL byte */ bus->sock.tx.writePtr[0] = 0; bus->sock.tx.writePtr += 1; status = bus->sock.tx.send(&bus->sock.tx); if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Authenticate(): status=%s\n", AJ_StatusText(status))); goto ExitConnect; } AJ_SASL_InitContext(&sasl, mechList, AJ_AUTH_RESPONDER, busAuthPwdFunc, FALSE); while (TRUE) { status = AuthAdvance(&sasl, &bus->sock.rx, &bus->sock.tx); if ((status != AJ_OK) || (sasl.state == AJ_SASL_FAILED)) { break; } if (sasl.state == AJ_SASL_AUTHENTICATED) { status = SendHello(bus); break; } } if (status == AJ_OK) { AJ_Message helloResponse; status = AJ_UnmarshalMsg(bus, &helloResponse, 5000); if (status == AJ_OK) { /* * The only error we might get is a timeout */ if (helloResponse.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_TIMEOUT; } else { AJ_Arg arg; status = AJ_UnmarshalArg(&helloResponse, &arg); if (status == AJ_OK) { if (arg.len >= (sizeof(bus->uniqueName) - 1)) { AJ_ErrPrintf(("AJ_Authenticate(): AJ_ERR_RESOURCES\n")); status = AJ_ERR_RESOURCES; } else { memcpy(bus->uniqueName, arg.val.v_string, arg.len); bus->uniqueName[arg.len] = '\0'; } } } AJ_CloseMsg(&helloResponse); // subscribe to the signal NameOwnerChanged and wait for the response status = AJ_BusSetSignalRule(bus, "type='signal',member='NameOwnerChanged',interface='org.freedesktop.DBus'", AJ_BUS_SIGNAL_ALLOW); if (status == AJ_OK) { uint8_t found_reply = FALSE; AJ_Message msg; AJ_Time timer; AJ_InitTimer(&timer); while (found_reply == FALSE && AJ_GetElapsedTime(&timer, TRUE) < 3000) { status = AJ_UnmarshalMsg(bus, &msg, 3000); if (status == AJ_OK) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): found_reply = TRUE; break; default: // ignore everything else AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } } } } } ExitConnect: if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Authenticate(): status=%s\n", AJ_StatusText(status))); } return status; }
AJ_Status AJ_ARDP_UDP_Connect(AJ_BusAttachment* bus, void* context, const AJ_Service* service, AJ_NetSocket* netSock) { AJ_Message hello; AJ_GUID localGuid; char guid_buf[33]; AJ_Status status; AJ_Message helloResponse; AJ_GetLocalGUID(&localGuid); AJ_GUID_ToString(&localGuid, guid_buf, sizeof(guid_buf)); AJ_MarshalMethodCall(bus, &hello, AJ_METHOD_BUS_SIMPLE_HELLO, AJ_BusDestination, 0, AJ_FLAG_ALLOW_REMOTE_MSG, AJ_UDP_CONNECT_TIMEOUT); AJ_MarshalArgs(&hello, "su", guid_buf, 10); hello.hdr->bodyLen = hello.bodyBytes; status = AJ_ARDP_Connect(bus->sock.tx.readPtr, AJ_IO_BUF_AVAIL(&bus->sock.tx), context, netSock); if (status != AJ_OK) { return status; } status = AJ_UnmarshalMsg(bus, &helloResponse, AJ_UDP_CONNECT_TIMEOUT); if (status == AJ_OK && helloResponse.msgId == AJ_REPLY_ID(AJ_METHOD_BUS_SIMPLE_HELLO)) { if (helloResponse.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_CONNECT; } else { AJ_Arg uniqueName, protoVersion; AJ_UnmarshalArg(&helloResponse, &uniqueName); AJ_SkipArg(&helloResponse); AJ_UnmarshalArg(&helloResponse, &protoVersion); /** * The two most-significant bits are reserved for the nameType, * which we don't currently care about in the thin client */ routingProtoVersion = (uint8_t) ((*protoVersion.val.v_uint32) & 0x3FFFFFFF); if (uniqueName.len >= (sizeof(bus->uniqueName) - 1)) { AJ_ErrPrintf(("AJ_ARDP_Connect(): AJ_ERR_RESOURCES\n")); status = AJ_ERR_RESOURCES; } else { memcpy(bus->uniqueName, uniqueName.val.v_string, uniqueName.len); bus->uniqueName[uniqueName.len] = '\0'; } /AJ_InfoPrintf(("Received name: %s and version %u\n", bus->uniqueName, routingProtoVersion)); if (routingProtoVersion < AJ_GetMinProtoVersion()) { AJ_InfoPrintf(("AJ_ARDP_Connect(): Blacklisting routing node, found %u but require >= %u\n", routingProtoVersion, AJ_GetMinProtoVersion())); AddRoutingNodeToBlacklist(service); status = AJ_ERR_CONNECT; } } }
AJ_Status AJ_Authenticate(AJ_BusAttachment* bus) { AJ_Status status = AJ_OK; AJ_Message helloResponse; if (bus->isAuthenticated) { // ARDP does not do SASL and it sends BusHello as part of the SYN message. // Therefore, Hello has already been sent by the time AJ_Net_Connect() returns, // *before* AJ_Authenticate is called. return AJ_OK; } // Send initial NUL byte bus->sock.tx.writePtr[0] = 0; bus->sock.tx.writePtr += 1; status = bus->sock.tx.send(&bus->sock.tx); if (status != AJ_OK) { AJ_InfoPrintf(("AJ_Authenticate(): status=%s\n", AJ_StatusText(status))); goto ExitConnect; } /* Use SASL Anonymous to connect to routing node */ //что-то посылается, что-то получается, не особо понятно status = AnonymousAuthAdvance(&bus->sock.rx, &bus->sock.tx); if (status == AJ_OK) { status = SendHello(bus); } if (status == AJ_OK) { status = AJ_UnmarshalMsg(bus, &helloResponse, 5000); } if (status == AJ_OK) { if (helloResponse.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_Authenticate(): AJ_ERR_TIMEOUT\n")); status = AJ_ERR_TIMEOUT; } else { AJ_Arg arg; status = AJ_UnmarshalArg(&helloResponse, &arg); if (status == AJ_OK) { if (arg.len >= (sizeof(bus->uniqueName) - 1)) { AJ_ErrPrintf(("AJ_Authenticate(): AJ_ERR_RESOURCES\n")); status = AJ_ERR_RESOURCES; } else { memcpy(bus->uniqueName, arg.val.v_string, arg.len); bus->uniqueName[arg.len] = '\0'; } } } AJ_CloseMsg(&helloResponse); } ExitConnect: if (status == AJ_OK) { bus->isAuthenticated = TRUE; } return status; }
AJ_Status AJ_StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts) { AJ_Status status = AJ_OK; AJ_Time timer; uint8_t foundName = FALSE; uint8_t clientStarted = FALSE; uint32_t elapsed = 0; AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., name=\"%s\", port=%d., sessionId=0x%p, opts=0x%p)\n", bus, daemonName, timeout, connected, name, port, sessionId, opts)); AJ_InitTimer(&timer); while (elapsed < timeout) { if (!connected) { AJ_InfoPrintf(("AJ_StartClient(): AJ_FindBusAndConnect()\n")); status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); elapsed = AJ_GetElapsedTime(&timer, TRUE); if (status != AJ_OK) { elapsed += AJ_CONNECT_PAUSE; if (elapsed > timeout) { break; } AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AllJoyn client connected to bus\n")); } /* * Kick things off by finding the service names */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n")); status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); if (status == AJ_OK) { break; } if (!connected) { AJ_WarnPrintf(("AjStartClient2(): AJ_Disconnect(): status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } } if (elapsed > timeout) { return AJ_ERR_TIMEOUT; } timeout -= elapsed; *sessionId = 0; while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if ((status == AJ_ERR_TIMEOUT) && !foundName) { /* * Timeouts are expected until we find a name */ if (timeout < AJ_UNMARSHAL_TIMEOUT) { return status; } timeout -= AJ_UNMARSHAL_TIMEOUT; status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); foundName = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; } else { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n")); status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_WarnPrintf(("AJ_StartClient(): AJ_Disconnect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
int AJ_Main(void) { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; AJ_Status authStatus = AJ_ERR_NULL; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(ProxyObjects); AJ_RegisterObjects(NULL, ProxyObjects); while (TRUE) { AJ_Message msg; if (!connected) { status = AJ_StartClient(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServiceName, ServicePort, &sessionId, NULL); if (status == AJ_OK) { AJ_Printf("StartClient returned %d, sessionId=%u\n", status, sessionId); AJ_Printf("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus)); connected = TRUE; #ifdef SECURE_INTERFACE AJ_BusSetPasswordCallback(&bus, PasswordCallback); status = AJ_BusAuthenticatePeer(&bus, ServiceName, AuthCallback, &authStatus); if (status != AJ_OK) { AJ_Printf("AJ_BusAuthenticatePeer returned %d\n", status); } #else authStatus = AJ_OK; #endif } else { AJ_Printf("StartClient returned %d\n", status); break; } } if (authStatus != AJ_ERR_NULL) { if (authStatus != AJ_OK) { AJ_Disconnect(&bus); break; } authStatus = AJ_ERR_NULL; AJ_BusSetLinkTimeout(&bus, sessionId, 10 * 1000); } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(&bus, sessionId); continue; } } else { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_SET_LINK_TIMEOUT): { uint32_t disposition; uint32_t timeout; status = AJ_UnmarshalArgs(&msg, "uu", &disposition, &timeout); if (disposition == AJ_SETLINKTIMEOUT_SUCCESS) { AJ_Printf("Link timeout set to %d\n", timeout); } else { AJ_Printf("SetLinkTimeout failed %d\n", disposition); } SendPing(&bus, sessionId, 1); } break; case AJ_REPLY_ID(PRX_MY_PING): { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); status = SendGetProp(&bus, sessionId); } break; case AJ_REPLY_ID(PRX_GET_PROP): { const char* sig; status = AJ_UnmarshalVariant(&msg, &sig); if (status == AJ_OK) { status = AJ_UnmarshalArgs(&msg, sig, &g_iterCount); AJ_Printf("Get prop reply %d\n", g_iterCount); if (status == AJ_OK) { g_iterCount = g_iterCount + 1; status = SendSetProp(&bus, sessionId, g_iterCount); } } } break; case AJ_REPLY_ID(PRX_SET_PROP): AJ_Printf("Set prop reply\n"); break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_Printf("Session lost. ID = %u, reason = %u", id, reason); } status = AJ_ERR_SESSION_LOST; break; default: /* * Pass to the built-in handlers */ status = AJ_BusHandleBusMessage(&msg); break; } } /* * Messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_SESSION_LOST) || (status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) { AJ_Printf("AllJoyn disconnect\n"); AJ_Printf("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus)); AJ_Disconnect(&bus); return status; } } AJ_Printf("clientlite EXIT %d\n", status); return status; }
AJ_Status AJ_StartClient2(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts ) { AJ_Status status = AJ_OK; AJ_Time timer; AJ_Time unmarshalTimer; uint8_t foundName = FALSE; uint8_t clientStarted = FALSE; uint8_t initial = TRUE; AJ_InitTimer(&timer); while (TRUE) { if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } if (!initial || !connected) { initial = FALSE; AJ_InfoPrintf(("Attempting to connect to bus\n")); status = AJ_Connect(bus, daemonName, CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", CONNECT_PAUSE / 1000)); AJ_Sleep(CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AllJoyn client connected to bus\n")); } /* * Kick things off by finding the service names */ status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); if (status == AJ_OK) { break; } AJ_WarnPrintf(("FindAdvertisedName failed\n")); AJ_Disconnect(bus); } *sessionId = 0; while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } status = AJ_UnmarshalMsg(bus, &msg, UNMARSHAL_TIMEOUT); /* * TODO This is a temporary hack to work around buggy select imlpementations */ AJ_InitTimer(&unmarshalTimer); if (status == AJ_ERR_TIMEOUT && (AJ_GetElapsedTime(&unmarshalTimer, TRUE) < UNMARSHAL_TIMEOUT || !foundName)) { /* * Timeouts are expected until we find a name */ status = AJ_OK; continue; } if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); foundName = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; AJ_BusSetSignalRule2(bus, "NameOwnerChanged", "org.freedesktop.DBus", AJ_BUS_SIGNAL_ALLOW); } else { status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST: /* * Force a disconnect */ status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_WarnPrintf(("AllJoyn disconnect bus status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
AJ_Status AJ_Connect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout) { AJ_Status status; AJ_SASL_Context sasl; AJ_Service service; /* * Clear the bus struct */ memset(bus, 0, sizeof(AJ_BusAttachment)); /* * Clear stale name->GUID mappings */ AJ_GUID_ClearNameMap(); /* * Host-specific network bring-up procedure. This includes establishing a connection to the * network and initializing the I/O buffers. */ status = AJ_Net_Up(); if (status != AJ_OK) { return status; } /* * Discover a daemon or service to connect to */ if (!serviceName) { serviceName = daemonService; } #if AJ_CONNECT_LOCALHOST service.ipv4port = 9955; #if HOST_IS_LITTLE_ENDIAN service.ipv4 = 0x0100007F; // 127.0.0.1 #endif #if HOST_IS_BIG_ENDIAN service.ipv4 = 0x7f000001; // 127.0.0.1 #endif service.addrTypes = AJ_ADDR_IPV4; #elif defined ARDUINO service.ipv4port = 9955; service.ipv4 = 0x6501A8C0; // 192.168.1.101 service.addrTypes = AJ_ADDR_IPV4; status = AJ_Discover(serviceName, &service, timeout); if (status != AJ_OK) { goto ExitConnect; } #elif defined AJ_SERIAL_CONNECTION // don't bother with discovery, we are connected to a daemon. #else status = AJ_Discover(serviceName, &service, timeout); if (status != AJ_OK) { goto ExitConnect; } #endif status = AJ_Net_Connect(&bus->sock, service.ipv4port, service.addrTypes & AJ_ADDR_IPV4, &service.ipv4); if (status != AJ_OK) { goto ExitConnect; } /* * Send initial NUL byte */ bus->sock.tx.writePtr[0] = 0; bus->sock.tx.writePtr += 1; status = bus->sock.tx.send(&bus->sock.tx); if (status != AJ_OK) { goto ExitConnect; } AJ_SASL_InitContext(&sasl, mechList, AJ_AUTH_RESPONDER, busAuthPwdFunc); while (TRUE) { status = AuthAdvance(&sasl, &bus->sock.rx, &bus->sock.tx); if ((status != AJ_OK) || (sasl.state == AJ_SASL_FAILED)) { break; } if (sasl.state == AJ_SASL_AUTHENTICATED) { status = SendHello(bus); break; } } if (status == AJ_OK) { AJ_Message helloResponse; status = AJ_UnmarshalMsg(bus, &helloResponse, 5000); if (status == AJ_OK) { /* * The only error we might get is a timeout */ if (helloResponse.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_TIMEOUT; } else { AJ_Arg arg; status = AJ_UnmarshalArg(&helloResponse, &arg); if (status == AJ_OK) { if (arg.len >= (sizeof(bus->uniqueName) - 1)) { status = AJ_ERR_RESOURCES; } else { memcpy(bus->uniqueName, arg.val.v_string, arg.len); bus->uniqueName[arg.len] = '\0'; } } } AJ_CloseMsg(&helloResponse); } } ExitConnect: if (status != AJ_OK) { AJ_Printf("AllJoyn connect failed %d\n", status); AJ_Disconnect(bus); } return status; }
AJ_Status AJ_PeerHandleAuthChallenge(AJ_Message* msg, AJ_Message* reply) { AJ_Status status; AJ_Arg arg; char* buf = NULL; const AJ_GUID* peerGuid = AJ_GUID_Find(msg->sender); /* * We expect to know the GUID of the sender */ if (!peerGuid) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } /* * Check for an authentication conversation in progress with a different peer */ if (authContext.peerGuid && (authContext.peerGuid != peerGuid)) { /* * Reject the request if the existing conversation has not expired */ if (AJ_GetElapsedTime(&authContext.timer, TRUE) < MAX_AUTH_TIME) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } memset(&authContext, 0, sizeof(AuthContext)); } if (authContext.sasl.state == AJ_SASL_IDLE) { /* * Remember which peer is being authenticated and initialize the timeout timer */ authContext.peerGuid = peerGuid; AJ_InitTimer(&authContext.timer); /* * Initialize SASL state machine */ AJ_SASL_InitContext(&authContext.sasl, authMechanisms, AJ_AUTH_CHALLENGER, msg->bus->pwdCallback); } if (AJ_UnmarshalArg(msg, &arg) != AJ_OK) { goto FailAuth; } /* * Need a short-lived buffer to compose the response */ buf = (char*)AJ_Malloc(AUTH_BUF_LEN); if (!buf) { status = AJ_ERR_RESOURCES; goto FailAuth; } status = AJ_SASL_Advance(&authContext.sasl, (char*)arg.val.v_string, buf, AUTH_BUF_LEN); if (status != AJ_OK) { goto FailAuth; } AJ_MarshalReplyMsg(msg, reply); AJ_MarshalArgs(reply, "s", buf); AJ_Free(buf); if (authContext.sasl.state == AJ_SASL_AUTHENTICATED) { status = authContext.sasl.mechanism->Final(peerGuid); memset(&authContext, 0, sizeof(AuthContext)); } return status; FailAuth: AJ_Free(buf); /* * Clear current authentication context then return an error response */ if (authContext.sasl.mechanism) { authContext.sasl.mechanism->Final(peerGuid); } memset(&authContext, 0, sizeof(AuthContext)); return AJ_MarshalErrorMsg(msg, reply, AJ_ErrSecurityViolation); }
int AJ_Main() #endif { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; AJ_Status authStatus = AJ_ERR_NULL; #ifdef SECURE_INTERFACE uint32_t suites[AJ_AUTH_SUITES_NUM]; size_t numsuites = 0; uint8_t clearkeys = FALSE; #endif #ifdef MAIN_ALLOWS_ARGS #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) ac--; av++; /* * Enable authentication mechanism by command line */ if (ac) { if (0 == strncmp(*av, "-ek", 3)) { clearkeys = TRUE; ac--; av++; } else if (0 == strncmp(*av, "-e", 2)) { ac--; av++; } if (!ac) { AJ_AlwaysPrintf(("-e(k) requires an auth mechanism.\n")); return 1; } while (ac) { if (0 == strncmp(*av, "ECDHE_ECDSA", 11)) { suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA; } else if (0 == strncmp(*av, "ECDHE_PSK", 9)) { suites[numsuites++] = AUTH_SUITE_ECDHE_PSK; } else if (0 == strncmp(*av, "ECDHE_NULL", 10)) { suites[numsuites++] = AUTH_SUITE_ECDHE_NULL; } ac--; av++; } } #endif #else suites[numsuites++] = AUTH_SUITE_ECDHE_ECDSA; clearkeys = TRUE; #endif #ifdef SECURE_INTERFACE if (numsuites == 0) { /* Default security to ECDHE_NULL, if not explicit elsewhere */ suites[numsuites++] = AUTH_SUITE_ECDHE_NULL; } #endif /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(ProxyObjects); AJ_RegisterObjects(NULL, ProxyObjects); while (TRUE) { AJ_Message msg; if (!connected) { #if defined (ANNOUNCE_BASED_DISCOVERY) status = AJ_StartClientByPeerDescription(&bus, NULL, CONNECT_TIMEOUT, FALSE, &pingServicePeer, testServicePort, &sessionId, g_peerServiceName, NULL); #elif defined (NGNS) status = AJ_StartClientByInterface(&bus, NULL, CONNECT_TIMEOUT, FALSE, testInterfaceNames, &sessionId, g_peerServiceName, NULL); #else status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, testServiceName, testServicePort, &sessionId, NULL, g_peerServiceName); #endif if (status == AJ_OK) { AJ_AlwaysPrintf(("StartClient returned %d, sessionId=%u, serviceName=%s\n", status, sessionId, g_peerServiceName)); AJ_AlwaysPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus))); connected = TRUE; #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); if (clearkeys) { AJ_ClearCredentials(AJ_GENERIC_MASTER_SECRET | AJ_CRED_TYPE_GENERIC); AJ_ClearCredentials(AJ_GENERIC_ECDSA_MANIFEST | AJ_CRED_TYPE_GENERIC); AJ_ClearCredentials(AJ_GENERIC_ECDSA_KEYS | AJ_CRED_TYPE_GENERIC); } status = AJ_BusAuthenticatePeer(&bus, g_peerServiceName, AuthCallback, &authStatus); if (status != AJ_OK) { AJ_AlwaysPrintf(("AJ_BusAuthenticatePeer returned %d\n", status)); } #else authStatus = AJ_OK; #endif } else { AJ_AlwaysPrintf(("StartClient returned %d\n", status)); break; } } AJ_AlwaysPrintf(("Auth status %d and AllJoyn status %d\n", authStatus, status)); if (status == AJ_ERR_RESOURCES) { AJ_InfoPrintf(("Peer is busy, disconnecting and retrying auth...\n")); AJ_Disconnect(&bus); connected = FALSE; continue; } if (authStatus != AJ_ERR_NULL) { if (authStatus != AJ_OK) { AJ_Disconnect(&bus); break; } authStatus = AJ_ERR_NULL; AJ_BusSetLinkTimeout(&bus, sessionId, 10 * 1000); } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(&bus, sessionId, g_peerServiceName); continue; } } else { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_SET_LINK_TIMEOUT): { uint32_t disposition; uint32_t timeout; status = AJ_UnmarshalArgs(&msg, "uu", &disposition, &timeout); if (disposition == AJ_SETLINKTIMEOUT_SUCCESS) { AJ_AlwaysPrintf(("Link timeout set to %d\n", timeout)); } else { AJ_AlwaysPrintf(("SetLinkTimeout failed %d\n", disposition)); } SendPing(&bus, sessionId, g_peerServiceName, 1); } break; case AJ_REPLY_ID(AJ_METHOD_BUS_PING): { uint32_t disposition; status = AJ_UnmarshalArgs(&msg, "u", &disposition); if (disposition == AJ_PING_SUCCESS) { AJ_AlwaysPrintf(("Bus Ping reply received\n")); } else { AJ_AlwaysPrintf(("Bus Ping failed, disconnecting: %d\n", disposition)); status = AJ_ERR_LINK_DEAD; } } break; case AJ_REPLY_ID(PRX_MY_PING): { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_AlwaysPrintf(("Got ping reply\n")); AJ_InfoPrintf(("INFO Got ping reply\n")); status = SendGetProp(&bus, sessionId, g_peerServiceName); } break; case AJ_REPLY_ID(PRX_GET_PROP): { const char* sig; status = AJ_UnmarshalVariant(&msg, &sig); if (status == AJ_OK) { status = AJ_UnmarshalArgs(&msg, sig, &g_iterCount); AJ_AlwaysPrintf(("Get prop reply %d\n", g_iterCount)); if (status == AJ_OK) { g_iterCount = g_iterCount + 1; status = SendSetProp(&bus, sessionId, g_peerServiceName, g_iterCount); } } } break; case AJ_REPLY_ID(PRX_SET_PROP): AJ_AlwaysPrintf(("Set prop reply\n")); break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u\n", id, reason)); } status = AJ_ERR_SESSION_LOST; break; default: /* * Pass to the built-in handlers */ status = AJ_BusHandleBusMessage(&msg); break; } } /* * Messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_SESSION_LOST) || (status == AJ_ERR_READ) || (status == AJ_ERR_WRITE) || (status == AJ_ERR_LINK_DEAD)) { AJ_AlwaysPrintf(("AllJoyn disconnect\n")); AJ_AlwaysPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_Disconnect(&bus); break; } } AJ_AlwaysPrintf(("clientlite EXIT %d\n", status)); return status; }
int AJ_Main(void) { int done = FALSE; AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; AJ_Status authStatus = AJ_ERR_NULL; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(ProxyObjects); AJ_RegisterObjects(NULL, ProxyObjects); while (!done) { AJ_Message msg; if (!connected) { status = AJ_StartClientByName(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServiceName, ServicePort, &sessionId, NULL, fullServiceName); if (status == AJ_OK) { AJ_InfoPrintf(("StartClient returned %d, sessionId=%u\n", status, sessionId)); connected = TRUE; if (authenticate) { AJ_BusSetPasswordCallback(&bus, PasswordCallback); authStatus = AJ_BusAuthenticatePeer(&bus, fullServiceName, AuthCallback, &authStatus); } else { authStatus = AJ_OK; } } else { AJ_InfoPrintf(("StartClient returned %d\n", status)); break; } } if (authStatus != AJ_ERR_NULL) { if (authStatus != AJ_OK) { AJ_Disconnect(&bus); break; } authStatus = AJ_ERR_NULL; SendPing(&bus, sessionId); } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { AppDoWork(); continue; } if (AJ_OK == status) { switch (msg.msgId) { case AJ_REPLY_ID(PRX_PING): { AJ_Arg arg; if (AJ_OK == AJ_UnmarshalArg(&msg, &arg)) { AJ_AlwaysPrintf(("%s.Ping (path=%s) returned \"%s\".\n", InterfaceName, ServicePath, arg.val.v_string)); if (strcmp(arg.val.v_string, pingString) == 0) { AJ_InfoPrintf(("Ping was successful.\n")); } else { AJ_InfoPrintf(("Ping returned different string.\n")); } } else { AJ_ErrPrintf(("Bad ping response.\n")); } done = TRUE; } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_AlwaysPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } status = AJ_ERR_SESSION_LOST; break; default: /* * Pass to the built-in handlers */ status = AJ_BusHandleBusMessage(&msg); break; } } /* * Messages must be closed to free resources */ AJ_CloseMsg(&msg); if (status == AJ_ERR_READ) { AJ_AlwaysPrintf(("AllJoyn disconnect.\n")); AJ_Disconnect(&bus); exit(0); } } AJ_AlwaysPrintf(("SecureClient EXIT %d.\n", status)); return status; }
int AJ_Main(void) { AJ_Status status = AJ_OK; uint8_t connected = FALSE; uint8_t done = FALSE; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_RegisterObjects(NULL, proxyObjects); while (!done) { AJ_Message msg; if (!connected) { const char* announceRule = "type='signal',sessionless='t',interface='org.alljoyn.About',member='Announce'"; status = AJ_FindBusAndConnect(&bus, NULL, AJ_CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("AJ_FindBusAndConnect(): failed - sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_AboutRegisterAnnounceHandlers(peerDescriptions, ArraySize(peerDescriptions)); AJ_BusSetSignalRule(&bus, announceRule, AJ_BUS_SIGNAL_ALLOW); connected = TRUE; } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { continue; } if (AJ_OK == status) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): if (msg.hdr->msgType != AJ_MSG_ERROR) { uint32_t result; status = AJ_UnmarshalArgs(&msg, "uu", &result, &sessionId); if (status == AJ_OK) { if (result == AJ_JOINSESSION_REPLY_SUCCESS) { AJ_AlwaysPrintf(("joined session %u\n", sessionId)); DoCat(); } else { AJ_AlwaysPrintf(("joined session rejected %d\n", result)); } } } else { AJ_ErrPrintf(("JoinSession reply was error: %s\n", msg.error)); } break; case AJ_REPLY_ID(BASIC_CLIENT_CAT): if (msg.hdr->msgType != AJ_MSG_ERROR) { AJ_Arg arg; status = AJ_UnmarshalArg(&msg, &arg); if (AJ_OK == status) { AJ_AlwaysPrintf(("cat returned \"%s\"\n", arg.val.v_string)); if (!waitVar) { done = TRUE; } } } else { AJ_ErrPrintf(("Reply was error: %s\n", msg.error)); } break; case AJ_SIGNAL_MP_SESSION_CHANGED_WITH_REASON: { uint32_t sessId; const char* peer; uint32_t added; uint32_t reason; status = AJ_UnmarshalArgs(&msg, "usbu", &sessId, &peer, &added, &reason); if (added) { AJ_AlwaysPrintf(("Member \"%s\" added to session %u\n", peer, sessId)); } else { AJ_AlwaysPrintf(("Member \"%s\" removed from session %u\n", peer, sessId)); } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_AlwaysPrintf(("Session lost\n")); break; default: /* Pass to the built-in handlers. */ status = AJ_BusHandleBusMessage(&msg); break; } } /* Messages MUST be discarded to free resources. */ AJ_CloseMsg(&msg); if (status == AJ_ERR_READ) { AJ_AlwaysPrintf(("Connection lost\n")); AJ_Disconnect(&bus); exit(0); } } AJ_AlwaysPrintf(("Basic client exiting with status %d.\n", status)); return status; }
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; }