static AJSVC_ServiceStatus AJApp_MessageProcessor(AJ_BusAttachment* bus, AJ_Message* msg, AJ_Status* status) { AJSVC_ServiceStatus serviceStatus = AJSVC_SERVICE_STATUS_NOT_HANDLED; switch (currentServicesInitializationState) { case INIT_SERVICES_PORT: if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT)) { currentServicesInitializationState = nextServicesInitializationState; } break; case INIT_ADVERTISE_NAME: if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME)) { currentServicesInitializationState = nextServicesInitializationState; } break; case INIT_ADDSLMATCH: if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_ADD_MATCH)) { currentServicesInitializationState = nextServicesInitializationState; } break; default: break; } return serviceStatus; }
static AJSVC_ServiceStatus AJApp_MessageProcessor(AJ_BusAttachment* busAttachment, AJ_Message* msg, AJ_Status* status) { AJSVC_ServiceStatus serviceStatus = AJSVC_SERVICE_STATUS_HANDLED; uint16_t port; char* joiner; uint32_t sessionId = 0; uint8_t session_accepted = FALSE; if (msg->msgId == AJ_METHOD_ACCEPT_SESSION) { // Process all incoming request to join a session and pass request for acceptance by all services *status = AJ_UnmarshalArgs(msg, "qus", &port, &sessionId, &joiner); if (*status != AJ_OK) { return serviceStatus; } session_accepted |= (port == AJ_ABOUT_SERVICE_PORT); session_accepted |= AJSVC_CheckSessionAccepted(port, sessionId, joiner); *status = AJ_BusReplyAcceptSession(msg, session_accepted); AJ_AlwaysPrintf(("%s session session_id=%u joiner=%s for port %u\n", (session_accepted ? "Accepted" : "Rejected"), sessionId, joiner, port)); } else { switch (currentServicesInitializationState) { case INIT_SERVICES_PORT: if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT)) { currentServicesInitializationState = nextServicesInitializationState; } break; default: serviceStatus = AJSVC_MessageProcessorAndDispatcher(busAttachment, msg, status); break; } } return serviceStatus; }
AJ_Status AJNS_Producer_ConnectedHandler(AJ_BusAttachment* busAttachment) { AJ_Status status; AJ_SessionOpts sessionOpts = { AJ_SESSION_TRAFFIC_MESSAGES, AJ_SESSION_PROXIMITY_ANY, AJ_TRANSPORT_ANY, FALSE }; uint8_t serviceStarted; AJ_Message msg; status = AJ_BusBindSessionPort(busAttachment, AJNS_NotificationProducerPort, &sessionOpts, 0); if (status != AJ_OK) { AJ_ErrPrintf(("Failed to send bind session port message\n")); } serviceStarted = FALSE; while (!serviceStarted && (status == AJ_OK)) { status = AJ_UnmarshalMsg(busAttachment, &msg, AJ_UNMARSHAL_TIMEOUT); if (status == AJ_ERR_NO_MATCH) { status = AJ_OK; continue; } else if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { serviceStarted = TRUE; } break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_ErrPrintf(("AllJoyn disconnect bus status=%d\n", status)); status = AJ_ERR_READ; } return status; }
AJSVC_ServiceStatus AJNS_Consumer_MessageProcessor(AJ_BusAttachment* busAttachment, AJ_Message* msg, AJ_Status* msgStatus) { switch (msg->msgId) { case NOTIFICATION_SIGNAL_RECEIVED: AJ_InfoPrintf(("Received Producer signal.\n")); *msgStatus = AJNS_Consumer_NotifySignalHandler(msg); break; case SUPERAGENT_SIGNAL: AJ_InfoPrintf(("Received Superagent Signal.\n")); *msgStatus = AJNS_Consumer_SetSignalRules(busAttachment, appSuperAgentMode, msg->sender); if (AJ_OK == *msgStatus && appProxyObjects != NULL) { appProxyObjects[NOTIFICATION_PROXYOBJECT_INDEX] = SuperAgentProxyObject; } *msgStatus = AJNS_Consumer_NotifySignalHandler(msg); break; case NOTIFICATION_DISMISSER_DISMISS_RECEIVED: AJ_InfoPrintf(("Received Dismisser Dismiss signal.\n")); *msgStatus = AJNS_Consumer_DismissSignalHandler(msg); break; case AJ_SIGNAL_LOST_ADV_NAME: if (appSuperAgentMode && AJNS_Consumer_IsSuperAgentLost(msg)) { *msgStatus = AJNS_Consumer_SetSignalRules(busAttachment, appSuperAgentMode, NULL); if (AJ_OK == *msgStatus && appProxyObjects != NULL) { appProxyObjects[NOTIFICATION_PROXYOBJECT_INDEX] = AllProxyObject; } } else { return AJSVC_SERVICE_STATUS_NOT_HANDLED; } break; case AJ_REPLY_ID(NOTIFICATION_PRODUCER_DISMISS_PROXY): if (producerSessionId != 0) { AJ_InfoPrintf(("NotificationProducer method replied. Leaving session %u\n", producerSessionId)); *msgStatus = AJ_BusLeaveSession(busAttachment, producerSessionId); if (AJ_OK != *msgStatus) { AJ_InfoPrintf(("Failed to leave session %u\n", producerSessionId)); } *msgStatus = AJNS_Consumer_SessionLostHandler(busAttachment, producerSessionId, 0); // Don't wait for SessionLost handle it immediately producerSessionId = 0; } break; default: return AJSVC_SERVICE_STATUS_NOT_HANDLED; } return AJSVC_SERVICE_STATUS_HANDLED; }
static AJ_Status SetSignalRules(AJ_BusAttachment* bus) { AJ_Status status = AJ_OK; /* * AJ_GUID needs the NameOwnerChanged signal to clear out entries in * its map. Prior to router version 10 this means we must set a * signal rule to receive every NameOwnerChanged signal. With * version 10 the router supports the arg[0,1,...] key in match * rules, allowing us to set a signal rule for just the * NameOwnerChanged signals of entries in the map. See aj_guid.c * for usage of the arg key. */ if (AJ_GetRoutingProtoVersion() < 11) { 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); } } } } return status; }
/* * This function is registered with About and handles property store read requests */ static AJ_Status AboutPropGetter(AJ_Message* msg, const char* language) { AJ_Status status = AJ_ERR_INVALID; int8_t langIndex; AJSVC_PropertyStoreCategoryFilter filter; memset(&filter, 0, sizeof(AJSVC_PropertyStoreCategoryFilter)); if (msg->msgId == AJ_SIGNAL_ABOUT_ANNOUNCE) { filter.bit2Announce = TRUE; langIndex = AJSVC_PropertyStore_GetLanguageIndex(language); status = AJ_OK; } else if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_ABOUT_GET_ABOUT_DATA)) { filter.bit0About = TRUE; langIndex = AJSVC_PropertyStore_GetLanguageIndex(language); status = (langIndex == AJSVC_PROPERTY_STORE_ERROR_LANGUAGE_INDEX) ? AJ_ERR_UNKNOWN : AJ_OK; } if (status == AJ_OK) { status = AJSVC_PropertyStore_ReadAll(msg, filter, langIndex); } return status; }
int AJ_Main() { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(AppObjects, NULL); SetBusAuthPwdCallback(MyBusAuthPwdCB); while (TRUE) { AJ_Message msg; if (!connected) { status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServicePort, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE, NULL); if (status != AJ_OK) { continue; } AJ_InfoPrintf(("StartService returned AJ_OK\n")); AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus))); connected = TRUE; #ifdef SECURE_OBJECT status = AJ_SetObjectFlags("/org/alljoyn/alljoyn_test", AJ_OBJ_FLAG_SECURE, 0); if (status != AJ_OK) { AJ_ErrPrintf(("Error calling AJ_SetObjectFlags.. [%s] \n", AJ_StatusText(status))); return -1; } #endif #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) /* Register a callback for providing bus authentication password */ AJ_BusSetPasswordCallback(&bus, PasswordCallback); AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); #endif /* Configure timeout for the link to the daemon bus */ AJ_SetBusLinkTimeout(&bus, 60); // 60 seconds } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status && AJ_ERR_LINK_TIMEOUT == AJ_BusLinkStateProc(&bus)) { status = AJ_ERR_READ; } if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(); continue; } } if (status == AJ_OK) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_InfoPrintf(("Failed to add match\n")); status = AJ_ERR_FAILURE; } else { status = AJ_OK; } break; case AJ_METHOD_ACCEPT_SESSION: { uint16_t port; char* joiner; AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner); if (port == ServicePort) { status = AJ_BusReplyAcceptSession(&msg, TRUE); AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", sessionId, joiner)); } else { status = AJ_BusReplyAcceptSession(&msg, FALSE); AJ_InfoPrintf(("Accepted rejected session_id=%u joiner=%s\n", sessionId, joiner)); } } break; case APP_MY_PING: status = AppHandlePing(&msg); break; case APP_GET_PROP: status = AJ_BusPropGet(&msg, PropGetHandler, NULL); break; case APP_SET_PROP: status = AJ_BusPropSet(&msg, PropSetHandler, NULL); if (status == AJ_OK) { AJ_InfoPrintf(("Property successfully set to %d.\n", propVal)); } else { AJ_InfoPrintf(("Property set attempt unsuccessful. Status = 0x%04x.\n", status)); } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0); } status = AJ_ERR_SESSION_LOST; } break; case AJ_SIGNAL_SESSION_JOINED: if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_STOP_ADVERTISING, 0); } break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE): case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } break; case APP_MY_SIGNAL: AJ_InfoPrintf(("Received my_signal\n")); status = AJ_OK; if (ReflectSignal) { AJ_Message out; AJ_MarshalSignal(&bus, &out, APP_MY_SIGNAL, msg.destination, msg.sessionId, 0, 0); AJ_MarshalArgs(&out, "a{ys}", 0, NULL); AJ_DeliverMsg(&out); AJ_CloseMsg(&out); } break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } // Any received packets indicates the link is active, so call to reinforce the bus link state AJ_NotifyLinkActive(); } /* * Unarshaled messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) { AJ_InfoPrintf(("AllJoyn disconnect\n")); AJ_InfoPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_Disconnect(&bus); connected = FALSE; /* * Sleep a little while before trying to reconnect */ AJ_Sleep(10 * 1000); } } AJ_WarnPrintf(("svclite EXIT %d\n", status)); return status; }
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; }
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_StartService(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, uint16_t port, const char* name, uint32_t flags, const AJ_SessionOpts* opts ) { AJ_Status status; AJ_Time timer; uint8_t serviceStarted = FALSE; AJ_InfoPrintf(("AJ_StartService(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., port=%d., name=\"%s\", flags=0x%x, opts=0x%p)\n", bus, daemonName, timeout, connected, port, name, flags, opts)); AJ_InitTimer(&timer); while (TRUE) { if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } if (!connected) { AJ_InfoPrintf(("AJ_StartService(): AJ_FindBusAndConnect()\n")); status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("AJ_StartService(): connect failed: sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AJ_StartService(): connected to bus\n")); } /* * Kick things off by binding a session port */ AJ_InfoPrintf(("AJ_StartService(): AJ_BindSessionPort()\n")); status = AJ_BusBindSessionPort(bus, port, opts, 0); if (status == AJ_OK) { break; } AJ_ErrPrintf(("AJ_StartService(): AJ_Disconnect(): status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } while (!serviceStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if (status == AJ_ERR_NO_MATCH) { // Ignore unknown messages status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartService(): status=%s.\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_BIND_SESSION_PORT: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { AJ_InfoPrintf(("AJ_StartService(): AJ_BusRequestName()\n")); status = AJ_BusRequestName(bus, name, flags); } break; case AJ_REPLY_ID(AJ_METHOD_REQUEST_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_REQUEST_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { AJ_InfoPrintf(("AJ_StartService(): AJ_BusAdvertiseName()\n")); status = AJ_BusAdvertiseName(bus, name, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0); } break; case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_ADVERTISE_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { serviceStarted = TRUE; } break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartService(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status == AJ_OK) { status = AJ_AboutInit(bus, port); } else { AJ_WarnPrintf(("AJ_StartService(): AJ_Disconnect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
AJSVC_ServiceStatus AJServices_MessageProcessor(AJ_BusAttachment* busAttachment, AJ_Message* msg, AJ_Status* status) { AJSVC_ServiceStatus serviceStatus = AJSVC_SERVICE_STATUS_NOT_HANDLED; if (msg->msgId == AJ_METHOD_ACCEPT_SESSION) { // Process all incoming request to join a session and pass request for acceptance by all services uint16_t port; char* joiner; uint32_t sessionId = 0; AJ_UnmarshalArgs(msg, "qus", &port, &sessionId, &joiner); uint8_t session_accepted = FALSE; session_accepted |= AJServices_CheckSessionAccepted(port, sessionId, joiner); *status = AJ_BusReplyAcceptSession(msg, session_accepted); AJ_AlwaysPrintf(("%s session session_id=%u joiner=%s for port %u\n", (session_accepted ? "Accepted" : "Rejected"), sessionId, joiner, port)); serviceStatus = AJSVC_SERVICE_STATUS_HANDLED; } else if (msg->msgId == AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION)) { // Process all incoming replies to join a session and pass session state change to all services uint32_t replyCode = 0; uint32_t sessionId = 0; uint8_t sessionJoined = FALSE; uint32_t joinSessionReplySerialNum = msg->replySerial; if (msg->hdr->msgType == AJ_MSG_ERROR) { AJ_AlwaysPrintf(("JoinSessionReply: AJ_METHOD_JOIN_SESSION: AJ_ERR_FAILURE\n")); *status = AJ_ERR_FAILURE; } else { *status = AJ_UnmarshalArgs(msg, "uu", &replyCode, &sessionId); if (*status != AJ_OK) { AJ_AlwaysPrintf(("JoinSessionReply: failed to unmarshal\n")); } else { if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { AJ_AlwaysPrintf(("JoinSessionReply: AJ_JOINSESSION_REPLY_SUCCESS with sessionId=%u and replySerial=%u\n", sessionId, joinSessionReplySerialNum)); sessionJoined = TRUE; } else { AJ_AlwaysPrintf(("JoinSessionReply: AJ_ERR_FAILURE\n")); *status = AJ_ERR_FAILURE; } } } if (sessionJoined) { serviceStatus = AJServices_SessionJoinedHandler(busAttachment, sessionId, joinSessionReplySerialNum); } else { serviceStatus = AJServices_SessionRejectedHandler(busAttachment, sessionId, joinSessionReplySerialNum, replyCode); } if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { AJ_ResetArgs(msg); } } else if (msg->msgId == AJ_SIGNAL_SESSION_LOST || msg->msgId == AJ_SIGNAL_SESSION_LOST_WITH_REASON) { // Process all incoming LeaveSession replies and lost session signals and pass session state change to all services uint32_t sessionId = 0; uint32_t reason = 0; if (msg->msgId == AJ_SIGNAL_SESSION_LOST_WITH_REASON) { *status = AJ_UnmarshalArgs(msg, "uu", &sessionId, &reason); } else { *status = AJ_UnmarshalArgs(msg, "u", &sessionId); } if (*status != AJ_OK) { AJ_AlwaysPrintf(("JoinSessionReply: failed to marshal\n")); } else { AJ_AlwaysPrintf(("Session lost: sessionId = %u, reason = %u\n", sessionId, reason)); serviceStatus = AJServices_SessionLostHandler(busAttachment, sessionId, reason); if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { AJ_ResetArgs(msg); } } } else { if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJApp_MessageProcessor(busAttachment, msg, status); } if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJ_About_MessageProcessor(busAttachment, msg, status); } #ifdef CONFIG_SERVICE if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJCFG_MessageProcessor(busAttachment, msg, status); } #endif #ifdef ONBOARDING_SERVICE if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJOBS_MessageProcessor(busAttachment, msg, status); } #endif #ifdef NOTIFICATION_SERVICE_PRODUCER if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJNS_Producer_MessageProcessor(busAttachment, msg, status); } #endif #ifdef NOTIFICATION_SERVICE_CONSUMER if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJNS_Consumer_MessageProcessor(busAttachment, msg, status); } #endif #ifdef CONTROLPANEL_SERVICE if (serviceStatus == AJSVC_SERVICE_STATUS_NOT_HANDLED) { serviceStatus = AJCPS_MessageProcessor(busAttachment, msg, status); } #endif } return serviceStatus; }
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_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 AJS_AttachAllJoyn(AJ_BusAttachment* aj) { AJ_Status status; uint8_t isConnected = FALSE; uint32_t linkTO = LINK_TO; size_t sapSz; /* * Initialize the onboarding service */ sapSz = min(sizeof(obSettings.AJOBS_SoftAPSSID), sizeof(softAPSSID)); memcpy((char*)obSettings.AJOBS_SoftAPSSID, softAPSSID, sapSz); status = AJOBS_Start(&obSettings); if (status != AJ_OK) { goto Exit; } AJ_InfoPrintf(("Attempting to attach to AllJoyn\n")); while (!isConnected) { status = AJSVC_RoutingNodeConnect(aj, busNode, CONNECT_TO, CONNECT_PAUSE, linkTO, &isConnected); if (status != AJ_ERR_TIMEOUT) { break; } } if (isConnected) { status = AJS_ServicesInit(aj); if (status != AJ_OK) { AJ_ErrPrintf(("Failed to initialize services")); } } if (isConnected && (AJOBS_GetState() != AJOBS_STATE_CONFIGURED_VALIDATED)) { /* * Kick of onboarding */ status = AJ_BusBindSessionPort(aj, ONBOARDING_PORT, NULL, 0); /* * Allow onboarding service to run its course */ while (status == AJ_OK) { AJ_Message msg; status = AJ_UnmarshalMsg(aj, &msg, MSG_TO); if (status == AJ_ERR_NO_MATCH) { /* * Discard unknown messages */ status = AJ_CloseMsg(&msg); continue; } if (status == AJ_ERR_TIMEOUT) { /* * Check the link is still up */ status = AJ_BusLinkStateProc(aj); if (status == AJ_OK) { continue; } } if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): AJ_AboutInit(aj, ONBOARDING_PORT); break; case AJ_METHOD_ACCEPT_SESSION: /* * TODO - check that the port number is correct */ status = AJ_BusReplyAcceptSession(&msg, TRUE); if (status == AJ_OK) { status = AJOBS_ConnectedHandler(aj); } break; default: /* * Let the service message handlers have first dibs on the message */ status = AJS_ServicesMsgHandler(&msg); if (status == AJ_ERR_NO_MATCH) { /* * Pass the unhandled message to the standard bus handler */ status = AJ_BusHandleBusMessage(&msg); if (status == AJ_ERR_NO_MATCH) { AJ_ErrPrintf(("Discarding unhandled message\n")); status = AJ_OK; } } break; } /* * Let the link monitor know we are receiving messages */ AJ_NotifyLinkActive(); /* * Free resources used by the message */ AJ_CloseMsg(&msg); if (AJOBS_GetState() == AJOBS_STATE_CONFIGURED_VALIDATED) { AJ_InfoPrintf(("Onboarding completed\n")); break; } AJ_InfoPrintf(("Onboarding continuing\n")); } /* * If we got an error during onboarding we should restart */ if (status != AJ_OK) { status = AJ_ERR_RESTART; } } /* * If all went well let the services know we are connected */ if (isConnected && (status == AJ_OK)) { /* * Add match rules to subscribe to session related signals */ status = AJ_BusSetSignalRuleFlags(aj, sessionLostMatchRule, AJ_BUS_SIGNAL_ALLOW, AJ_FLAG_NO_REPLY_EXPECTED); if (status == AJ_OK) { status = AJSVC_ConnectedHandler(aj); } } Exit: return status; }
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; }
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; }
int main(int argc, char*argv[]) { AJ_Status status = AJ_ERR_INVALID; if (argc > 1) { AJ_BusAttachment bus; uint8_t connected = FALSE; uint8_t done = FALSE; uint32_t sessionId = 0; char*newName = argv[1]; status = AJ_OK; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(NULL, AppObjects); while (!done) { AJ_Message msg; if (!connected) { status = AJ_StartClient(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServiceName, ServicePort, &sessionId, NULL); if (status == AJ_OK) { AJ_InfoPrintf(("StartClient returned %d, sessionId=%u.\n", status, sessionId)); connected = TRUE; SendNewName(&bus, sessionId, newName); } else { AJ_InfoPrintf(("StartClient returned 0x%04x.\n", status)); break; } } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { continue; } if (AJ_OK == status) { switch (msg.msgId) { case AJ_REPLY_ID(PRX_SET_PROP): done = TRUE; AJ_Printf("Name on the interface '%s' at service '%s' was set to '%s'.\n", InterfaceName, ServiceName, newName); 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 discarded to free resources. */ AJ_CloseMsg(&msg); if (status == AJ_ERR_SESSION_LOST) { AJ_Printf("AllJoyn disconnect.\n"); AJ_Disconnect(&bus); exit(0); } } } else { AJ_ErrPrintf(("Error. New name not given: nameChange_client [new name].\n")); } AJ_Printf("nameChange_Client exiting with status 0x%04x.\n", status); 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() { AJ_Status status; AJ_BusAttachment bus; int i; AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(AppObjects, NULL); Do_Connect(&bus); if (authenticate) { AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); } else { authStatus = AJ_OK; } i = 0; while (commands[i] != NULL) { AJ_AlwaysPrintf(("%s\n", commands[i])); i++; } i = 0; while (TRUE) { // check for serial input and dispatch if needed. char buf[1024]; AJ_Message msg; // read a line if (commands[i] != NULL) { char*command; strcpy(buf, commands[i]); AJ_AlwaysPrintf((">~~~%s\n", buf)); command = aj_strtok(buf, " \r\n"); i++; if (0 == strcmp("startservice", command)) { uint16_t port = 0; const char* name; AJ_SessionOpts opts; char* token = aj_strtok(NULL, " \r\n"); if (token) { name = token; } else { name = ServiceName; } token = aj_strtok(NULL, " \r\n"); if (token) { port = (uint16_t)atoi(token); } if (port == 0) { port = ServicePort; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.isMultipoint = (0 == strcmp("true", token)); } else { opts.isMultipoint = 0; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.traffic = atoi(token); } else { opts.traffic = 0x1; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.proximity = atoi(token); } else { opts.proximity = 0xFF; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.transports = atoi(token); } else { opts.transports = 0xFFFF; } status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, TRUE, port, name, AJ_NAME_REQ_DO_NOT_QUEUE, &opts); AJ_BusAddSignalRule(&bus, "Chat", InterfaceName, AJ_BUS_SIGNAL_ALLOW); } else if (0 == strcmp("find", command)) { char* namePrefix = aj_strtok(NULL, " \r\n"); if (!namePrefix) { AJ_AlwaysPrintf(("Usage: find <name_prefix>\n")); continue; } status = AJ_BusFindAdvertisedName(&bus, namePrefix, AJ_BUS_START_FINDING); } else if (0 == strcmp("cancelfind", command)) { char* namePrefix = aj_strtok(NULL, " \r\n"); if (!namePrefix) { AJ_AlwaysPrintf(("Usage: cancelfind <name_prefix>\n")); continue; } status = AJ_BusFindAdvertisedName(&bus, namePrefix, AJ_BUS_STOP_FINDING); } else if (0 == strcmp("find2", command)) { char* namePrefix = aj_strtok(NULL, " \r\n"); uint16_t transport = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { transport = (uint16_t)atoi(token); } if (!namePrefix || !transport) { AJ_AlwaysPrintf(("Usage: find2 <name_prefix> <transport>\n")); continue; } status = AJ_BusFindAdvertisedNameByTransport(&bus, namePrefix, transport, AJ_BUS_START_FINDING); } else if (0 == strcmp("cancelfind2", command)) { char* namePrefix = aj_strtok(NULL, " \r\n"); uint16_t transport = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { transport = (uint16_t)atoi(token); } if (!namePrefix || !transport) { AJ_AlwaysPrintf(("Usage: cancelfind2 <name_prefix> <transport>\n")); continue; } status = AJ_BusFindAdvertisedNameByTransport(&bus, namePrefix, transport, AJ_BUS_STOP_FINDING); } else if (0 == strcmp("requestname", command)) { char* name = aj_strtok(NULL, " \r\n"); if (!name) { AJ_AlwaysPrintf(("Usage: requestname <name>\n")); continue; } status = AJ_BusRequestName(&bus, name, AJ_NAME_REQ_DO_NOT_QUEUE); } else if (0 == strcmp("releasename", command)) { char* name = aj_strtok(NULL, " \r\n"); if (!name) { AJ_AlwaysPrintf(("Usage: releasename <name>\n")); continue; } status = AJ_BusReleaseName(&bus, name); } else if (0 == strcmp("advertise", command)) { uint16_t transport = 0xFFFF; char* token = NULL; char* name = aj_strtok(NULL, " \r\n"); if (!name) { AJ_AlwaysPrintf(("Usage: advertise <name> [transports]\n")); continue; } token = aj_strtok(NULL, " \r\n"); if (token) { transport = (uint16_t)atoi(token); } status = AJ_BusAdvertiseName(&bus, name, transport, AJ_BUS_START_ADVERTISING, 0); } else if (0 == strcmp("canceladvertise", command)) { uint16_t transport = 0xFFFF; char* token = NULL; char* name = aj_strtok(NULL, " \r\n"); if (!name) { AJ_AlwaysPrintf(("Usage: canceladvertise <name> [transports]\n")); continue; } token = aj_strtok(NULL, " \r\n"); if (token) { transport = (uint16_t)atoi(token); } status = AJ_BusAdvertiseName(&bus, name, transport, AJ_BUS_STOP_ADVERTISING, 0); } else if (0 == strcmp("bind", command)) { AJ_SessionOpts opts; uint16_t port = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { port = (uint16_t)atoi(token); } if (port == 0) { AJ_AlwaysPrintf(("Usage: bind <port> [isMultipoint] [traffic] [proximity] [transports]\n")); continue; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.isMultipoint = (0 == strcmp("true", token)); } else { opts.isMultipoint = 0; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.traffic = atoi(token); } else { opts.traffic = 0x1; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.proximity = atoi(token); } else { opts.proximity = 0xFF; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.transports = atoi(token); } else { opts.transports = 0xFFFF; } status = AJ_BusBindSessionPort(&bus, port, &opts, 0); } else if (0 == strcmp("unbind", command)) { uint16_t port = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { port = (uint16_t) atoi(token); } if (port == 0) { AJ_AlwaysPrintf(("Usage: unbind <port>\n")); continue; } status = AJ_BusUnbindSession(&bus, port); } else if (0 == strcmp("join", command)) { AJ_SessionOpts opts; uint16_t port = 0; char* name = aj_strtok(NULL, " \r\n"); char* token = aj_strtok(NULL, " \r\n"); if (token) { port = (uint16_t)atoi(token); } else { port = 0; } if (!name || (port == 0)) { AJ_AlwaysPrintf(("Usage: join <name> <port> [isMultipoint] [traffic] [proximity] [transports]\n")); continue; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.isMultipoint = (0 == strcmp("true", token)); } else { opts.isMultipoint = 0; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.traffic = (uint8_t)atoi(token); } else { opts.traffic = 0x1; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.proximity = (uint8_t)atoi(token); } else { opts.proximity = 0xFF; } token = aj_strtok(NULL, " \r\n"); if (token) { opts.transports = (uint16_t)atoi(token); } else { opts.transports = 0xFFFF; } status = AJ_BusJoinSession(&bus, name, port, &opts); } else if (0 == strcmp("leave", command)) { uint32_t sessionId = (uint32_t)atoi(aj_strtok(NULL, "\r\n")); if (sessionId == 0) { AJ_AlwaysPrintf(("Usage: leave <sessionId>\n")); continue; } status = AJ_BusLeaveSession(&bus, sessionId); } else if (0 == strcmp("addmatch", command)) { char* ruleString = aj_strtok(NULL, "\r\n"); if (!ruleString) { AJ_AlwaysPrintf(("Usage: addmatch <rule>\n")); continue; } status = AJ_BusSetSignalRule(&bus, ruleString, AJ_BUS_SIGNAL_ALLOW); } else if (0 == strcmp("removematch", command)) { char* ruleString = aj_strtok(NULL, "\r\n"); if (!ruleString) { AJ_AlwaysPrintf(("Usage: removematch <rule>\n")); continue; } status = AJ_BusSetSignalRule(&bus, ruleString, AJ_BUS_SIGNAL_DENY); } else if (0 == strcmp("sendttl", command)) { int32_t ttl = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { ttl = atoi(token); } if (ttl < 0) { AJ_AlwaysPrintf(("Usage: sendttl <ttl>\n")); continue; } sendTTL = ttl; } else if (0 == strcmp("schat", command)) { char* chatMsg = aj_strtok(NULL, "\r\n"); if (!chatMsg) { AJ_AlwaysPrintf(("Usage: schat <msg>\n")); continue; } status = AppSendChatSignal(&bus, 0, chatMsg, AJ_FLAG_SESSIONLESS, sendTTL); } else if (0 == strcmp("chat", command)) { char* sessionIdString = aj_strtok(NULL, " \r\n"); char*chatMsg; uint32_t session = g_sessionId; if (sessionIdString != NULL) { if (sessionIdString[0] != '#') { session = (long)atoi(sessionIdString); } } chatMsg = aj_strtok(NULL, "\r\n"); status = AppSendChatSignal(&bus, session, chatMsg, 0, sendTTL); } else if (0 == strcmp("cancelsessionless", command)) { uint32_t serialId = 0; char* token = aj_strtok(NULL, " \r\n"); if (token) { serialId = (uint32_t)atoi(token); } if (serialId == 0) { AJ_AlwaysPrintf(("Invalid serial number\n")); AJ_AlwaysPrintf(("Usage: cancelsessionless <serialNum>\n")); continue; } status = AJ_BusCancelSessionless(&bus, serialId); } else if (0 == strcmp("exit", command)) { break; } else if (0 == strcmp("help", command)) { //AJ_AlwaysPrintf(("debug <module_name> <level> - Set debug level for a module\n")); AJ_AlwaysPrintf(("startservice [name] [port] [isMultipoint] [traffic] [proximity] [transports] - Startservice\n")); AJ_AlwaysPrintf(("requestname <name> - Request a well-known name\n")); AJ_AlwaysPrintf(("releasename <name> - Release a well-known name\n")); AJ_AlwaysPrintf(("bind <port> [isMultipoint] [traffic] [proximity] [transports] - Bind a session port\n")); AJ_AlwaysPrintf(("unbind <port> - Unbind a session port\n")); AJ_AlwaysPrintf(("advertise <name> [transports] - Advertise a name\n")); AJ_AlwaysPrintf(("canceladvertise <name> [transports] - Cancel an advertisement\n")); AJ_AlwaysPrintf(("find <name_prefix> - Discover names that begin with prefix\n")); AJ_AlwaysPrintf(("find2 <name_prefix> <transport> - Discover names that begin with prefix by specific transports\n")); AJ_AlwaysPrintf(("cancelfind <name_prefix> - Cancel discovering names that begins with prefix\n")); AJ_AlwaysPrintf(("cancelfind2 <name_prefix> <transport> - Cancel discovering names that begins with prefix by specific transports\n")); AJ_AlwaysPrintf(("join <name> <port> [isMultipoint] [traffic] [proximity] [transports] - Join a session\n")); AJ_AlwaysPrintf(("leave <sessionId> - Leave a session\n")); AJ_AlwaysPrintf(("chat <sessionId> <msg> - Send a message over a given session\n")); AJ_AlwaysPrintf(("schat <msg> - Send a sessionless message\n")); AJ_AlwaysPrintf(("cancelsessionless <serialNum> - Cancel a sessionless message\n")); AJ_AlwaysPrintf(("addmatch <rule> - Add a DBUS rule\n")); AJ_AlwaysPrintf(("removematch <rule> - Remove a DBUS rule\n")); AJ_AlwaysPrintf(("sendttl <ttl> - Set default ttl (in ms) for all chat messages (0 = infinite)\n")); AJ_AlwaysPrintf(("exit - Exit this program\n")); AJ_AlwaysPrintf(("\n")); continue; } else if (0 == strcmp("wait", command)) { char* token = aj_strtok(NULL, " \n\r"); if (token) { AJ_AlwaysPrintf(("Sleeping...\n")); AJ_Sleep((uint16_t)atoi(token)); AJ_AlwaysPrintf(("Done\n")); } } else { AJ_AlwaysPrintf(("Unknown command: %s\n", command)); continue; } } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(); continue; } } if (status == AJ_OK) { switch (msg.msgId) { case AJ_METHOD_ACCEPT_SESSION: { uint16_t port; char* joiner; AJ_AlwaysPrintf(("Accepting...\n")); AJ_UnmarshalArgs(&msg, "qus", &port, &g_sessionId, &joiner); status = AJ_BusReplyAcceptSession(&msg, TRUE); if (status == AJ_OK) { AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", g_sessionId, joiner)); } else { AJ_InfoPrintf(("AJ_BusReplyAcceptSession: error %d\n", status)); } } 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, &g_sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { AJ_InfoPrintf(("Joined session session_id=%u\n", g_sessionId)); AJ_BusAddSignalRule(&bus, "Chat", InterfaceName, AJ_BUS_SIGNAL_ALLOW); } else { AJ_InfoPrintf(("Joined session failed\n")); } } } break; case APP_CHAT_SIGNAL: status = AppHandleChatSignal(&msg); break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * don't force a disconnect, be ready to accept another session */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } break; case AJ_SIGNAL_FOUND_ADV_NAME: { char* name; char* namePrefix; uint16_t transport; AJ_UnmarshalArgs(&msg, "sqs", &name, &transport, &namePrefix); AJ_AlwaysPrintf(("FoundAdvertisedName name=%s, namePrefix=%s\n", name, namePrefix)); } 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) || (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); connected = FALSE; /* * Sleep a little while before trying to reconnect */ AJ_Sleep(10 * 1000); Do_Connect(&bus); } } return 0; }
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; }
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 AJS_MessageLoop(duk_context* ctx, AJ_BusAttachment* aj, duk_idx_t ajIdx) { AJ_Status status = AJ_OK; AJ_Message msg; AJ_Time timerClock; uint32_t linkTO; uint32_t msgTO = 0x7FFFFFFF; duk_idx_t top = duk_get_top_index(ctx); uint8_t ldstate; AJ_InfoPrintf(("AJS_MessageLoop top=%d\n", (int)top)); deferredOp = AJS_OP_NONE; if (ajIdx >= 0) { /* * Read the link timeout property from the config set */ duk_get_prop_string(ctx, -1, "config"); duk_get_prop_string(ctx, -1, "linkTimeout"); linkTO = duk_get_int(ctx, -1); duk_pop_2(ctx); AJ_SetBusLinkTimeout(aj, linkTO); } /* * timer clock must be initialized */ AJ_InitTimer(&timerClock); AJ_ASSERT(duk_get_top_index(ctx) == top); /* * Initialize About we can start sending announcements */ AJ_AboutInit(aj, AJS_APP_PORT); while (status == AJ_OK) { /* * Check we are cleaning up the duktape stack correctly. */ if (duk_get_top_index(ctx) != top) { AJ_ErrPrintf(("!!!AJS_MessageLoop top=%d expected %d\n", (int)duk_get_top_index(ctx), (int)top)); AJS_DumpStack(ctx); AJ_ASSERT(duk_get_top_index(ctx) == top); } AJS_SetWatchdogTimer(AJS_DEFAULT_WATCHDOG_TIMEOUT); /* * Pinned items (strings/buffers) are only valid while running script */ AJS_ClearPins(ctx); /* * Check if there are any pending I/O operations to perform. */ status = AJS_ServiceIO(ctx); if (status != AJ_OK) { AJ_ErrPrintf(("Error servicing I/O functions\n")); break; } /* * Services the internal and timeout timers and updates the timeout value for any new * timers that have been registered since this function was last called. */ status = AJS_RunTimers(ctx, &timerClock, &msgTO); if (status != AJ_OK) { AJ_ErrPrintf(("Error servicing timer functions\n")); break; } /* * Do any announcing required */ status = AJS_GetLockdownState(&ldstate); if (status == AJ_OK && ldstate == AJS_CONSOLE_UNLOCKED) { status = AJ_AboutAnnounce(aj); } if (status != AJ_OK) { break; } /* * This special wildcard allows us to unmarshal signals with any source path */ AJS_SetObjectPath("!"); /* * Block until a message is received, the timeout expires, or the operation is interrupted. */ status = AJ_UnmarshalMsg(aj, &msg, msgTO); if (status != AJ_OK) { if ((status == AJ_ERR_INTERRUPTED) || (status == AJ_ERR_TIMEOUT)) { status = AJ_OK; continue; } if (status == AJ_ERR_NO_MATCH) { status = AJ_OK; } AJ_CloseMsg(&msg); continue; } switch (msg.msgId) { case 0: /* If a message was parsed but is unrecognized and should be ignored */ break; /* Introspection messages */ case AJ_METHOD_PING: case AJ_METHOD_BUS_PING: case AJ_METHOD_GET_MACHINE_ID: case AJ_METHOD_INTROSPECT: case AJ_METHOD_GET_DESCRIPTION_LANG: case AJ_METHOD_INTROSPECT_WITH_DESC: /* About messages */ case AJ_METHOD_ABOUT_GET_PROP: case AJ_METHOD_ABOUT_SET_PROP: case AJ_METHOD_ABOUT_GET_ABOUT_DATA: case AJ_METHOD_ABOUT_GET_OBJECT_DESCRIPTION: case AJ_METHOD_ABOUT_ICON_GET_PROP: case AJ_METHOD_ABOUT_ICON_SET_PROP: case AJ_METHOD_ABOUT_ICON_GET_URL: case AJ_METHOD_ABOUT_ICON_GET_CONTENT: /* Authentication messages and replies */ case AJ_METHOD_EXCHANGE_GUIDS: case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GUIDS): case AJ_METHOD_EXCHANGE_SUITES: case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_SUITES): case AJ_METHOD_AUTH_CHALLENGE: case AJ_REPLY_ID(AJ_METHOD_AUTH_CHALLENGE): case AJ_METHOD_GEN_SESSION_KEY: case AJ_REPLY_ID(AJ_METHOD_GEN_SESSION_KEY): case AJ_METHOD_EXCHANGE_GROUP_KEYS: case AJ_REPLY_ID(AJ_METHOD_EXCHANGE_GROUP_KEYS): case AJ_METHOD_KEY_EXCHANGE: case AJ_REPLY_ID(AJ_METHOD_KEY_EXCHANGE): case AJ_METHOD_KEY_AUTHENTICATION: case AJ_REPLY_ID(AJ_METHOD_KEY_AUTHENTICATION): /* Replies the app ignores */ case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): case AJ_REPLY_ID(AJ_METHOD_REMOVE_MATCH): case AJ_REPLY_ID(AJ_METHOD_PING): case AJ_REPLY_ID(AJ_METHOD_BUS_PING): /* Signals the app ignores */ case AJ_SIGNAL_PROBE_ACK: case AJ_SIGNAL_PROBE_REQ: case AJ_SIGNAL_NAME_OWNER_CHANGED: status = AJ_BusHandleBusMessage(&msg); break; case AJ_METHOD_ACCEPT_SESSION: status = SessionDispatcher(ctx, &msg); break; case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): status = SessionBindReply(ctx, &msg); break; default: status = HandleMessage(ctx, ajIdx, &msg); break; } /* * Free message resources */ AJ_CloseMsg(&msg); /* * Decide which messages should cause us to exit */ switch (status) { case AJ_OK: break; case AJ_ERR_READ: case AJ_ERR_WRITE: case AJ_ERR_RESTART: case AJ_ERR_RESTART_APP: break; default: AJ_ErrPrintf(("Got error %s - continuing anyway\n", AJ_StatusText(status))); status = AJ_OK; } /* * Let link monitor know we are getting messages */ AJ_NotifyLinkActive(); /* * Perform any deferred operations. These are operations such as factory reset that cannot * be cleanly performed from inside duktape. */ if (status == AJ_OK) { status = DoDeferredOperation(ctx); } } AJS_ClearPins(ctx); AJS_ClearWatchdogTimer(); return status; }
int AJ_Main(void) { AJ_Status status = AJ_OK; /* Required: Need to initialize once before starting */ AJ_Initialize(); /* Required: Register the AppObjects before starting */ AJ_RegisterObjects(NULL, AppObjects); CPS_Init(); SetBusAuthPwdCallback(MyBusAuthPwdCB); while (TRUE) { /* AllJoyn related section */ AJ_Message msg; if (!isBusConnected) { status = CPS_StartService(&busAttachment, busAddress, CPSC_CONNECT_TIMEOUT, isBusConnected); } status = AJ_UnmarshalMsg(&busAttachment, &msg, CPSC_UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { // nothing on bus, do our own thing CPS_IdleConnectedHandler(&busAttachment); continue; } if (AJ_OK == status) { if (msg.msgId == AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION)) { if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("Could not connect session.\n")); } else { uint32_t replyCode; AJ_UnmarshalArgs(&msg, "uu", &replyCode, &sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { CPS_NotifySessionAccepted(sessionId, msg.sender); } } } else { if (CPS_MessageProcessor(&busAttachment, &msg, &status) == AJSVC_SERVICE_STATUS_NOT_HANDLED) { //pass to build in status = AJ_BusHandleBusMessage(&msg); } } } /* Messages MUST be discarded to free resources. */ AJ_CloseMsg(&msg); if (status == AJ_ERR_READ) { AJ_ErrPrintf(("AllJoyn disconnect.\n")); AJ_Disconnect(&busAttachment); isBusConnected = FALSE; /* Sleep a little while before trying to reconnect. */ AJ_Sleep(CPSC_SLEEP_TIME); } } AJ_InfoPrintf(("Control Panel Sample exiting with status 0x%04x.\n", status)); 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_StartService2(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, uint16_t port, const char* name, uint32_t flags, const AJ_SessionOpts* opts ) { AJ_Status status; AJ_Time timer; uint8_t serviceStarted = 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 service connected to bus\n")); } /* * Kick things off by binding a session port */ status = AJ_BusBindSessionPort(bus, port, opts); if (status == AJ_OK) { break; } AJ_ErrPrintf(("Failed to send bind session port message\n")); AJ_Disconnect(bus); } while (!serviceStarted && (status == AJ_OK)) { AJ_Message msg; AJ_GetElapsedTime(&timer, TRUE); status = AJ_UnmarshalMsg(bus, &msg, UNMARSHAL_TIMEOUT); /* * TODO This is a temporary hack to work around buggy select imlpementations */ if (status == AJ_ERR_TIMEOUT) { if (AJ_GetElapsedTime(&timer, TRUE) < UNMARSHAL_TIMEOUT) { AJ_WarnPrintf(("Spurious timeout error - continuing\n")); status = AJ_OK; continue; } } if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_BusRequestName(bus, name, flags); } break; case AJ_REPLY_ID(AJ_METHOD_REQUEST_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_BusAdvertiseName(bus, name, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING); } break; case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { serviceStarted = TRUE; AJ_BusSetSignalRule2(bus, "NameOwnerChanged", "org.freedesktop.DBus", AJ_BUS_SIGNAL_ALLOW); } 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; }
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(void) { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint8_t done = FALSE; uint32_t sessionId = 0; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(NULL, AppObjects); 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; status = AJ_BusAddSignalRule(&bus, "nameChanged", InterfaceName, AJ_BUS_SIGNAL_ALLOW); } else { AJ_InfoPrintf(("StartClient returned 0x%04x.\n", status)); break; } } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { continue; } switch (status) { case AJ_OK: /* * The contents of the message are meaningful, only when * the message was unmarshaled successfully. */ switch (msg.msgId) { case NAMECHANGE_SIGNAL: ReceiveNewName(&msg); break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): AJ_InfoPrintf(("JoinSession SUCCESS (Session id=%d).\n", sessionId)); 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; } break; case AJ_ERR_NULL: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Unexpected NULL pointer'.\n")); break; case AJ_ERR_UNEXPECTED: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An operation was unexpected at this time'.\n")); break; case AJ_ERR_INVALID: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'A value was invalid'.\n")); break; case AJ_ERR_IO_BUFFER: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An I/O buffer was invalid or in the wrong state'.\n")); break; case AJ_ERR_READ: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An error while reading data from the network'.\n")); break; case AJ_ERR_WRITE: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An error while writing data to the network'.\n")); break; case AJ_ERR_TIMEOUT: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'A timeout occurred'.\n")); break; case AJ_ERR_MARSHAL: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Marshaling failed due to badly constructed message argument'.\n")); break; case AJ_ERR_UNMARSHAL: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Unmarshaling failed due to a corrupt or invalid message'.\n")); break; case AJ_ERR_END_OF_DATA: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'No enough data'.\n")); break; case AJ_ERR_RESOURCES: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Insufficient memory to perform the operation'.\n")); break; case AJ_ERR_NO_MORE: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Attempt to unmarshal off the end of an array'.\n")); break; case AJ_ERR_SECURITY: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Authentication or decryption failed'.\n")); break; case AJ_ERR_CONNECT: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Network connect failed'.\n")); break; case AJ_ERR_UNKNOWN: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'A unknown value'.\n")); break; case AJ_ERR_NO_MATCH: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Something didn't match'.\n")); break; case AJ_ERR_SIGNATURE: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'Signature is not what was expected'.\n")); break; case AJ_ERR_DISALLOWED: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An operations was not allowed'.\n")); break; case AJ_ERR_FAILURE: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'A failure has occured'.\n")); break; case AJ_ERR_RESTART: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'The OEM event loop must restart'.\n")); break; case AJ_ERR_LINK_TIMEOUT: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'The bus link is inactive too long'.\n")); break; case AJ_ERR_DRIVER: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned 'An error communicating with a lower-layer driver'.\n")); break; case AJ_ERR_SESSION_LOST: AJ_ErrPrintf(("The session was lost\n")); break; default: AJ_ErrPrintf(("AJ_UnmarshalMsg() returned '%s'.\n", AJ_StatusText(status))); break; } /* Messages MUST be discarded to free resources. */ AJ_CloseMsg(&msg); if (status == AJ_ERR_SESSION_LOST) { AJ_AlwaysPrintf(("AllJoyn disconnect.\n")); AJ_Disconnect(&bus); exit(0); } } AJ_AlwaysPrintf(("signalConsumer_Client exiting with status 0x%04x.\n", status)); 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; }