public void UnpublishService(int index) { ThrowIfDisposed(); AdvertisementWrapper advertiser = null; lock (thisLock) { if (index > advertisers.Count - 1) { throw new IndexOutOfRangeException("Attempted to stop service not found in list"); } advertiser = advertisers[index]; } try { advertiser.Advertiser.Stop(); } catch (Exception ex) { RootPage.NotifyUser("Stop Advertisement Failed: " + ex.Message, NotifyType.ErrorMessage); } }
public void CloseSession(int index) { SessionWrapper session = null; // First remove from list lock (thisLock) { if (index > connectedSessions.Count - 1) { throw new IndexOutOfRangeException("Attempted to close session not found in list"); } session = connectedSessions[index]; // Session will remove self from list when its status changes } // Close session by disposing underlying WiFiDirectServiceSession session.Close(); RootPage.NotifyUser("Closed Session", NotifyType.StatusMessage); }
public void InitializeBtleWatcher(string aqsFilter) { if (Watcher != null) { return; } ResultCollection.Clear(); Debug.WriteLine("BTLEWatcher aqsFilter: " + aqsFilter); //////////////////////////////////////////////////////////////// // Create the Watcher for the BTLE - GATT_STREAM_SERVICE_UUID // //////////////////////////////////////////////////////////////// // List of additional properties // https://msdn.microsoft.com/en-us/windows/uwp/devices-sensors/device-information-properties Watcher = DeviceInformation.CreateWatcher(aqsFilter); // An AQS string that filters the DeviceInformation objects to enumerate ///////////////////////////////////////////////////////////////////////// // Hook up handlers for the watcher events before starting the watcher // ///////////////////////////////////////////////////////////////////////// /////////// // Added // /////////// _handlerAdded = async(watcher, deviceInfo) => { // Since we have the collection databound to a UI element, we need to update the collection on the UI thread. await RootPage.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { // Check for duplicate entry var isDuplicate = ResultCollection.Any(bleInfoDisp => deviceInfo.Id == bleInfoDisp.Id); if (isDuplicate) { return; } // DeviceID W4 - \\?\BTHLEDevice#{151c0000-4580-4111-9ca1-5056f3454fbc}_f7a30813de8a#6&2e59d2a&f9&000c#{6e3bb679-4372-40c8-9eaa-4509df260cd8} Debug.WriteLine(Name + " - " + deviceInfo.Id); ResultCollection.Add(new DeviceInformationDisplay(deviceInfo)); //MainPage.Debug_DisplayDeviceParams( deviceInfo, ResultCollection.Count ); RootPage.NotifyUser(string.Format(Name + "-{0} devices found.", ResultCollection.Count), NotifyType.StatusMessage); // Fire Event var args = new BtleWatcherEventsArgs { Event = WatcherEvents.Added, TimeReached = DateTime.Now }; OnWatcherEventReached(args); }); }; Watcher.Added += _handlerAdded; ///////////// // Updated // ///////////// _handlerUpdated = async(watcher, deviceInfoUpdate) => { // Since we have the collection databound to a UI element, we need to update the collection on the UI thread. await RootPage.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { // Find the corresponding updated DeviceInformation in the collection and pass the update object // to the Update method of the existing DeviceInformation. This automatically updates the object for us. foreach (DeviceInformationDisplay deviceInfoDisp in ResultCollection) { if (deviceInfoDisp.Id != deviceInfoUpdate.Id) { continue; } deviceInfoDisp.Update(deviceInfoUpdate, Name); break; } // Fire Event var args = new BtleWatcherEventsArgs { Event = WatcherEvents.Updated, TimeReached = DateTime.Now }; OnWatcherEventReached(args); }); }; Watcher.Updated += _handlerUpdated; ///////////// // Removed // ///////////// _handlerRemoved = async(watcher, deviceInfoUpdate) => { // Since we have the collection databound to a UI element, we need to update the collection on the UI thread. await RootPage.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { // Find the corresponding DeviceInformation in the collection and remove it foreach (DeviceInformationDisplay deviceInfoDisp in ResultCollection) { if (deviceInfoDisp.Id != deviceInfoUpdate.Id) { continue; } if (ResultCollection.Contains(deviceInfoDisp)) { ResultCollection.Remove(deviceInfoDisp); } break; } RootPage.NotifyUser(string.Format(Name + "-{0} devices found.", ResultCollection.Count), NotifyType.StatusMessage); // Fire Event var args = new BtleWatcherEventsArgs { Event = WatcherEvents.Removed, TimeReached = DateTime.Now }; OnWatcherEventReached(args); }); }; Watcher.Removed += _handlerRemoved; ////////////////////////// // EnumerationCompleted // ////////////////////////// _handlerEnumCompleted = async(watcher, obj) => { await RootPage.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { EnumCompleted = true; Debug.WriteLine(Name + " Enumeration completed: {0} devices found .... Watching for updates...", ResultCollection.Count); RootPage.NotifyUser(string.Format(Name + "-{0} devices found.\n{1}-Enumeration completed.\n{1}-Watching for updates...", ResultCollection.Count, Name), NotifyType.StatusMessage); Utility.VibratePhone(); // Fire Event var args = new BtleWatcherEventsArgs { Event = WatcherEvents.EnumerationCompleted, TimeReached = DateTime.Now }; OnWatcherEventReached(args); }); }; Watcher.EnumerationCompleted += _handlerEnumCompleted; ///////////// // Stopped // ///////////// _handlerStopped = async(watcher, obj) => { await RootPage.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => { RootPage.NotifyUser(string.Format(Name + "-{0} devices found. Watcher {1}.", ResultCollection.Count, DeviceWatcherStatus.Aborted == watcher.Status ? "aborted" : "stopped"), NotifyType.StatusMessage); // Fire Event var args = new BtleWatcherEventsArgs { Event = WatcherEvents.Stopped, TimeReached = DateTime.Now }; OnWatcherEventReached(args); }); }; Watcher.Stopped += _handlerStopped; }
public async void DiscoverServicesAsync(string serviceName, string requestedServiceInfo) { try { ThrowIfDisposed(); RootPage.NotifyUser("Discover services... (name='" + serviceName + "', requestedInfo='" + requestedServiceInfo + "')", NotifyType.StatusMessage); // Clear old results discoveredDevices.Clear(); // Discovery depends on whether service information is requested string serviceSelector = ""; if (requestedServiceInfo == "") { // Just search by name serviceSelector = WiFiDirectService.GetSelector(serviceName); } else { using (var serviceInfoDataWriter = new DataWriter(new InMemoryRandomAccessStream())) { serviceInfoDataWriter.WriteString(requestedServiceInfo); // Discover by name and try to discover service information serviceSelector = WiFiDirectService.GetSelector(serviceName, serviceInfoDataWriter.DetachBuffer()); } } List <string> additionalProperties = new List <string>(); additionalProperties.Add("System.Devices.WiFiDirectServices.ServiceAddress"); additionalProperties.Add("System.Devices.WiFiDirectServices.ServiceName"); additionalProperties.Add("System.Devices.WiFiDirectServices.ServiceInformation"); additionalProperties.Add("System.Devices.WiFiDirectServices.AdvertisementId"); additionalProperties.Add("System.Devices.WiFiDirectServices.ServiceConfigMethods"); // Note: This sample demonstrates finding services with FindAllAsync, which does a discovery and returns a list // It is also possible to use DeviceWatcher to receive updates as soon as services are found and to continue the discovery until it is stopped // See the DeviceWatcher sample for an example on how to use that class instead of DeviceInformation.FindAllAsync DeviceInformationCollection deviceInfoCollection = await DeviceInformation.FindAllAsync(serviceSelector, additionalProperties); if (deviceInfoCollection != null && deviceInfoCollection.Count > 0) { RootPage.NotifyUser("Done discovering services, found " + deviceInfoCollection.Count + " services", NotifyType.StatusMessage); foreach (var device in deviceInfoCollection) { discoveredDevices.Add(new DiscoveredDeviceWrapper(device, this)); } } else { RootPage.NotifyUser("Done discovering services, No services found", NotifyType.StatusMessage); } // Update UI list if (scenario3 != null) { scenario3.UpdateDiscoveryList(discoveredDevices); } } catch (Exception ex) { RootPage.NotifyUser(String.Format("Failed to discover services: {0}", ex.Message), NotifyType.ErrorMessage); throw ex; } }
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; } }