/// <summary> /// This action retrieves the value of the external IP address on this connection instance. /// </summary> /// <returns>External IP</returns> public System.Net.IPAddress GetExternalIPAddress(IUPnPUpdater upnp) { UPnPFunction func = new UPnPFunction(); func.Name = "GetExternalIPAddress"; func.Service = this; func.Arguments.Add("NewExternalIPAddress", string.Empty); FmdcEventArgs e = new FmdcEventArgs(Actions.UPnPFunctionCall, func); upnp.FireUpdateBase(e); if (e.Handled) { func = e.Data as UPnPFunction; if (func != null) { try { return(System.Net.IPAddress.Parse(func.Arguments["NewExternalIPAddress"])); } catch { } } } return(null); }
/// <summary> /// This action deletes a previously instantiated port mapping. /// As each entry is deleted, the array is compacted, and the evented variable PortMappingNumberOfEntries is decremented. /// </summary> /// <param name="upnp"></param> /// <returns></returns> public bool DeletePortMapping(IUPnPUpdater upnp, PortMapping mapping) { UPnPFunction func = new UPnPFunction(); func.Name = "DeletePortMapping"; func.Service = this; func.Arguments.Add("NewRemoteHost", (mapping.RemoteHost != null ? mapping.RemoteHost : string.Empty)); func.Arguments.Add("NewExternalPort", mapping.ExternalPort.ToString()); func.Arguments.Add("NewProtocol", mapping.Protocol); FmdcEventArgs e = new FmdcEventArgs(Actions.UPnPFunctionCall, func); upnp.FireUpdateBase(e); return(e.Handled); }
public bool AddPortMapping(IUPnPUpdater upnp, PortMapping mapping) { UPnPFunction func = new UPnPFunction(); func.Name = "AddPortMapping"; func.Service = this; func.Arguments.Add("NewRemoteHost", (mapping.RemoteHost != null ? mapping.RemoteHost : string.Empty)); func.Arguments.Add("NewExternalPort", mapping.ExternalPort.ToString()); func.Arguments.Add("NewProtocol", mapping.Protocol); func.Arguments.Add("NewInternalPort", mapping.InternalPort.ToString()); func.Arguments.Add("NewInternalClient", mapping.InternalHost); func.Arguments.Add("NewEnabled", (mapping.Enable ? "1" : "0")); func.Arguments.Add("NewPortMappingDescription", mapping.Description); func.Arguments.Add("NewLeaseDuration", mapping.LeaseDuration.ToString()); FmdcEventArgs e = new FmdcEventArgs(Actions.UPnPFunctionCall, func); upnp.FireUpdateBase(e); return(e.Handled); }
public void ActOnOutMessage(FlowLib.Events.FmdcEventArgs e) { string key = null; UPnPDevice device = null; switch (e.Action) { case Actions.UPnPDeviceDescription: key = e.Data as string; if (key != null) { try { if (con.RootDevices.ContainsKey(key)) { device = con.RootDevices[key]; System.Net.HttpWebRequest httpRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(device.Information.DescriptionURL); WebResponse webResponse = httpRequest.GetResponse(); System.IO.StreamReader sr = new System.IO.StreamReader(webResponse.GetResponseStream()); string ret = sr.ReadToEnd(); sr.Close(); FmdcEventArgs e2 = new FmdcEventArgs(Actions.UPnPDeviceDescription, ret); Update(con, e2); if (!e2.Handled) { ParseDescription(ref device, ret); Update(con, new FmdcEventArgs(Actions.UPnPDeviceUpdated, device)); } } } catch (System.Exception) { // TODO: Make exception handling } } break; case Actions.UPnPFunctionCall: UPnPFunction func = e.Data as UPnPFunction; if (func != null) { try { #region Create Envelope System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append("<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"); sb.Append("<s:Body>"); sb.Append("<u:" + func.Name + " xmlns:u=\"" + func.Service.Information.serviceType + "\">"); foreach (KeyValuePair <string, string> argument in func.Arguments) { sb.AppendFormat("<{0}>{1}</{0}>", argument.Key, argument.Value); } sb.Append("</u:" + func.Name + ">"); sb.Append("</s:Body>"); sb.Append("</s:Envelope>"); #endregion #region Create Request byte[] body = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); string url = null; // Is ControlURL relative or absolute? if (func.Service.Information.ControlURL.StartsWith("/")) { url = "http://" + func.Service.Device.Information.URLBase + func.Service.Information.ControlURL; } else { url = func.Service.Information.ControlURL; } WebRequest wr = WebRequest.Create(url); //+ controlUrl); wr.Headers.Clear(); wr.Method = "POST"; wr.ContentType = "text/xml; charset=\"utf-8\""; wr.Headers.Add("SOAPAction", "\"" + func.Service.Information.serviceType + "#" + func.Name + "\""); wr.ContentLength = body.Length; #endregion #region Call Service function // TODO: Add error handling in this (If server returns code 500 or something) System.IO.Stream stream = wr.GetRequestStream(); stream.Write(body, 0, body.Length); stream.Flush(); stream.Close(); WebResponse wres = wr.GetResponse(); System.IO.StreamReader sr = new System.IO.StreamReader(wres.GetResponseStream()); string xml = sr.ReadToEnd(); sr.Close(); #endregion #region Parse returning data XmlDocument document = new XmlDocument(); document.LoadXml(xml); SortedList <string, string> tmpList = new SortedList <string, string>(func.Arguments); foreach (KeyValuePair <string, string> argument in func.Arguments) { XmlNodeList nodes = document.GetElementsByTagName(argument.Key); if (nodes.Count == 1) { tmpList[argument.Key] = nodes[0].InnerText; } } func.Arguments = tmpList; #endregion #region Return data e.Data = func; e.Handled = true; #endregion } catch (System.Net.WebException webEx) { HttpWebResponse resp = webEx.Response as HttpWebResponse; if (resp != null) { func.ErrorCode = (int)resp.StatusCode; } e.Data = func; } catch { // TODO: Add more specific error handling here } } break; } }
/// <summary> /// This action retrieves NAT port mappings one entry at a time. Control points can call this action /// with an incrementing array index until no more entries are found on the gateway. If /// PortMappingNumberOfEntries is updated during a call, the process may have to start over. /// Entries in the array are contiguous. As entries are deleted, the array is compacted, and the /// evented variable PortMappingNumberOfEntries is decremented. Port mappings are logically /// stored as an array on the IGD and retrieved using an array index ranging from 0 to /// PortMappingNumberOfEntries-1. /// </summary> /// <param name="index"></param> /// <returns></returns> public PortMapping GetGenericPortMappingEntry(IUPnPUpdater upnp, int index) { PortMapping mapping = new PortMapping(); UPnPFunction func = new UPnPFunction(); func.Name = "GetSpecificPortMappingEntry"; func.Service = this; func.Arguments.Add("NewPortMappingIndex", index.ToString()); func.Arguments.Add("NewRemoteHost", string.Empty); func.Arguments.Add("NewExternalPort", string.Empty); func.Arguments.Add("NewProtocol", string.Empty); func.Arguments.Add("NewInternalPort", string.Empty); func.Arguments.Add("NewInternalClient", string.Empty); func.Arguments.Add("NewEnabled", string.Empty); func.Arguments.Add("NewPortMappingDescription", string.Empty); func.Arguments.Add("NewLeaseDuration", string.Empty); FmdcEventArgs e = new FmdcEventArgs(Actions.UPnPFunctionCall, func); upnp.FireUpdateBase(e); if (e.Handled) { func = e.Data as UPnPFunction; if (func != null) { string str = func.Arguments["NewRemoteHost"]; if (!string.IsNullOrEmpty(str)) { mapping.RemoteHost = str; } str = func.Arguments["NewExternalPort"]; if (!string.IsNullOrEmpty(str)) { try { mapping.ExternalPort = int.Parse(str); } catch { } } str = func.Arguments["NewProtocol"]; if (!string.IsNullOrEmpty(str)) { mapping.Protocol = str; } str = func.Arguments["NewInternalPort"]; if (!string.IsNullOrEmpty(str)) { try { mapping.InternalPort = int.Parse(str); } catch { } } str = func.Arguments["NewInternalClient"]; if (!string.IsNullOrEmpty(str)) { mapping.InternalHost = str; } str = func.Arguments["NewEnabled"]; if (!string.IsNullOrEmpty(str)) { switch (str) { case "1": mapping.Enable = true; break; case "0": mapping.Enable = false; break; } } str = func.Arguments["NewPortMappingDescription"]; if (!string.IsNullOrEmpty(str)) { mapping.Description = str; } str = func.Arguments["NewLeaseDuration"]; if (!string.IsNullOrEmpty(str)) { try { mapping.LeaseDuration = int.Parse(str); } catch { } } return(mapping); } } return(null); }