protected virtual void OnVolumeRequested(VolumeRequestedEventArgs e) { if (VolumeRequested != null) { VolumeRequested(this, e); } }
protected override HttpResponse HandleRequest(HttpRequest request) { HttpResponse response = new HttpResponse("RTSP/1.0"); //iTunes wants to know we are legit before it will even authenticate string challengeResponse = getChallengeResponse(request); if (challengeResponse != null) { response.SetHeader("Apple-Response", challengeResponse); } if (IsAuthorised(request)) { response.Status = "200 OK"; response.SetHeader("Audio-Jack-Status", "connected; type=analog"); response.SetHeader("CSeq", request.GetHeader("CSeq")); } else { response.Status = "401 UNAUTHORIZED"; response.SetHeader("WWW-Authenticate", string.Format("Digest realm=\"{0}\" nonce=\"{1}\"", DIGEST_REALM, nonce)); response.SetHeader("Method", "DENIED"); return(response); } string requestType = request.Method; if (requestType == "OPTIONS") { response.SetHeader("Public", "ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER"); } else if (requestType == "ANNOUNCE") { initRemoteHandler(request); getSessionParams(request); } else if (requestType == "SETUP") { int port; if (setupAudioServer(request, out port)) { response.SetHeader("Transport", string.Format("RTP/AVP/UDP;unicast;mode=record;x-events;server_port={0};control_port={0};timing_port={0}", port)); response.SetHeader("Session", "1"); } } else if (requestType == "RECORD") { // Headers // Range: ntp=0- // RTP-Info: seq={Note 1};rtptime={Note 2} // Note 1: Initial value for the RTP Sequence Number, random 16 bit value // Note 2: Initial value for the RTP Timestamps, random 32 bit value response.SetHeader("Audio-Latency", "44100"); } else if (requestType == "FLUSH") { lock (audioServerLock) if (audioServer != null) { audioServer.Buffer.Flush(); } } else if (requestType == "TEARDOWN") { Logger.Debug("RAOPSession: TEARDOWN received"); response.SetHeader("Connection", "close"); } else if (requestType == "SET_PARAMETER") { string contentType = request.GetHeader("Content-Type"); if (contentType == null) { Logger.Debug("RAOPSession: Empty Content-Type\r\n{0}", request.ToString()); } if (contentType == "application/x-dmap-tagged") { Logger.Debug("RAOPSession: Received metadata"); OnMetaDataChanged(new MetaDataChangedEventArgs(new DmapData(request.Content), request.Uri)); } else if (contentType != null && contentType.StartsWith("image/")) { Logger.Debug("RAOPSession: Received cover art"); OnArtworkChanged(new ArtwokChangedEventArgs(request.Content, contentType, request.Uri)); } else { handleParameterString(request); } } else if (requestType == "GET_PARAMETER") { bool handled = false; if (request["Content-Type"] == "text/parameters") { if (request.GetContentString().StartsWith("volume")) { handled = true; Logger.Debug("RAOPSession: Client requested volume"); VolumeRequestedEventArgs e = new VolumeRequestedEventArgs(request.Uri); OnVolumeRequested(e); response["Content-Type"] = "text/parameters"; response.SetContent(string.Format(CultureInfo.InvariantCulture, "volume: {0}", e.Volume)); } } if (!handled) { Logger.Debug("Unhandled GET_PARAMETER request\r\n{0}", request.ToString()); } } else { //Unsupported Logger.Debug("RAOPSession: Unsupported request type: {0}", requestType); Logger.Debug(request.ToString()); } return(response); }