int AJ_Main() { AJ_Status status; AJ_BusAttachment bus; AJ_Initialize(); status = AJ_FindBusAndConnect(&bus, NULL, CONNECT_TIMEOUT); if (status == AJ_OK) { status = AJ_BusRequestName(&bus, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE); } while (status == AJ_OK) { AJ_Message msg; status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (status == AJ_OK) { status = AJ_BusHandleBusMessage(&msg); } AJ_CloseMsg(&msg); } return 0; }
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; }
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; }
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; }