/// <summary> /// Invoked whenever a 'Stream Initiation' request for file transfers /// is received. /// </summary> /// <param name="from">The JID of the XMPP entity that wishes to initiate /// the data-stream.</param> /// <param name="si">The 'si' element of the request.</param> /// <param name="result">The response to the SI request or an error element to include /// in the IQ response.</param> private void OnStreamInitiationRequest(Jid from, XmlElement si, Action <XmlElement> result) { try { string method = SelectStreamMethod(si["feature"]); // If the session-id is already in use, we cannot process the request. string sid = si.GetAttribute("id"); if (String.IsNullOrEmpty(sid) || siSessions.ContainsKey(sid)) { result(new XmppError(ErrorType.Cancel, ErrorCondition.Conflict).Data); } // Extract file information and hand to user. var file = si["file"]; string desc = file["desc"] != null ? file["desc"].InnerText : null, name = file.GetAttribute("name"); int size = int.Parse(file.GetAttribute("size")); FileTransfer transfer = new FileTransfer(from, im.Jid, name, size, sid, desc); TransferRequest.Invoke(transfer, (string savePath) => { try { // User has rejected the request. if (savePath == null) { result(new XmppError(ErrorType.Cancel, ErrorCondition.NotAcceptable).Data); } else { // Create an SI session instance. SISession session = new SISession(sid, File.OpenWrite(savePath), size, true, from, im.Jid, im.GetExtension(method) as IDataStream); siSessions.TryAdd(sid, session); // Store the file's meta data. metaData.TryAdd(sid, new FileMetaData(name, desc)); // Construct and return the negotiation result. result(Xml.Element("si", "http://jabber.org/protocol/si").Child( FeatureNegotiation.Create(new SubmitForm( new ListField("stream-method", method))))); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Exception raised", e.ToString() + e.StackTrace); result(new XmppError(ErrorType.Cancel, ErrorCondition.BadRequest).Data); } }); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Exception raised", e.ToString() + e.StackTrace); result(new XmppError(ErrorType.Cancel, ErrorCondition.BadRequest).Data); } }