AJ_Status ExecuteAction(AJ_Message* msg, uint32_t msgId, ExecuteActionContext* context) { AJ_Message reply; AJ_MarshalReplyMsg(msg, &reply); switch (msgId) { case EN_MYDEVICE_OVENACTION_EXEC: case DE_AT_MYDEVICE_OVENACTION_EXEC: { AJ_InfoPrintf(("Starting the Oven. Execute was called\n")); } break; case EN_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION1: case DE_AT_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION1: { AJ_InfoPrintf(("Execute Action1 was called\n")); } break; case EN_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION2: case DE_AT_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION2: { AJ_InfoPrintf(("Execute Action2 was called\n")); } break; case EN_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION3: case DE_AT_MYDEVICE_LIGHTCONFIRM_EXEC_ACTION3: { AJ_InfoPrintf(("Execute Action3 was called\n")); } break; case EN_MYDEVICE_AREYOUSURE_EXEC_ACTION1: case DE_AT_MYDEVICE_AREYOUSURE_EXEC_ACTION1: { AJ_InfoPrintf(("Execute Action1 was called\n")); addDismissSignal(context, MYDEVICE_NOTIFICATION_ACTION_AREYOUSURE_SIGNAL_DISMISS); } break; case EN_MYDEVICE_AREYOUSURE_EXEC_ACTION2: case DE_AT_MYDEVICE_AREYOUSURE_EXEC_ACTION2: { AJ_MarshalErrorMsg(msg, &reply, AJ_ErrServiceUnknown); } break; case EN_MYDEVICE_AREYOUSURE_EXEC_ACTION3: case DE_AT_MYDEVICE_AREYOUSURE_EXEC_ACTION3: { AJ_MarshalErrorMsg(msg, &reply, AJ_ErrServiceUnknown); } break; } return AJ_DeliverMsg(&reply); }
static uint8_t IsValueValid(AJ_Message* msg, AJ_Message* reply, const char* key, const char* value) { if (strcmp(AJSVC_PropertyStore_GetFieldName(AJSVC_PROPERTY_STORE_DEFAULT_LANGUAGE), key) == 0) { // Check that if language was updated that it is supported if (strlen(value) > 0) { // that it is not empty return AJSVC_IsLanguageSupported(msg, reply, value, NULL); } else { AJ_MarshalErrorMsg(msg, reply, AJSVC_ERROR_LANGUAGE_NOT_SUPPORTED); } } else if (strcmp(AJSVC_PropertyStore_GetFieldName(AJSVC_PROPERTY_STORE_DEVICE_NAME), key) == 0) { // Check that if device name was updated if (strlen(value) <= AJSVC_PropertyStore_GetMaxValueLength(AJSVC_PROPERTY_STORE_DEVICE_NAME)) { // that it does not exceed maximum length if (strlen(value) > 0) { // that it is not empty return TRUE; } else { AJ_MarshalErrorMsg(msg, reply, AJSVC_ERROR_INVALID_VALUE); } } else { AJ_MarshalErrorMsg(msg, reply, AJSVC_ERROR_MAX_SIZE_EXCEEDED); } } else if (AJSVC_PropertyStore_GetFieldIndex(key) == AJSVC_PROPERTY_STORE_ERROR_FIELD_INDEX) { // Check that the key exists AJ_MarshalErrorMsg(msg, reply, AJSVC_ERROR_INVALID_VALUE); } else { if (AppIsValueValid == NULL || (AppIsValueValid)(key, value)) { return TRUE; } AJ_MarshalErrorMsg(msg, reply, AJSVC_ERROR_INVALID_VALUE); } return FALSE; }
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 AJSUSI_VgaGetBacklightBrightness_Handler(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_Message reply; AJ_Arg replyArg; uint32_t id, bright; //Get Args status = AJ_UnmarshalArgs(msg, "u", &id); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("%s : id=%d\n", __func__, id)); //SUSI API if (AJ_SusiVgaGetBacklightBrightness(id, &bright)) { AJ_MarshalErrorMsg(msg, &reply, AJ_ErrFeatureNotAvailable); return AJ_DeliverMsg(&reply); } //Status Reply AJ_InfoPrintf(("%s : ret=0x%x\n", __func__, bright)); AJ_InitArg(&replyArg, AJ_ARG_UINT32, 0, &bright, 0); return SendReplyMsg(msg, &replyArg); }
AJ_Status AJ_PeerHandleGenSessionKey(AJ_Message* msg, AJ_Message* reply) { AJ_Status status; char* remGuid; char* locGuid; char* nonce; AJ_GUID guid; AJ_GUID localGuid; /* * 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[AES_KEY_LEN + VERIFIER_LEN]; /* * Remote peer GUID, Local peer GUID and Remote peer's nonce */ AJ_UnmarshalArgs(msg, "sss", &remGuid, &locGuid, &nonce); /* * We expect arg[1] to be the local GUID */ status = AJ_GUID_FromString(&guid, locGuid); if (AJ_OK == status) { status = AJ_GetLocalGUID(&localGuid); } if ((status != AJ_OK) || (memcmp(&guid, &localGuid, sizeof(AJ_GUID)) != 0)) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } AJ_RandHex(authContext.nonce, sizeof(authContext.nonce), NONCE_LEN); status = KeyGen(msg->sender, AJ_ROLE_KEY_RESPONDER, nonce, authContext.nonce, (uint8_t*)verifier, sizeof(verifier)); if (status == AJ_OK) { AJ_MarshalReplyMsg(msg, reply); status = AJ_MarshalArgs(reply, "ss", authContext.nonce, verifier); } else { status = AJ_MarshalErrorMsg(msg, reply, AJ_ErrRejected); } return status; }
AJ_Status AJ_MarshalStatusMsg(const AJ_Message* methodCall, AJ_Message* reply, AJ_Status status) { switch (status) { case AJ_ERR_NO_MATCH: status = AJ_MarshalErrorMsg(methodCall, reply, AJ_ErrServiceUnknown); break; case AJ_ERR_SECURITY: status = AJ_MarshalErrorMsg(methodCall, reply, AJ_ErrSecurityViolation); /* * We get a security violation error so if we encrypt the error message the receiver * won't be able to decrypt it. We can fix this by clearing the header flags. */ if (status == AJ_OK) { reply->hdr->flags = 0; } break; default: status = AJ_MarshalErrorMsg(methodCall, reply, AJ_ErrRejected); break; } return status; }
AJ_Status AJSUSI_VgaSetBacklightEnable_Handler(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_Message reply; uint32_t id, enable; //Get Args status = AJ_UnmarshalArgs(msg, "uu", &id, &enable); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("%s : id=%d, enable=%d\n", __func__, id, enable)); //SUSI API if (AJ_SusiVgaSetBacklightEnable(id, enable)) { AJ_MarshalErrorMsg(msg, &reply, AJ_ErrFeatureNotAvailable); return AJ_DeliverMsg(&reply); } //Status Reply return SendReplyMsg(msg, NULL); }
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 AJ_HandleIntrospectRequest(const AJ_Message* msg, AJ_Message* reply) { AJ_Status status = AJ_OK; const AJ_Object* obj = objectLists[AJ_APP_ID_FLAG]; uint32_t children = 0; AJ_Object parent; WriteContext context; /* * Return an error if there are no local objects */ if (!obj) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown); } /* * Find out which object we are introspecting. There are two possibilities: * * - The request has a complete object path to one of the application objects. * - The request has a path to a parent object of one or more application objects where the * parent itself is just a place-holder in the object hierarchy. */ for (; obj->path != NULL; ++obj) { if (strcmp(msg->objPath, obj->path) == 0) { break; } if (ChildPath(msg->objPath, obj->path, NULL)) { ++children; } } /* * If there was not a direct match but the requested node has children we create * a temporary AJ_Object for the parent and introspect that object. */ if ((obj->path == NULL) && children) { parent.flags = 0; parent.path = msg->objPath; parent.interfaces = NULL; obj = &parent; } /* * Skip objects that are hidden or disabled */ if (obj->path && !(obj->flags & (AJ_OBJ_FLAG_HIDDEN | AJ_OBJ_FLAG_DISABLED))) { /* * First pass computes the size of the XML string */ context.len = 0; status = GenXML(SizeXML, &context.len, obj, objectLists[1]); if (status != AJ_OK) { AJ_ErrPrintf(("AJ_HandleIntrospectRequest(): Failed to generate XML. status=%s", AJ_StatusText(status))); return status; } /* * Second pass marshals the XML */ AJ_InfoPrintf(("AJ_HandleIntrospectRequest() %d bytes of XML\n", context.len)); AJ_MarshalReplyMsg(msg, reply); /* * Do a partial delivery */ status = AJ_DeliverMsgPartial(reply, context.len + 5); /* * Marshal the string length */ if (status == AJ_OK) { status = AJ_MarshalRaw(reply, &context.len, 4); } if (status == AJ_OK) { uint8_t nul = 0; context.status = AJ_OK; context.reply = reply; GenXML(WriteXML, &context, obj, objectLists[1]); status = context.status; if (status == AJ_OK) { /* * Marshal the terminating NUL */ status = AJ_MarshalRaw(reply, &nul, 1); } } } else { /* * Return a ServiceUnknown error response */ AJ_WarnPrintf(("AJ_HandleIntrospectRequest() NO MATCH for %s\n", msg->objPath)); AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown); } return status; }
AJ_Status AJCFG_ResetConfigurationsHandler(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_Arg array; AJ_Message reply; char* key; char* language; int8_t langIndex = AJSVC_PROPERTY_STORE_ERROR_LANGUAGE_INDEX; uint8_t numOfDeletedItems = 0; uint8_t errorReply = FALSE; AJ_InfoPrintf(("Handling ResetConfigurations request\n")); status = AJ_UnmarshalArgs(msg, "s", &language); if (status != AJ_OK) { goto Exit; } AJ_InfoPrintf(("Lang=%s\n", language)); errorReply = !AJSVC_IsLanguageSupported(msg, &reply, language, &langIndex); if (!errorReply) { status = AJ_UnmarshalContainer(msg, &array, AJ_ARG_ARRAY); if (status != AJ_OK) { goto Exit; } while (1) { status = AJ_UnmarshalArgs(msg, "s", &key); if (status != AJ_OK) { break; } AJ_InfoPrintf(("Key=%s\n", key)); status = AJSVC_PropertyStore_Reset(key, langIndex); if (status == AJ_OK) { numOfDeletedItems++; } else if (status == AJ_ERR_INVALID) { if (!errorReply) { AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_INVALID_VALUE); errorReply = TRUE; } } else if (status == AJ_ERR_FAILURE) { if (!errorReply) { AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_UPDATE_NOT_ALLOWED); errorReply = TRUE; } } } if (status != AJ_OK && status != AJ_ERR_NO_MORE) { goto Exit; } status = AJ_UnmarshalCloseContainer(msg, &array); if (status != AJ_OK) { goto Exit; } } if (!errorReply) { status = AJ_MarshalReplyMsg(msg, &reply); if (status != AJ_OK) { goto Exit; } } status = AJ_DeliverMsg(&reply); if (status != AJ_OK) { goto Exit; } Exit: if (numOfDeletedItems) { if (errorReply) { AJSVC_PropertyStore_LoadAll(); // Discard partial successful deletions } else { AJSVC_PropertyStore_SaveAll(); AJ_AboutSetShouldAnnounce(); } } 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); }
AJ_Status AJ_BusHandleBusMessage(AJ_Message* msg) { AJ_Status status = AJ_OK; char* name; char* oldOwner; char* newOwner; AJ_Message reply; AJ_InfoPrintf(("AJ_BusHandleBusMessage(msg=0x%p)\n", msg)); /* * Check we actually have a message to handle */ if (!msg->hdr) { return AJ_OK; } switch (msg->msgId) { case AJ_METHOD_PING: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_PING\n")); status = AJ_MarshalReplyMsg(msg, &reply); break; case AJ_METHOD_GET_MACHINE_ID: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_GET_MACHINE_ID\n")); status = HandleGetMachineId(msg, &reply); break; case AJ_METHOD_INTROSPECT: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_INTROSPECT\n")); status = AJ_HandleIntrospectRequest(msg, &reply); break; case AJ_METHOD_EXCHANGE_GUIDS: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_EXCHANGE_GUIDS\n")); status = AJ_PeerHandleExchangeGUIDs(msg, &reply); break; case AJ_METHOD_GEN_SESSION_KEY: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_GEN_SESSION_KEY\n")); status = AJ_PeerHandleGenSessionKey(msg, &reply); break; case AJ_METHOD_EXCHANGE_GROUP_KEYS: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_EXCHANGE_GROUP_KEYS\n")); status = AJ_PeerHandleExchangeGroupKeys(msg, &reply); break; case AJ_METHOD_AUTH_CHALLENGE: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_AUTH_CHALLENGE\n")); status = AJ_PeerHandleAuthChallenge(msg, &reply); break; case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GUIDS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GUIDS)\n")); status = AJ_PeerHandleExchangeGUIDsReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_AUTH_CHALLENGE): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_AUTH_CHALLENGE)\n")); status = AJ_PeerHandleAuthChallengeReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_GEN_SESSION_KEY): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_GEN_SESSION_KEY)\n")); status = AJ_PeerHandleGenSessionKeyReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GROUP_KEYS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GROUP_KEYS)\n")); status = AJ_PeerHandleExchangeGroupKeysReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_SESSIONLESS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_CANCEL_SESSIONLESS)\n")); // handle return code here status = AJ_OK; break; case AJ_SIGNAL_SESSION_JOINED: case AJ_SIGNAL_NAME_ACQUIRED: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_SIGNAL_{SESSION_JOINED|NAME_ACQUIRED}\n")); // nothing to do here status = AJ_OK; break; case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): case AJ_REPLY_ID(AJ_METHOD_REMOVE_MATCH): case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE): case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_{ADD_MATCH|CANCEL_ADVERTISE|ADVERTISE_NAME})\n")); if (msg->hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } break; case AJ_SIGNAL_NAME_OWNER_CHANGED: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_SIGNAL_NAME_OWNER_CHANGED)\n")); AJ_UnmarshalArgs(msg, "sss", &name, &oldOwner, &newOwner); if (newOwner && oldOwner && newOwner[0] == '\0') { AJ_GUID_DeleteNameMapping(oldOwner); } /* * Reset so the application can handle this too */ status = AJ_ResetArgs(msg); break; default: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): default\n")); if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { status = AJ_MarshalErrorMsg(msg, &reply, AJ_ErrRejected); } break; } if ((status == AJ_OK) && (msg->hdr->msgType == AJ_MSG_METHOD_CALL)) { status = AJ_DeliverMsg(&reply); } return status; }
AJ_Status AJOBS_ConfigureWiFiHandler(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_Message reply; AJOBS_Info newInfo; char* ssid; char* pc; size_t ssidLen; size_t pcLen; int16_t retVal; // Set provided network configuration AJ_InfoPrintf(("Handling ConfigureWiFi request\n")); status = AJ_UnmarshalArgs(msg, "ssn", &ssid, &pc, &newInfo.authType); if (status != AJ_OK) { return status; } if ((int8_t)newInfo.authType >= AJOBS_AUTH_TYPE_MAX_OF_WIFI_AUTH_TYPE || (int8_t)newInfo.authType <= AJOBS_AUTH_TYPE_MIN_OF_WIFI_AUTH_TYPE) { AJ_ErrPrintf(("Unknown authentication type %d\n", newInfo.authType)); status = AJ_MarshalErrorMsg(msg, &reply, AJSVC_ERROR_INVALID_VALUE); if (status != AJ_OK) { return status; } status = AJ_DeliverMsg(&reply); if (status != AJ_OK) { return status; } return status; } ssidLen = min(strlen(ssid), AJOBS_SSID_MAX_LENGTH); strncpy(newInfo.ssid, ssid, AJOBS_SSID_MAX_LENGTH); newInfo.ssid[ssidLen] = '\0'; pcLen = min(strlen(pc), AJOBS_PASSCODE_MAX_LENGTH); strncpy(newInfo.pc, pc, AJOBS_PASSCODE_MAX_LENGTH); newInfo.pc[pcLen] = '\0'; AJ_InfoPrintf(("Got new info for %s with passcode=%s and auth=%d\n", newInfo.ssid, newInfo.pc, newInfo.authType)); retVal = 1; status = AJ_MarshalReplyMsg(msg, &reply); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(&reply, "n", retVal); if (status != AJ_OK) { return status; } status = AJ_DeliverMsg(&reply); if (status != AJ_OK) { return status; } newInfo.state = AJOBS_STATE_CONFIGURED_NOT_VALIDATED; status = AJOBS_SetInfo(&newInfo); if (status == AJ_OK) { // Change state to CONFIGURED AJOBS_SetState(newInfo.state); } return status; }
AJ_Status AJ_BusHandleBusMessage(AJ_Message* msg) { AJ_Status status = AJ_OK; AJ_BusAttachment* bus = msg->bus; char* languageTag; AJ_Message reply; AJ_InfoPrintf(("AJ_BusHandleBusMessage(msg=0x%p)\n", msg)); memset(&reply, 0, sizeof(AJ_Message)); /* * Check we actually have a message to handle */ if (!msg->hdr) { return AJ_OK; } switch (msg->msgId) { case AJ_METHOD_PING: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_PING\n")); status = AJ_MarshalReplyMsg(msg, &reply); break; case AJ_METHOD_GET_MACHINE_ID: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_GET_MACHINE_ID\n")); status = HandleGetMachineId(msg, &reply); break; case AJ_METHOD_INTROSPECT: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_INTROSPECT\n")); status = AJ_HandleIntrospectRequest(msg, &reply, NULL); break; case AJ_METHOD_GET_DESCRIPTION_LANG: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_GET_DESCRIPTION_LANG\n")); status = AJ_HandleGetDescriptionLanguages(msg, &reply); break; case AJ_METHOD_INTROSPECT_WITH_DESC: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_INTROSPECT_WITH_DESC\n")); AJ_UnmarshalArgs(msg, "s", &languageTag); status = AJ_HandleIntrospectRequest(msg, &reply, languageTag); break; case AJ_METHOD_EXCHANGE_GUIDS: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_EXCHANGE_GUIDS\n")); status = AJ_PeerHandleExchangeGUIDs(msg, &reply); break; case AJ_METHOD_GEN_SESSION_KEY: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_GEN_SESSION_KEY\n")); status = AJ_PeerHandleGenSessionKey(msg, &reply); break; case AJ_METHOD_EXCHANGE_GROUP_KEYS: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_EXCHANGE_GROUP_KEYS\n")); status = AJ_PeerHandleExchangeGroupKeys(msg, &reply); break; case AJ_METHOD_EXCHANGE_SUITES: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_EXCHANGE_SUITES\n")); status = AJ_PeerHandleExchangeSuites(msg, &reply); break; case AJ_METHOD_KEY_EXCHANGE: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_KEY_EXCHANGE\n")); status = AJ_PeerHandleKeyExchange(msg, &reply); break; case AJ_METHOD_KEY_AUTHENTICATION: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_METHOD_KEY_AUTHENTICATION\n")); status = AJ_PeerHandleKeyAuthentication(msg, &reply); break; case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GUIDS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GUIDS)\n")); status = AJ_PeerHandleExchangeGUIDsReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_SUITES): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_EXCHANGE_SUITES)\n")); status = AJ_PeerHandleExchangeSuitesReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_KEY_EXCHANGE): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_KEY_EXCHANGE)\n")); status = AJ_PeerHandleKeyExchangeReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_KEY_AUTHENTICATION): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_KEY_AUTHENTICATION)\n")); status = AJ_PeerHandleKeyAuthenticationReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_GEN_SESSION_KEY): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_GEN_SESSION_KEY)\n")); status = AJ_PeerHandleGenSessionKeyReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GROUP_KEYS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GROUP_KEYS)\n")); status = AJ_PeerHandleExchangeGroupKeysReply(msg); break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_SESSIONLESS): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_CANCEL_SESSIONLESS)\n")); // handle return code here status = AJ_OK; break; case AJ_SIGNAL_SESSION_JOINED: case AJ_SIGNAL_NAME_ACQUIRED: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_SIGNAL_{SESSION_JOINED|NAME_ACQUIRED}\n")); // nothing to do here status = AJ_OK; break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE): case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): AJ_InfoPrintf(("AJ_BusHandleBusMessage(): AJ_REPLY_ID(AJ_METHOD_{CANCEL_ADVERTISE|ADVERTISE_NAME})\n")); if (msg->hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } break; case AJ_METHOD_ABOUT_GET_PROP: return AJ_AboutHandleGetProp(msg); case AJ_METHOD_ABOUT_GET_ABOUT_DATA: status = AJ_AboutHandleGetAboutData(msg, &reply); break; case AJ_METHOD_ABOUT_GET_OBJECT_DESCRIPTION: status = AJ_AboutHandleGetObjectDescription(msg, &reply); break; case AJ_METHOD_ABOUT_ICON_GET_PROP: return AJ_AboutIconHandleGetProp(msg); case AJ_METHOD_ABOUT_ICON_GET_URL: status = AJ_AboutIconHandleGetURL(msg, &reply); break; case AJ_METHOD_ABOUT_ICON_GET_CONTENT: status = AJ_AboutIconHandleGetContent(msg, &reply); break; #ifdef ANNOUNCE_BASED_DISCOVERY case AJ_SIGNAL_ABOUT_ANNOUNCE: status = AJ_AboutHandleAnnounce(msg, NULL, NULL, NULL, NULL); break; #endif default: AJ_InfoPrintf(("AJ_BusHandleBusMessage(): default\n")); if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { status = AJ_MarshalErrorMsg(msg, &reply, AJ_ErrRejected); } break; } if ((status == AJ_OK) && (msg->hdr->msgType == AJ_MSG_METHOD_CALL)) { status = AJ_DeliverMsg(&reply); } /* * Check if there is anything to announce */ if (status == AJ_OK) { AJ_AboutAnnounce(bus); } return status; }
AJ_Status AJ_ProcessInternal(AJ_Message* msg, IdentifyFunction identifyFunction) { AJ_Status status = AJ_OK; switch (msg->msgId) { case APP_SET_WIFI: { uint32_t active = AJ_GetActive(); uint32_t index; char* ssid; char* password; uint32_t auth; uint32_t encryption; status = AJ_UnmarshalArgs(msg, "ussuu", &index, &ssid, &password, &auth, &encryption); if (status == AJ_OK) { status = AJ_SaveWifiProfile(index, ssid, password, auth, encryption); if (status == AJ_OK) { AJ_Message reply; AJ_MarshalReplyMsg(msg, &reply); status = AJ_DeliverMsg(&reply); } else { AJ_Message reply; AJ_MarshalErrorMsg(msg, &reply, "Invalid parameter"); status = AJ_DeliverMsg(&reply); } } // if we are modifying the current profile, we need to if (status == AJ_OK && index == active) { status = AJ_ERR_RESTART; } break; } case APP_GET_WIFI: { uint32_t index; status = AJ_UnmarshalArgs(msg, "u", &index); if (status == AJ_OK) { const AJ_ConnectionProfile* config = AJ_ReadProfile(index); switch (config->type) { case PROFILE_TYPE_WIFI: { const AJ_WifiProfile* profile = &(config->wifi); AJ_Message reply; AJ_MarshalReplyMsg(msg, &reply); AJ_MarshalArgs(&reply, "ssuu", profile->ssid, profile->password, &profile->auth, &profile->encryption); status = AJ_DeliverMsg(&reply); break; } default: status = AJ_ERR_INVALID; break; } } if (status != AJ_OK) { AJ_Message reply; AJ_MarshalErrorMsg(msg, &reply, "Invalid parameter"); status = AJ_DeliverMsg(&reply); } break; } case APP_IDENTIFY: { AJ_Message reply; char name[80]; // limit the output to 80 bytes (*identifyFunction)(name, sizeof(name)); name[sizeof(name) - 1] = '\0'; AJ_MarshalReplyMsg(msg, &reply); AJ_MarshalArgs(&reply, "s", name); status = AJ_DeliverMsg(&reply); break; } case APP_MAX_PROFILE: { AJ_Message reply; uint32_t max = MAX_PROFILES; AJ_MarshalReplyMsg(msg, &reply); AJ_MarshalArgs(&reply, "u", &max); status = AJ_DeliverMsg(&reply); break; } case APP_CLEAR: { AJ_Message reply; uint32_t index; status = AJ_UnmarshalArgs(msg, "u", &index); if (index == AJ_GetActive()) { AJ_MarshalErrorMsg(msg, &reply, "Cannot clear active profile"); status = AJ_DeliverMsg(&reply); } else { AJ_ClearConfig(index); AJ_MarshalReplyMsg(msg, &reply); status = AJ_DeliverMsg(&reply); } break; } case APP_CONNECT: { AJ_Message reply; uint32_t index; status = AJ_UnmarshalArgs(msg, "u", &index); if (status == AJ_OK) { status = AJ_SetActive(index); if (status == AJ_OK) { AJ_MarshalReplyMsg(msg, &reply); status = AJ_DeliverMsg(&reply); } } if (status != AJ_OK) { AJ_MarshalErrorMsg(msg, &reply, "Invalid parameter"); status = AJ_DeliverMsg(&reply); } else { status = AJ_ERR_RESTART; } break; } default: status = AJ_ERR_UNEXPECTED; break; } return status; }
static AJ_Status HandleMessage(duk_context* ctx, duk_idx_t ajIdx, AJ_Message* msg) { duk_idx_t msgIdx; uint8_t accessor = AJS_NOT_ACCESSOR; const char* func; AJ_Status status; uint8_t ldstate; #if !defined(AJS_CONSOLE_LOCKDOWN) status = AJS_GetLockdownState(&ldstate); if (status == AJ_OK && ldstate == AJS_CONSOLE_UNLOCKED) { status = AJS_ConsoleMsgHandler(ctx, msg); if (status != AJ_ERR_NO_MATCH) { if (status != AJ_OK) { AJ_WarnPrintf(("AJS_ConsoleMsgHandler returned %s\n", AJ_StatusText(status))); } return status; } } #endif /* * JOIN_SESSION replies are handled in the AllJoyn.js layer and don't get passed to JavaScript */ if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION)) { return AJS_HandleJoinSessionReply(ctx, msg); } /* * Nothing more to do if the AllJoyn module was not loaded */ if (ajIdx < 0) { return AJ_OK; } /* * Let the bases services layer take a look at the message */ status = AJS_ServicesMsgHandler(msg); if (status != AJ_ERR_NO_MATCH) { if (status != AJ_OK) { AJ_WarnPrintf(("AJS_ServicesMsgHandler returned %s\n", AJ_StatusText(status))); } return status; } /* * Push the appropriate callback function onto the duktape stack */ if (msg->hdr->msgType == AJ_MSG_SIGNAL) { /* * About announcements and found name signal get special handling */ if (msg->msgId == AJ_SIGNAL_ABOUT_ANNOUNCE) { return AJS_AboutAnnouncement(ctx, msg); } if (msg->msgId == AJ_SIGNAL_FOUND_ADV_NAME) { return AJS_FoundAdvertisedName(ctx, msg); } if ((msg->msgId == AJ_SIGNAL_SESSION_LOST) || (msg->msgId == AJ_SIGNAL_SESSION_LOST_WITH_REASON)) { if (AJS_DebuggerIsAttached()) { msg = AJS_CloneAndCloseMessage(ctx, msg); } return AJS_SessionLost(ctx, msg); } func = "onSignal"; duk_get_prop_string(ctx, ajIdx, func); } else if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { accessor = IsPropAccessor(msg); switch (accessor) { case AJS_NOT_ACCESSOR: func = "onMethodCall"; break; case AJ_PROP_GET: func = "onPropGet"; break; case AJ_PROP_SET: func = "onPropSet"; break; case AJ_PROP_GET_ALL: func = "onPropGetAll"; break; default: return AJ_ERR_INVALID; } duk_get_prop_string(ctx, ajIdx, func); } else { func = "onReply"; AJS_GetGlobalStashObject(ctx, func); if (duk_is_object(ctx, -1)) { duk_get_prop_index(ctx, -1, msg->replySerial); duk_swap_top(ctx, -2); /* * Clear the onReply entry */ duk_del_prop_index(ctx, -1, msg->replySerial); duk_pop(ctx); } } /* * Skip if there is no function to call. */ if (!duk_is_function(ctx, -1)) { if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { AJ_Message error; AJ_WarnPrintf(("%s: not registered - rejecting message\n", func)); AJ_MarshalErrorMsg(msg, &error, AJ_ErrRejected); status = AJ_DeliverMsg(&error); } else { AJ_WarnPrintf(("%s: not registered - ignoring message\n", func)); status = AJ_OK; } duk_pop(ctx); return status; } /* * Opens up a stack entry above the function */ duk_dup_top(ctx); msgIdx = AJS_UnmarshalMessage(ctx, msg, accessor); AJ_ASSERT(msgIdx == (ajIdx + 3)); /* * Save the message object on the stack */ duk_copy(ctx, msgIdx, -3); /* * Special case for GET prop so we can get the signature for marshalling the result */ if (accessor == AJS_NOT_ACCESSOR) { status = AJS_UnmarshalMsgArgs(ctx, msg); } else { status = AJS_UnmarshalPropArgs(ctx, msg, accessor, msgIdx); } if (status == AJ_OK) { duk_idx_t numArgs = duk_get_top(ctx) - msgIdx - 1; /* * If attached, the debugger will begin to unmarshal a message when the * method handler is called, therefore it must be cloned-and-closed now. */ if (AJS_DebuggerIsAttached()) { msg = AJS_CloneAndCloseMessage(ctx, msg); } if (duk_pcall_method(ctx, numArgs) != DUK_EXEC_SUCCESS) { const char* err = duk_safe_to_string(ctx, -1); AJ_ErrPrintf(("%s: %s\n", func, err)); /* * Generate an error reply if this was a method call */ if (msg->hdr->msgType == AJ_MSG_METHOD_CALL) { duk_push_c_lightfunc(ctx, AJS_MethodCallError, 1, 0, 0); duk_insert(ctx, -3); (void)duk_pcall_method(ctx, 1); } } } /* * Cleanup stack back to the AJ object */ duk_set_top(ctx, ajIdx + 1); return status; }