Example #1
0
/*----------------------------------------------------------------------
|    PLT_SsdpListenTask::DoInit
+---------------------------------------------------------------------*/
void
PLT_SsdpListenTask::DoInit() 
{
    if (m_Multicast) {
        if (m_JoinHard) {
            NPT_List<NPT_IpAddress> ips;
            PLT_UPnPMessageHelper::GetIPAddresses(ips);

            /* Join multicast group for every ip we found */
            ips.Apply(PLT_SsdpInitMulticastIterator((NPT_UdpMulticastSocket*)m_Socket));
        } else {
            NPT_IpAddress addr;
            addr.ResolveName("239.255.255.250");
            ((NPT_UdpMulticastSocket*)m_Socket)->JoinGroup(addr, NPT_IpAddress::Any);
        }
    }
}
Example #2
0
void FrontEnd::broadcastLocked(DeviceImplInfo *deviceInfo, bool avail)
{
	NPT_TimeStamp ts;
	NPT_System::GetCurrentTimeStamp(ts);

	NPT_List<MatchContext*> matchList;

	if (deviceInfo) {
		deviceInfo->m_updateTS = ts;
		MatchContext *matchContext = new MatchContext();
		if (deviceInfo->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
			matchList.Add(matchContext);
			matchContext->deviceUuid = deviceInfo->m_deviceImpl->uuid();
			matchContext->expireSeconds = deviceInfo->m_deviceImpl->m_expireSeconds;
			matchContext->descPath = deviceInfo->m_deviceImpl->m_descPath;
			matchContext->httpRoot = deviceInfo->m_context.m_httpRoot;
		} else {
			delete matchContext;
		}
	} else {
		for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
			NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
			DeviceImplInfo *info = *it;
			info->m_updateTS = ts;
			MatchContext *matchContext = new MatchContext();
			if (info->m_deviceImpl->match("ssdp:all", matchContext->matches)) {
				matchList.Add(matchContext);
				matchContext->deviceUuid = info->m_deviceImpl->uuid();
				matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
				matchContext->descPath = info->m_deviceImpl->m_descPath;
				matchContext->httpRoot = info->m_context.m_httpRoot;
			} else {
				delete matchContext;
			}
		}
	}

	NPT_SocketAddress targetAddr(NPT_IpAddress(239, 255, 255, 250), 1900);

	for (NPT_Ordinal i = 0; i < m_ifList.GetItemCount(); i++) {
		Interface *nif = *m_ifList.GetItem(i);
		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(nif->m_context.m_ifAddr, 0));
		for (NPT_Ordinal j = 0; j < matchList.GetItemCount(); j++) {
			MatchContext *matchContext = *matchList.GetItem(j);
			NPT_String location = NPT_String::Format("http://%s:%d%s%s", nif->m_context.m_ifAddr.ToString().GetChars(), nif->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());
			for (NPT_Ordinal k = 0; k < matchContext->matches.GetItemCount(); k++) {
				NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(k);
				NPT_String msg;
				if (avail) {
					//msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\n\r\n",
					//		matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars());
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=%d\r\nLOCATION: %s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											matchContext->expireSeconds, location.GetChars(), it2->m_st.GetChars(), m_serverHeader.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				} else {
					msg = NPT_String::Format("NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nNT: %s\r\nNTS: ssdp:byebye\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
											it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
				}
				NPT_DataBuffer packet(msg.GetChars(), msg.GetLength(), false);
				sock.Send(packet, &targetAddr);
			}
		}
	}

	matchList.Apply(NPT_ObjectDeleter<MatchContext>());
}
Example #3
0
void FrontEnd::processSsdpSearch(SsdpServerTask *task, Interface *intf, const NPT_DataBuffer& data, const NPT_SocketAddress& fromAddr)
{
	do {
		NPT_HttpRequest *req;
		NPT_InputStreamReference inputStream0(new NPT_MemoryStream(data.GetData(), data.GetDataSize()));
		NPT_BufferedInputStream inputStream(inputStream0);
		if (NPT_FAILED(NPT_HttpRequest::Parse(inputStream, NULL, req))) {
			break;
		}

		PtrHolder<NPT_HttpRequest> req1(req);
		if (req->GetMethod().Compare("M-SEARCH") != 0 || req->GetProtocol().Compare(NPT_HTTP_PROTOCOL_1_1) != 0 || req->GetUrl().GetPath().Compare("*") != 0) {
			break;
		}

		NPT_HttpHeader *hdrMan = req->GetHeaders().GetHeader("MAN");
		if (!hdrMan || hdrMan->GetValue().Compare("\"ssdp:discover\"") != 0) {
			break;
		}

		NPT_HttpHeader *hdrHost = req->GetHeaders().GetHeader("HOST");
		if (!hdrHost || (hdrHost->GetValue().Compare("239.255.255.250:1900") != 0 && hdrHost->GetValue().Compare("239.255.255.250") != 0)) {
			break;
		}

		int mx;
		NPT_HttpHeader *hdrMX = req->GetHeaders().GetHeader("MX");
		if (!hdrMX || NPT_FAILED(NPT_ParseInteger(hdrMX->GetValue(), mx)) || mx < 1) {
			break;
		}

		if (mx > 120) {
			mx = 120;
		}

		NPT_HttpHeader *hdrST = req->GetHeaders().GetHeader("ST");
		if (!hdrST) {
			break;
		}

		NPT_List<MatchContext*> matchList;

		NPT_UdpSocket sock(NPT_SOCKET_FLAG_CANCELLABLE);
		sock.Bind(NPT_SocketAddress(intf->m_context.m_ifAddr, 0));
		NPT_SharedVariable waitVar;
		waitVar.SetValue(0);

		{
			ReadLocker locker(m_dsLock);
			for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) {
				NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i);
				DeviceImplInfo *info = *it;
				MatchContext *matchContext = new MatchContext();
				if (info->m_deviceImpl->match(hdrST->GetValue(), matchContext->matches)) {
					matchList.Add(matchContext);
					matchContext->deviceUuid = info->m_deviceImpl->uuid();
					matchContext->expireSeconds = info->m_deviceImpl->m_expireSeconds;
					matchContext->descPath = info->m_deviceImpl->m_descPath;
					matchContext->httpRoot = info->m_context.m_httpRoot;
				} else {
					delete matchContext;
				}
			}
		}

		SsdpSearchAbortCallback abortCallback(&sock, &waitVar);
		if (task->registerAbortCallback(&abortCallback)) {

			for (NPT_Ordinal i = 0; i < matchList.GetItemCount(); i++) {
				MatchContext *matchContext = *matchList.GetItem(i);

				NPT_String location = NPT_String::Format("http://%s:%d%s%s", intf->m_context.m_ifAddr.ToString().GetChars(), intf->m_context.m_httpPort, matchContext->httpRoot.GetChars(), matchContext->descPath.GetChars());

				bool broken = false;

				for (NPT_Ordinal j = 0; j < matchContext->matches.GetItemCount(); j++) {
					NPT_List<DeviceImplMatch>::Iterator it2 = matchContext->matches.GetItem(j);

					NPT_Timeout timeout = NPT_System::GetRandomInteger() % (mx * 1000);
					// TODO: wait or not ???
					timeout = 0;
					if (NPT_SUCCEEDED(waitVar.WaitWhileEquals(0, timeout))) {
						break;
					}

					{
						ReadLocker locker(m_dsLock);
						if (m_deviceImplIndex.HasKey(matchContext->deviceUuid)) {
							NPT_TimeStamp ts;
							NPT_System::GetCurrentTimeStamp(ts);
							NPT_String dateStr = NPT_DateTime(ts).ToString(NPT_DateTime::FORMAT_RFC_1123);
							NPT_String resp = NPT_String::Format("HTTP/1.1 200 OK\r\nCACHE-CONTROL: max-age=%d\r\nDATE: %s\r\nEXT: \r\nLOCATION: %s\r\nSERVER: %s\r\nST: %s\r\nUSN: %s\r\nCUSTOM:%s\r\n\r\n",
														matchContext->expireSeconds, dateStr.GetChars(), location.GetChars(), m_serverHeader.GetChars(), it2->m_st.GetChars(), it2->m_usn.GetChars(), m_DevName.GetChars());
							NPT_DataBuffer packet(resp.GetChars(), resp.GetLength(), false);
							sock.Send(packet, &fromAddr);
						}
					}
				}

				if (broken) {
					break;
				}
			}

			task->unregisterAbortCallback(&abortCallback);
		}

		matchList.Apply(NPT_ObjectDeleter<MatchContext>());
	} while (false);
}