public void CustomTwoSeparate() { // Rfcomm/StdSvcClass/SvcName ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(BluetoothService.SerialPort); bldr.ServiceName = "Hello World!"; ServiceAttribute attr = new ServiceAttribute( UniversalAttributeId.ServiceAvailability, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 255)); bldr.AddCustomAttribute(attr); attr = new ServiceAttribute( UniversalAttributeId.ServiceInfoTimeToLive, ServiceElement.CreateNumericalServiceElement(ElementType.UInt32, 56623104)); bldr.AddCustomAttribute(attr); DoTest(ServiceRecordBuilderTests_Data.OnePlusNamePlusCustomTwo, bldr); }
static void chaosaSrb2() { ushort u = 0x37; // the mobile can get the number of '10' using this ServiceElement se = new ServiceElement(ElementType.Int32, 10); ServiceAttribute sa = new ServiceAttribute(u, se); ServiceRecordBuilder srb = new ServiceRecordBuilder(); srb.AddCustomAttribute(sa); ServiceRecord rcd = srb.ServiceRecord; }
/// <inheritdoc /> internal override void StartListening(EndPoint desiredLocalListenEndPoint, bool useRandomPortFailOver) { if (IsListening) throw new InvalidOperationException("Attempted to call StartListening when already listening."); if(!(desiredLocalListenEndPoint is BluetoothEndPoint)) throw new ArgumentException("Bluetooth connections can only be made from a local BluetoothEndPoint", "desiredLocalListenIPEndPoint"); try { ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass((desiredLocalListenEndPoint as BluetoothEndPoint).Service); if (IsDiscoverable) bldr.AddCustomAttribute(new ServiceAttribute(NetworkCommsBTAttributeId.NetworkCommsEndPoint, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 1))); listenerInstance = new BluetoothListener(desiredLocalListenEndPoint as BluetoothEndPoint, bldr.ServiceRecord); listenerInstance.Start(); listenerInstance.BeginAcceptBluetoothClient(BluetoothConnectionReceivedAsync, null); } catch (SocketException) { //If the port we wanted is not available if (useRandomPortFailOver) { try { Guid service = Guid.NewGuid(); ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(service); if (IsDiscoverable) bldr.AddCustomAttribute(new ServiceAttribute(NetworkCommsBTAttributeId.NetworkCommsEndPoint, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 1))); listenerInstance = new BluetoothListener(new BluetoothEndPoint((desiredLocalListenEndPoint as BluetoothEndPoint).Address, service), bldr.ServiceRecord); listenerInstance.Start(); listenerInstance.BeginAcceptBluetoothClient(BluetoothConnectionReceivedAsync, null); } catch (SocketException) { //If we get another socket exception this appears to be a bad IP. We will just ignore this IP if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Error("It was not possible to open a random port on " + desiredLocalListenEndPoint + ". This endPoint may not support listening or possibly try again using a different port."); throw new CommsSetupShutdownException("It was not possible to open a random port on " + desiredLocalListenEndPoint + ". This endPoint may not support listening or possibly try again using a different port."); } } else { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Error("It was not possible to listen on " + desiredLocalListenEndPoint.ToString() + ". This endPoint may not support listening or possibly try again using a different port."); throw new CommsSetupShutdownException("It was not possible to listen on " + desiredLocalListenEndPoint.ToString() + ". This endPoint may not support listening or possibly try again using a different port."); } } this.LocalListenEndPoint = desiredLocalListenEndPoint; this.IsListening = true; }
static ServiceRecord Documentation_SRB_Simple_() { ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(BluetoothService.SerialPort); bldr.ServiceName = "Alan's SPP service"; bldr.AddCustomAttribute(new ServiceAttribute(0x8001, ServiceElement.CreateNumericalServiceElement(ElementType.UInt16, 0xFEDC))); // ServiceRecord record = bldr.ServiceRecord; return(record); }
public void Five_HSPv1_2() { // Headset == Rfcomm/2xStdSvcClass/BtPDL/1xCustom ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(BluetoothService.HeadsetHeadset); bldr.AddServiceClass(BluetoothService.GenericAudio); bldr.AddBluetoothProfileDescriptor(BluetoothService.Headset, 1, 2); bldr.AddCustomAttribute(new ServiceAttribute( HeadsetProfileAttributeId.RemoteAudioVolumeControl, new ServiceElement(ElementType.Boolean, false))); DoTest(ServiceRecordBuilderTests_Data.Five_HSPv1_2_HS, bldr); Assert.AreEqual(BluetoothProtocolDescriptorType.Rfcomm, bldr.ProtocolType); }
public void CustomTwoFromOneWithHighAttrIdAdded() { // Rfcomm/StdSvcClass/SvcName ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(BluetoothService.SerialPort); bldr.ServiceName = "Hello World!"; ServiceAttribute attr2 = new ServiceAttribute( 0x8000, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 0x80)); bldr.AddCustomAttribute(attr2); ServiceAttribute attr2b = new ServiceAttribute( 0xFFFF, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 255)); bldr.AddCustomAttribute(attr2b); ServiceAttribute attr = new ServiceAttribute( UniversalAttributeId.ServiceAvailability, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 8)); bldr.AddCustomAttribute(attr); DoTest(ServiceRecordBuilderTests_Data.CustomTwoFromOneWithHighAttrIdAdded, bldr); }
static void Documentation_SRB_ToByteArray_Pbap() { ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(BluetoothService.PhonebookAccessPse); bldr.ServiceName = "Phonebook Access PSE"; bldr.AddBluetoothProfileDescriptor(BluetoothService.PhonebookAccess, 1, 0); // v1.0 const ushort SupportedRepositories = 0x0314; bldr.AddCustomAttribute(new ServiceAttribute(SupportedRepositories, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 0x03))); // ServiceRecord record = bldr.ServiceRecord; // var txt = ServiceRecordUtilities.Dump(record); Console.WriteLine(txt); // var byteArr = record.ToByteArray(); var txtBA = BitConverter.ToString(byteArr); Console.WriteLine(txtBA); }
internal static ServiceRecord CreateServiceRecord(ref Structs.BtSdkRemoteServiceAttrStru attrs, IBluesoleilApi api) { ServiceRecordBuilder bldr = new ServiceRecordBuilder(); //-- Guid sc = BluetoothService.CreateBluetoothUuid(attrs.svc_class); bldr.AddServiceClass(sc); //-- string name = ParseServiceName(ref attrs); if (name.Length != 0) { bldr.ServiceName = name; } // byte?port = null; var extras = new List <ServiceAttribute>(); Debug.Assert(attrs.status == 0, "attrs.status: 0x" + attrs.status.ToString("X")); if (attrs.ext_attributes != IntPtr.Zero) { if (sc == BluetoothService.HumanInterfaceDevice) { var hidInfo = (Structs.BtSdkRmtHidSvcExtAttrStru_HACK)Marshal.PtrToStructure( attrs.ext_attributes, typeof(Structs.BtSdkRmtHidSvcExtAttrStru_HACK)); Debug.Assert(Marshal.SizeOf(typeof(Structs.BtSdkRmtHidSvcExtAttrStru_HACK)) == Marshal.SizeOf(hidInfo), "SizeOf x2"); Debug.Assert(hidInfo.size == Marshal.SizeOf(typeof(Structs.BtSdkRmtHidSvcExtAttrStru_HACK)) + Structs.BtSdkRmtHidSvcExtAttrStru_HACK.StackMiscountsPaddingSize, "Different sizes! hidInfo.size: " + hidInfo.size + ", SizeOf(): " + Marshal.SizeOf(typeof(Structs.BtSdkRmtHidSvcExtAttrStru_HACK))); // TO-DO Human Interface (HID) record: Use "mask" field, it's undocumented, check for real life values // With test SdpCreateAHumanInputDeviceRecordsAllTwoOfThree // which adds two out of three of {DeviceReleaseNumber,DeviceSubclass,CountryCode} // mask==0. So mask apparently applies to other fields! // So we check these three values for zero // and discard them if so! Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "HID.mask: {0:X}", hidInfo.mask)); var list = new List <ServiceAttribute>(); if (hidInfo.deviceReleaseNumber != 0) { list.Add( new ServiceAttribute(HidProfileAttributeId.DeviceReleaseNumber, new ServiceElement(ElementType.UInt16, hidInfo.deviceReleaseNumber))); } if (hidInfo.deviceSubclass != 0) { list.Add( new ServiceAttribute(HidProfileAttributeId.DeviceSubclass, new ServiceElement(ElementType.UInt8, hidInfo.deviceSubclass))); } if (hidInfo.countryCode != 0) { list.Add( new ServiceAttribute(HidProfileAttributeId.CountryCode, new ServiceElement(ElementType.UInt8, hidInfo.countryCode))); } // TO-DO HID other... extras.AddRange(list); } else if (sc == BluetoothService.PnPInformation) { var deviceInfo = (Structs.BtSdkRmtDISvcExtAttrStru)Marshal.PtrToStructure( attrs.ext_attributes, typeof(Structs.BtSdkRmtDISvcExtAttrStru)); Debug.Assert(Marshal.SizeOf(typeof(Structs.BtSdkRmtDISvcExtAttrStru)) == Marshal.SizeOf(deviceInfo), "SizeOf x2"); Debug.Assert(deviceInfo.size == Marshal.SizeOf(typeof(Structs.BtSdkRmtDISvcExtAttrStru)) + Structs.BtSdkRmtDISvcExtAttrStru.StackMiscountsPaddingSize, "Different sizes! deviceInfo.size: " + deviceInfo.size + ", Marshal.SizeOf: " + Marshal.SizeOf(typeof(Structs.BtSdkRmtDISvcExtAttrStru))); // TO-DO Device Info (PnP) record: Use "mask" field, it's undocumented, check for real life values //Debug.Assert(deviceInfo.mask == 0, "Is mask field in BtSdkRmtDISvcExtAttrStru ever set!!!, is here:" + deviceInfo.mask); Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "PnP/DI.mask: {0:X}", deviceInfo.mask)); // Like above (PnP) we see mask==0 for the fields we handle // here (six of). So we check these values // for zero and discard them if so! var list = new List <ServiceAttribute>(); if (deviceInfo.spec_id != 0) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.SpecificationId, new ServiceElement(ElementType.UInt16, deviceInfo.spec_id))); } if (deviceInfo.vendor_id != 0) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.VendorId, new ServiceElement(ElementType.UInt16, deviceInfo.vendor_id))); } if (deviceInfo.product_id != 0) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.ProductId, new ServiceElement(ElementType.UInt16, deviceInfo.product_id))); } if (deviceInfo.version != 0) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.Version, new ServiceElement(ElementType.UInt16, deviceInfo.version))); } if (true /* Zero means False here!! */) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.PrimaryRecord, new ServiceElement(ElementType.Boolean, deviceInfo.primary_record))); } if (deviceInfo.vendor_id_source != 0) { list.Add( new ServiceAttribute(DeviceIdProfileAttributeId.VendorIdSource, new ServiceElement(ElementType.UInt16, deviceInfo.vendor_id_source))); } // TO-DO URLs... extras.AddRange(list); } else { // On testing we see this never working! For one device // with an ImagingResponder record the size of 0x18 and // not 0x8 as per definition, and the port value is wrong. // And for its PhonebookAccessPse record the size is // correctly 0x8, but again the port value is wrong! // var sppInfo = (Structs.BtSdkRmtSPPSvcExtAttrStru)Marshal.PtrToStructure( attrs.ext_attributes, typeof(Structs.BtSdkRmtSPPSvcExtAttrStru)); Debug.Assert(sppInfo.size == Marshal.SizeOf(typeof(Structs.BtSdkRmtSPPSvcExtAttrStru)), "Different sizes!"); port = sppInfo.server_channel; } api.Btsdk_FreeMemory(attrs.ext_attributes); }//if (attrs.ext_attributes != NULL) // Use a different API to try and get the RFCOMM port number as // the previous API is quite rubbish at doing that!! var svcB = new Structs.BtSdkAppExtSPPAttrStru(sc); var retSpp = api.Btsdk_SearchAppExtSPPService(attrs.dev_hdl, ref svcB); if (retSpp == BtSdkError.NO_SERVICE) // error { } else if (retSpp != BtSdkError.OK) // error { Debug.WriteLine("GetSvcRcds Btsdk_SearchAppExtSPPService ret: " + BluesoleilUtils.BtSdkErrorToString(retSpp)); } else // success { if (svcB.rf_svr_chnl != 0) { byte newPort = svcB.rf_svr_chnl; if (port.HasValue) { Debug.Assert(port.Value == newPort, "port: " + port.Value + ", newPort: " + newPort); } else { port = newPort; } } if (svcB.sdp_record_handle != 0) { bldr.AddCustomAttribute(new ServiceAttribute( UniversalAttributeId.ServiceRecordHandle, ServiceElement.CreateNumericalServiceElement(ElementType.UInt32, svcB.sdp_record_handle))); } #if DEBUG Debug.Assert(svcB.service_class_128 == sc, "svcSpp.service_class_128: " + svcB.service_class_128 + ", sc: " + sc); var snSpp = BluesoleilUtils.FromNameString(svcB.svc_name, StackConsts.BTSDK_SERVICENAME_MAXLENGTH); if (snSpp == null) { Debug.Assert(name == null || name.Length == 0, "svcSpp.svc_name: null" + ", name: " + name); } else if (snSpp.Length == 1) { // SearchAppExtSPPService doesn't handle Unicode // but Btsdk_BrowseRemoteServicesEx etc does. Debug.Assert(snSpp[0] == name[0], "svcSpp.svc_name: " + snSpp + ", name: " + name); } else { Debug.Assert(snSpp == name, "svcSpp.svc_name: " + snSpp + ", bldr.ServiceName: " + name); } #endif } // if (port.HasValue) { } else { bldr.ProtocolType = BluetoothProtocolDescriptorType.None; } if (extras.Count != 0) { bldr.AddCustomAttributes(extras); } // const ServiceAttributeId FakeDescr = (ServiceAttributeId)(-1); bldr.AddCustomAttribute(new ServiceAttribute(FakeDescr, new ServiceElement(ElementType.TextString, "<partial BlueSoleil decode>"))); ServiceRecord sr = bldr.ServiceRecord; if (port.HasValue) { Debug.Assert(bldr.ProtocolType == BluetoothProtocolDescriptorType.Rfcomm, "type=" + bldr.ProtocolType); ServiceRecordHelper.SetRfcommChannelNumber(sr, port.Value); } else { bldr.ProtocolType = BluetoothProtocolDescriptorType.None; } return(sr); }
/// <inheritdoc /> internal override void StartListening(EndPoint desiredLocalListenEndPoint, bool useRandomPortFailOver) { if (IsListening) { throw new InvalidOperationException("Attempted to call StartListening when already listening."); } if (!(desiredLocalListenEndPoint is BluetoothEndPoint)) { throw new ArgumentException("Bluetooth connections can only be made from a local BluetoothEndPoint", "desiredLocalListenIPEndPoint"); } try { ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass((desiredLocalListenEndPoint as BluetoothEndPoint).Service); if (IsDiscoverable) { bldr.AddCustomAttribute(new ServiceAttribute(NetworkCommsBTAttributeId.NetworkCommsEndPoint, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 1))); } listenerInstance = new BluetoothListener(desiredLocalListenEndPoint as BluetoothEndPoint, bldr.ServiceRecord); listenerInstance.Start(); listenerInstance.BeginAcceptBluetoothClient(BluetoothConnectionReceivedAsync, null); } catch (SocketException) { //If the port we wanted is not available if (useRandomPortFailOver) { try { Guid service = Guid.NewGuid(); ServiceRecordBuilder bldr = new ServiceRecordBuilder(); bldr.AddServiceClass(service); if (IsDiscoverable) { bldr.AddCustomAttribute(new ServiceAttribute(NetworkCommsBTAttributeId.NetworkCommsEndPoint, ServiceElement.CreateNumericalServiceElement(ElementType.UInt8, 1))); } listenerInstance = new BluetoothListener(new BluetoothEndPoint((desiredLocalListenEndPoint as BluetoothEndPoint).Address, service), bldr.ServiceRecord); listenerInstance.Start(); listenerInstance.BeginAcceptBluetoothClient(BluetoothConnectionReceivedAsync, null); } catch (SocketException) { //If we get another socket exception this appears to be a bad IP. We will just ignore this IP if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Error("It was not possible to open a random port on " + desiredLocalListenEndPoint + ". This endPoint may not support listening or possibly try again using a different port."); } throw new CommsSetupShutdownException("It was not possible to open a random port on " + desiredLocalListenEndPoint + ". This endPoint may not support listening or possibly try again using a different port."); } } else { if (NetworkComms.LoggingEnabled) { NetworkComms.Logger.Error("It was not possible to listen on " + desiredLocalListenEndPoint.ToString() + ". This endPoint may not support listening or possibly try again using a different port."); } throw new CommsSetupShutdownException("It was not possible to listen on " + desiredLocalListenEndPoint.ToString() + ". This endPoint may not support listening or possibly try again using a different port."); } } this.LocalListenEndPoint = desiredLocalListenEndPoint; this.IsListening = true; }
public ServiceRecord[] GetServiceRecords() { Debug.Assert(m_request.searchScope == SdpSearchScope.Anywhere, "unexpected searchScope: " + m_request.searchScope); int classInSCL, classAnywhere; if (m_records == null) { m_records = new List <ServiceRecord>(); SdpDiscoveryRecordsBufferBase.SimpleInfo[] infoArr = GetSimpleInfo(); foreach (SdpDiscoveryRecordsBufferBase.SimpleInfo info in infoArr) { classInSCL = classAnywhere = 0; //Utils.MiscUtils.Trace_WriteLine("fake int: {0}", info.fake); ServiceRecordBuilder bldr = new ServiceRecordBuilder(); const ServiceAttributeId FakeDescr = (ServiceAttributeId)(-1); bldr.AddCustomAttribute(new ServiceAttribute(FakeDescr, new ServiceElement(ElementType.TextString, "<partial Widcomm decode>"))); //-- bldr.AddServiceClass(info.serviceUuid); if (m_request.serviceGuid == info.serviceUuid) { ++classInSCL; } //-- if (info.serviceNameWchar != IntPtr.Zero) { string name = Marshal.PtrToStringUni(info.serviceNameWchar); if (name.Length != 0) { bldr.ServiceName = name; } } else if (info.serviceNameChar != IntPtr.Zero) { // PtrToStringAnsi is not supported on NETCF. The field // is not used by the native code there so that's ok. #if NETCF Debug.Fail("Don't expect 'serviceNameChar' on PPC."); #else string name = Marshal.PtrToStringAnsi(info.serviceNameChar); if (name.Length != 0) { bldr.ServiceName = name; } #endif } //-- if (info.scn == -1) { bldr.ProtocolType = BluetoothProtocolDescriptorType.None; } //-- switch (bldr.ProtocolType) { case BluetoothProtocolDescriptorType.GeneralObex: Debug.Fail("GEOP untested"); if (m_request.serviceGuid == BluetoothService.ObexProtocol) { ++classAnywhere; } goto case BluetoothProtocolDescriptorType.Rfcomm; case BluetoothProtocolDescriptorType.Rfcomm: if (m_request.serviceGuid == BluetoothService.RFCommProtocol) { ++classAnywhere; } if (m_request.serviceGuid == BluetoothService.L2CapProtocol) { ++classAnywhere; } break; case BluetoothProtocolDescriptorType.None: // We'd better assume L2CAP in the PDL or we'd skip too many // e.g. the SDP server record! if (m_request.serviceGuid == BluetoothService.L2CapProtocol) { ++classAnywhere; } break; } //-- ServiceRecord sr = bldr.ServiceRecord; if (info.scn != -1) { Debug.Assert(bldr.ProtocolType == BluetoothProtocolDescriptorType.Rfcomm, "type=" + bldr.ProtocolType); ServiceRecordHelper.SetRfcommChannelNumber(sr, checked ((byte)info.scn)); } if (classInSCL > 0 || classAnywhere > 0) { Utils.MiscUtils.Trace_WriteLine("Adding record"); m_records.Add(sr); } else // COVERAGE { Utils.MiscUtils.Trace_WriteLine("Skipping record"); } } } return(m_records.ToArray()); }