UtlBoolean SipSubscribeServerEventHandler::getNotifyContent(const UtlString& resourceId, const UtlString& eventTypeKey, const UtlString& eventType, SipPublishContentMgr& contentMgr, const char* acceptHeaderValue, SipMessage& notifyRequest, int& version) { UtlBoolean gotBody = FALSE; // Default behavior is to just go get the content from // the content manager and attach it to the notify HttpBody* messageBody = NULL; UtlBoolean isDefaultEventContent; gotBody = contentMgr.getContent(resourceId, eventTypeKey, eventType, acceptHeaderValue, messageBody, version, isDefaultEventContent); // The body will be freed with the NOTIFY message. if(messageBody) { const char* contentTypePtr = messageBody->getContentType(); UtlString contentType; if(contentTypePtr) { contentType = contentTypePtr; } else { OsSysLog::add(FAC_SIP, PRI_ERR, "SipSubscribeServerEventHandler::getNotifyContent body published for resourceId: '%s' eventTypeKey: '%s' with no content type", resourceId.data() ? resourceId.data() : "<null>", eventTypeKey.data() ? eventTypeKey.data() : "<null>"); contentType = "text/unknown"; } notifyRequest.setContentType(contentType); notifyRequest.setBody(messageBody); UtlString request; ssize_t requestLength; notifyRequest.getBytes(&request, &requestLength); OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipSubscribeServerEventHandler::getNotifyContent resourceId '%s', eventTypeKey '%s' contentType '%s' NOTIFY message length = %zu, message = '%s'", resourceId.data(), eventTypeKey.data(), contentType.data(), requestLength, request.data()); } return(gotBody); }
void subscribeMwiClientTest() { smClientExpiration = -1; smNumClientNotifiesReceived = 0; smLastClientNotifyReceived = NULL; smNumClientSubResponsesReceived = 0; smLastClientSubResponseReceived = NULL; UtlString resourceId("[email protected]:"); UtlString eventTypeKey("message-summary"); UtlString eventType(eventTypeKey); UtlString from("Frida<sip:111@localhost:"); UtlString to("Tia<sip:222@localhost:"); UtlString contact("sip:[email protected]:"); char portString[20]; sprintf(portString, "%d", UNIT_TEST_SIP_PORT); resourceId.append(portString); from.append(portString); from.append('>'); to.append(portString); to.append('>'); contact.append(portString); SipUserAgent* userAgent = new SipUserAgent(UNIT_TEST_SIP_PORT, UNIT_TEST_SIP_PORT); userAgent->start(); // Set up the subscribe client SipDialogMgr* clientDialogMgr = new SipDialogMgr(); SipRefreshManager* refreshMgr = new SipRefreshManager(*userAgent, *clientDialogMgr); refreshMgr->start(); SipSubscribeClient* subClient = new SipSubscribeClient(*userAgent, *clientDialogMgr, *refreshMgr); subClient->start(); // Set up the subscribe server SipSubscribeServer* subServer = SipSubscribeServer::buildBasicServer(*userAgent, eventType); SipSubscriptionMgr* subMgr = subServer->getSubscriptionMgr(eventType); SipDialogMgr* serverDialogMgr = subMgr->getDialogMgr(); SipPublishContentMgr* contentMgr = subServer->getPublishMgr(eventType); HttpBody* preexistingBodyPtr = NULL; UtlBoolean isDefaultContent; subServer->start(); // Enable the handler for the MWI server subServer->enableEventType(eventType, userAgent); //CPPUNIT_ASSERT(TRUE); //ASSERT_STR_EQUAL("a", "a"); // Create a crude Subscription server/observer OsMsgQ incomingServerMsgQueue; // Register an interest in SUBSCRIBE requests // for this event type userAgent->addMessageObserver(incomingServerMsgQueue, SIP_SUBSCRIBE_METHOD, TRUE, // requests FALSE, // no reponses TRUE, // incoming FALSE, // no outgoing eventType, NULL, NULL); OsMsgQ incomingClientMsgQueue; userAgent->addMessageObserver(incomingClientMsgQueue, SIP_SUBSCRIBE_METHOD, FALSE, // no requests TRUE, // reponses TRUE, // incoming FALSE, // no outgoing eventType, NULL, NULL); // Should not be any pre-existing content CPPUNIT_ASSERT(!contentMgr->getContent(resourceId, eventTypeKey, NULL, preexistingBodyPtr, isDefaultContent)); int numDefaultContent = -1; int numResourceSpecificContent = -1; int numCallbacksRegistered = -1; contentMgr->getStats(numDefaultContent, numResourceSpecificContent, numCallbacksRegistered); CPPUNIT_ASSERT(numDefaultContent == 0); CPPUNIT_ASSERT(numResourceSpecificContent == 0); CPPUNIT_ASSERT(numCallbacksRegistered == 1); // Create a subscribe request, send it and keep it refreshed UtlString earlyDialogHandle; CPPUNIT_ASSERT(subClient->addSubscription(resourceId, eventType, from, to, contact, 60, // seconds expiration this, subStateCallback, notifyCallback, earlyDialogHandle)); contentMgr->getStats(numDefaultContent, numResourceSpecificContent, numCallbacksRegistered); CPPUNIT_ASSERT(numDefaultContent == 0); CPPUNIT_ASSERT(numResourceSpecificContent == 0); CPPUNIT_ASSERT(numCallbacksRegistered == 1); // See if a subscribe was sent and received /*OsTime messageTimeout(5, 0); // 5 seconds OsMsg* osMessage = NULL; const SipMessage* subscribeResponse = NULL; const SipMessage* notifyRequest = NULL; incomingServerMsgQueue.receive(osMessage, messageTimeout); CPPUNIT_ASSERT(osMessage); int msgType = osMessage->getMsgType(); int msgSubType = osMessage->getMsgSubType(); CPPUNIT_ASSERT(msgType == OsMsg::PHONE_APP); CPPUNIT_ASSERT(msgSubType == SipMessage::NET_SIP_MESSAGE); const SipMessage* sipMessage = ((SipMessageEvent*)osMessage)->getMessage(); int messageType = ((SipMessageEvent*)osMessage)->getMessageStatus(); CPPUNIT_ASSERT(sipMessage); CPPUNIT_ASSERT(messageType == SipMessageEvent::APPLICATION);*/ const SipMessage* serverSideSubRequest = NULL; CPPUNIT_ASSERT(removeMessage(incomingServerMsgQueue, 5000, // milliseconds serverSideSubRequest)); CPPUNIT_ASSERT(serverSideSubRequest); // Sub request got to server const SipMessage* clientSideSubResponse = NULL; CPPUNIT_ASSERT(removeMessage(incomingClientMsgQueue, 5000, // milliseconds clientSideSubResponse)); CPPUNIT_ASSERT(clientSideSubResponse); //UtlString clientStateString; //subClient->dumpStates(clientStateString); //printf("client states:\n%s\n", clientStateString.data()); int waitIterations = 0; while(smLastClientNotifyReceived == NULL || smLastClientSubResponseReceived == NULL) { OsTask::delay(100); waitIterations++; if(waitIterations >= 100) { break; } } CPPUNIT_ASSERT(smLastClientSubResponseReceived); CPPUNIT_ASSERT(smLastClientNotifyReceived); SipMessage* firstSubResponse = smLastClientSubResponseReceived; smLastClientSubResponseReceived = NULL; int firstSubCseq; firstSubResponse->getCSeqField(&firstSubCseq, NULL); SipMessage* firstNotifyRequest = smLastClientNotifyReceived; smLastClientNotifyReceived = NULL; int firstNotifyCseq; firstNotifyRequest->getCSeqField(&firstNotifyCseq, NULL); CPPUNIT_ASSERT(firstSubCseq == 1); CPPUNIT_ASSERT(firstNotifyCseq == 0); //subClient->dumpStates(clientStateString); //printf("client states:\n%s\n", clientStateString.data()); //UtlString dialogMgrDumpString; //clientDialogMgr.toString(dialogMgrDumpString); //printf("Client Dialog manager dump 1:\n%s\n", // dialogMgrDumpString.data()); // The refresh manager should re-SUBSCRIBE // Wait for the next notify request and subscribe response int secondMessageWait = 60; int resendTimeout = 0.55 * secondMessageWait; if(resendTimeout < 40) { resendTimeout = 40; } for(int i = 0; i < secondMessageWait - 1; i++) { if(i == resendTimeout - 1) { printf("v"); } else { printf("="); } } printf("v\n"); SipMessage* secondSubResponse = NULL; SipMessage* secondNotifyRequest = NULL; while(secondNotifyRequest == NULL || secondSubResponse == NULL) { OsTask::delay(1000); if(smLastClientSubResponseReceived) { secondSubResponse = smLastClientSubResponseReceived; smLastClientSubResponseReceived = NULL; } if(smLastClientNotifyReceived) { secondNotifyRequest = smLastClientNotifyReceived; smLastClientNotifyReceived = NULL; } printf("."); waitIterations++; if(waitIterations >= secondMessageWait) { printf("\n"); break; } } //subClient->dumpStates(clientStateString); //printf("client states:\n%s\n", clientStateString.data()); //clientDialogMgr.toString(dialogMgrDumpString); //printf("Client Dialog manager dump 2:\n%s\n", // dialogMgrDumpString.data()); CPPUNIT_ASSERT(removeMessage(incomingServerMsgQueue, 5000, // milliseconds serverSideSubRequest)); CPPUNIT_ASSERT(serverSideSubRequest); // Sub request got to server //UtlString subRequestDump; //int len; //serverSideSubRequest->getBytes(&subRequestDump, &len); //printf("server side sub request:\n%s\n", // subRequestDump.data()); CPPUNIT_ASSERT(removeMessage(incomingClientMsgQueue, 5000, // milliseconds clientSideSubResponse)); CPPUNIT_ASSERT(clientSideSubResponse); // Sub respon got to client //UtlString subResponseDump; //clientSideSubResponse->getBytes(&subResponseDump, &len); //printf("client side sub response:\n%s\n", // subResponseDump.data()); CPPUNIT_ASSERT(secondNotifyRequest); CPPUNIT_ASSERT(secondSubResponse); int secondSubCseq = -1; int secondNotifyCseq = -1; smLastClientSubResponseReceived = NULL; secondSubResponse->getCSeqField(&secondSubCseq, NULL); smLastClientNotifyReceived = NULL; secondNotifyRequest->getCSeqField(&secondNotifyCseq, NULL); CPPUNIT_ASSERT(firstSubCseq < secondSubCseq); CPPUNIT_ASSERT(firstNotifyCseq < secondNotifyCseq); // Unregister the queues so we stop receiving messages on them userAgent->removeMessageObserver(incomingServerMsgQueue); userAgent->removeMessageObserver(incomingClientMsgQueue); refreshMgr->requestShutdown(); subClient->requestShutdown(); }