public AdvertisementWrapper( WiFiDirectServiceAdvertiser advertiser, WiFiDirectServiceManager manager, string pin = "" ) { this.advertiser = advertiser; this.manager = manager; // Store PIN for "display" config method this.pin = pin; uniqueInternalId = nextId++; // This should fire when the service is created and advertisement has started // It will also fire when the advertisement has stopped for any reason this.advertiser.AdvertisementStatusChanged += OnAdvertisementStatusChanged; // This will fire when an auto-accept session is connected. Advertiser should keep track of the new service session this.advertiser.AutoAcceptSessionConnected += OnAutoAcceptSessionConnected; // This will fire when a session is requested and it must be explicitly accepted or rejected. // The advertiser may need to display a PIN or take user input for a PIN this.advertiser.SessionRequested += OnSessionRequested; }
/// <summary> /// Start advertising a service /// </summary> /// <param name="serviceName"></param> /// <param name="autoAccept"></param> /// <param name="preferGO"></param> /// <param name="configMethods"></param> /// <param name="status"></param> /// <param name="customStatus"></param> /// <param name="serviceInfo"></param> /// <param name="deferredServiceInfo"></param> /// <returns></returns> public WFDSvcWrapperHandle PublishService( string serviceName, bool autoAccept = true, bool preferGO = true, List <WiFiDirectServiceConfigurationMethod> configMethods = null, WiFiDirectServiceStatus status = WiFiDirectServiceStatus.Available, uint customStatus = 0, string serviceInfo = "", string deferredServiceInfo = "", List <String> prefixList = null ) { ThrowIfDisposed(); WiFiDirectTestLogger.Log("Creating Service: \"{0}\"", serviceName); WiFiDirectServiceAdvertiser advertiser = new WiFiDirectServiceAdvertiser(serviceName); advertiser.AutoAcceptSession = autoAccept; advertiser.PreferGroupOwnerMode = preferGO; advertiser.ServiceStatus = status; advertiser.CustomServiceStatusCode = customStatus; if (serviceInfo != null && serviceInfo.Length > 0) { using (var serviceInfoDataWriter = new Windows.Storage.Streams.DataWriter(new Windows.Storage.Streams.InMemoryRandomAccessStream())) { serviceInfoDataWriter.WriteString(serviceInfo); advertiser.ServiceInfo = serviceInfoDataWriter.DetachBuffer(); } WiFiDirectTestLogger.Log("Included Service Info: \"{0}\"", WiFiDirectTestUtilities.GetTruncatedString(serviceInfo)); } else { advertiser.ServiceInfo = null; } if (deferredServiceInfo != null && deferredServiceInfo.Length > 0) { using (var deferredSessionInfoDataWriter = new Windows.Storage.Streams.DataWriter(new Windows.Storage.Streams.InMemoryRandomAccessStream())) { deferredSessionInfoDataWriter.WriteString(deferredServiceInfo); advertiser.DeferredSessionInfo = deferredSessionInfoDataWriter.DetachBuffer(); } WiFiDirectTestLogger.Log("Included Session Info: \"{0}\"", WiFiDirectTestUtilities.GetTruncatedString(deferredServiceInfo)); } else { advertiser.DeferredSessionInfo = null; } if (configMethods != null) { advertiser.PreferredConfigurationMethods.Clear(); foreach (var configMethod in configMethods) { advertiser.PreferredConfigurationMethods.Add(configMethod); WiFiDirectTestLogger.Log("Added config method {0}", configMethod.ToString()); } } if (prefixList != null && prefixList.Count > 0) { advertiser.ServiceNamePrefixes.Clear(); foreach (var prefix in prefixList) { advertiser.ServiceNamePrefixes.Add(prefix); WiFiDirectTestLogger.Log("Added prefix {0}", prefix); } } ServiceAdvertiser advertiserWrapper = new ServiceAdvertiser(advertiser, this, this, this); advertiserCollection.Add(advertiserWrapper.Handle, advertiserWrapper); WiFiDirectTestLogger.Log("Starting Service: \"{1}\" (Advertiser={0})", advertiserWrapper.Handle, serviceName); advertiser.Start(); return(advertiserWrapper.Handle); }
public void StartAdvertisement( string serviceName, bool autoAccept, bool preferGO, string pin, IList<WiFiDirectServiceConfigurationMethod> configMethods, WiFiDirectServiceStatus status, uint customStatus, string serviceInfo, string deferredServiceInfo, IList<String> prefixList ) { ThrowIfDisposed(); // Create Advertiser object for the service // NOTE: service name is internally limited to up to 255 bytes in UTF-8 encoding // Valid characters include alpha-numeric, '.', '-', and any multi-byte character // characters a-z, A-Z are case-insensitive when discovering services WiFiDirectServiceAdvertiser advertiser = new WiFiDirectServiceAdvertiser(serviceName); // Auto-accept services will connect without interaction from advertiser // NOTE: if the config method used for a connection requires a PIN, then the advertiser will have to accept the connection advertiser.AutoAcceptSession = autoAccept; // Set the Group Owner intent to a large value so that the advertiser will try to become the group owner (GO) // NOTE: The GO of a P2P connection can connect to multiple clients while the client can connect to a single GO only advertiser.PreferGroupOwnerMode = preferGO; // Default status is "Available", but services may use a custom status code (value > 1) if applicable advertiser.ServiceStatus = status; advertiser.CustomServiceStatusCode = customStatus; // Service information can be up to 65000 bytes. // Service Seeker may explicitly discover this by specifying a short buffer that is a subset of this buffer. // If seeker portion matches, then entire buffer is returned, otherwise, the service information is not returned to the seeker // This sample uses a string for the buffer but it can be any data if (serviceInfo != null && serviceInfo.Length > 0) { using (var tempStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()) { using (var serviceInfoDataWriter = new Windows.Storage.Streams.DataWriter(tempStream)) { serviceInfoDataWriter.WriteString(serviceInfo); advertiser.ServiceInfo = serviceInfoDataWriter.DetachBuffer(); } } } else { advertiser.ServiceInfo = null; } // This is a buffer of up to 144 bytes that is sent to the seeker in case the connection is "deferred" (i.e. not auto-accepted) // This buffer will be sent when auto-accept is false, or if a PIN is required to complete the connection // For the sample, we use a string, but it can contain any data if (deferredServiceInfo != null && deferredServiceInfo.Length > 0) { using (var tempStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()) { using (var deferredSessionInfoDataWriter = new Windows.Storage.Streams.DataWriter(tempStream)) { deferredSessionInfoDataWriter.WriteString(deferredServiceInfo); advertiser.DeferredSessionInfo = deferredSessionInfoDataWriter.DetachBuffer(); } } } else { advertiser.DeferredSessionInfo = null; } // The advertiser supported configuration methods // Valid values are PIN-only (either keypad entry, display, or both), or PIN (keypad entry, display, or both) and WFD Services default // WFD Services Default config method does not require explicit PIN entry and offers a more seamless connection experience // Typically, an advertiser will support PIN display (and WFD Services Default), and a seeker will connect with either PIN entry or WFD Services Default if (configMethods != null) { advertiser.PreferredConfigurationMethods.Clear(); foreach (var configMethod in configMethods) { advertiser.PreferredConfigurationMethods.Add(configMethod); } } // Advertiser may also be discoverable by a prefix of the service name. Must explicitly specify prefixes allowed here. if (prefixList != null && prefixList.Count > 0) { advertiser.ServiceNamePrefixes.Clear(); foreach (var prefix in prefixList) { advertiser.ServiceNamePrefixes.Add(prefix); } } // For this sample, we wrap the advertiser in our own object which handles the advertiser events AdvertisementWrapper advertiserWrapper = new AdvertisementWrapper(advertiser, this, pin); AddAdvertiser(advertiserWrapper); RootPage.NotifyUser("Starting service...", NotifyType.StatusMessage); try { // This may fail if the driver is unable to handle the request or if services is not supported // NOTE: this must be called from the UI thread of the app advertiser.Start(); } catch (Exception ex) { RootPage.NotifyUser(String.Format(CultureInfo.InvariantCulture, "Failed to start service: {0}", ex.Message), NotifyType.ErrorMessage); throw; } }
private void OnAdvertisementStatusChanged(WiFiDirectServiceAdvertiser sender, object args) { try { ThrowIfDisposed(); WiFiDirectServiceAdvertisementStatus status = advertiser.AdvertisementStatus; manager.NotifyUser("Advertisement Status Changed to " + status.ToString(), NotifyType.StatusMessage); manager.AdvertiserStatusChanged(this); } catch (Exception ex) { manager.NotifyUser("OnAdvertisementStatusChanged Failed: " + ex.Message, NotifyType.ErrorMessage); } }
// NOTE: this is mutually exclusive with OnSessionRequested private void OnAutoAcceptSessionConnected(WiFiDirectServiceAdvertiser sender, WiFiDirectServiceAutoAcceptSessionConnectedEventArgs args) { try { ThrowIfDisposed(); string sessionInfo = ""; if (args.SessionInfo != null && args.SessionInfo.Length > 0) { using (DataReader sessionInfoDataReader = DataReader.FromBuffer(args.SessionInfo)) { sessionInfo = sessionInfoDataReader.ReadString(args.SessionInfo.Length); } } manager.NotifyUser("Auto-Accept Session Connected: sessionInfo=" + sessionInfo, NotifyType.StatusMessage); SessionWrapper sessionWrapper = new SessionWrapper(args.Session, manager); manager.AddSession(sessionWrapper); } catch (Exception ex) { manager.NotifyUser("OnAutoAcceptSessionConnected Failed: " + ex.Message, NotifyType.ErrorMessage); } }
// NOTE: this is mutually exclusive with OnAutoAcceptSessionConnected private void OnSessionRequested(WiFiDirectServiceAdvertiser sender, WiFiDirectServiceSessionRequestedEventArgs args) { try { ThrowIfDisposed(); manager.NotifyUser("Received session request", NotifyType.StatusMessage); string sessionInfo = ""; if (args.GetSessionRequest().SessionInfo != null && args.GetSessionRequest().SessionInfo.Length > 0) { using (DataReader sessionInfoDataReader = DataReader.FromBuffer(args.GetSessionRequest().SessionInfo)) { sessionInfo = sessionInfoDataReader.ReadString(args.GetSessionRequest().SessionInfo.Length); manager.NotifyUser("Received Session Info: " + sessionInfo, NotifyType.StatusMessage); } } lock (thisLock) { requestList.Add(args.GetSessionRequest()); } // Now we update the UI and wait for action to take (accept or decline) manager.AddSessionRequest(args.GetSessionRequest(), this); if (args.GetSessionRequest().ProvisioningInfo.IsGroupFormationNeeded && args.GetSessionRequest().ProvisioningInfo.SelectedConfigurationMethod == WiFiDirectServiceConfigurationMethod.PinDisplay) { // This means the advertiser should display a PIN and the seeker will look at the display and enter the same PIN // The PIN may be randomly generated now, but for this sample, we configure a PIN when starting the advertiser manager.NotifyUser("Remote side should enter PIN: " + pin, NotifyType.StatusMessage); } } catch (Exception ex) { manager.NotifyUser("OnSessionRequest Failed: " + ex.Message, NotifyType.ErrorMessage); } }
public WiFiDirectServiceAdvertiserEvents(WiFiDirectServiceAdvertiser This) { this.This = This; }
public void StartAdvertisement( string serviceName, bool autoAccept, bool preferGO, string pin, IList <WiFiDirectServiceConfigurationMethod> configMethods, WiFiDirectServiceStatus status, uint customStatus, string serviceInfo, string deferredServiceInfo, IList <String> prefixList ) { ThrowIfDisposed(); // Create Advertiser object for the service // NOTE: service name is internally limited to up to 255 bytes in UTF-8 encoding // Valid characters include alpha-numeric, '.', '-', and any multi-byte character // characters a-z, A-Z are case-insensitive when discovering services WiFiDirectServiceAdvertiser advertiser = new WiFiDirectServiceAdvertiser(serviceName); // Auto-accept services will connect without interaction from advertiser // NOTE: if the config method used for a connection requires a PIN, then the advertiser will have to accept the connection advertiser.AutoAcceptSession = autoAccept; // Set the Group Owner intent to a large value so that the advertiser will try to become the group owner (GO) // NOTE: The GO of a P2P connection can connect to multiple clients while the client can connect to a single GO only advertiser.PreferGroupOwnerMode = preferGO; // Default status is "Available", but services may use a custom status code (value > 1) if applicable advertiser.ServiceStatus = status; advertiser.CustomServiceStatusCode = customStatus; // Service information can be up to 65000 bytes. // Service Seeker may explicitly discover this by specifying a short buffer that is a subset of this buffer. // If seeker portion matches, then entire buffer is returned, otherwise, the service information is not returned to the seeker // This sample uses a string for the buffer but it can be any data if (serviceInfo != null && serviceInfo.Length > 0) { using (var tempStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()) { using (var serviceInfoDataWriter = new Windows.Storage.Streams.DataWriter(tempStream)) { serviceInfoDataWriter.WriteString(serviceInfo); advertiser.ServiceInfo = serviceInfoDataWriter.DetachBuffer(); } } } else { advertiser.ServiceInfo = null; } // This is a buffer of up to 144 bytes that is sent to the seeker in case the connection is "deferred" (i.e. not auto-accepted) // This buffer will be sent when auto-accept is false, or if a PIN is required to complete the connection // For the sample, we use a string, but it can contain any data if (deferredServiceInfo != null && deferredServiceInfo.Length > 0) { using (var tempStream = new Windows.Storage.Streams.InMemoryRandomAccessStream()) { using (var deferredSessionInfoDataWriter = new Windows.Storage.Streams.DataWriter(tempStream)) { deferredSessionInfoDataWriter.WriteString(deferredServiceInfo); advertiser.DeferredSessionInfo = deferredSessionInfoDataWriter.DetachBuffer(); } } } else { advertiser.DeferredSessionInfo = null; } // The advertiser supported configuration methods // Valid values are PIN-only (either keypad entry, display, or both), or PIN (keypad entry, display, or both) and WFD Services default // WFD Services Default config method does not require explicit PIN entry and offers a more seamless connection experience // Typically, an advertiser will support PIN display (and WFD Services Default), and a seeker will connect with either PIN entry or WFD Services Default if (configMethods != null) { advertiser.PreferredConfigurationMethods.Clear(); foreach (var configMethod in configMethods) { advertiser.PreferredConfigurationMethods.Add(configMethod); } } // Advertiser may also be discoverable by a prefix of the service name. Must explicitly specify prefixes allowed here. if (prefixList != null && prefixList.Count > 0) { advertiser.ServiceNamePrefixes.Clear(); foreach (var prefix in prefixList) { advertiser.ServiceNamePrefixes.Add(prefix); } } // For this sample, we wrap the advertiser in our own object which handles the advertiser events AdvertisementWrapper advertiserWrapper = new AdvertisementWrapper(advertiser, this, pin); AddAdvertiser(advertiserWrapper); RootPage.NotifyUser("Starting service...", NotifyType.StatusMessage); try { // This may fail if the driver is unable to handle the request or if services is not supported // NOTE: this must be called from the UI thread of the app advertiser.Start(); } catch (Exception ex) { RootPage.NotifyUser(String.Format(CultureInfo.InvariantCulture, "Failed to start service: {0}", ex.Message), NotifyType.ErrorMessage); throw; } }