예제 #1
0
 public static extern int bind(int sockfd, ref Sockaddr_hci addr, int addrlen);
예제 #2
0
        public void Start()
        {
            log.Debug($"Hub initialising...");
            var devId = Bluez.hci_get_route(IntPtr.Zero);

            log.Debug($"Device ID = {devId}");
            var sockFd = Linux.socket(Consts.AF_BLUETOOTH, Consts.SOCK_RAW | Consts.SOCK_CLOEXEC, Consts.BTPROTO_HCI);

            log.Debug($"Socket FD = {sockFd}");
            var addr = new Sockaddr_hci
            {
                hci_family  = Consts.AF_BLUETOOTH,
                hci_dev     = (ushort)devId,
                hci_channel = Consts.HCI_CHANNEL_RAW
            };
            var status = Linux.bind(sockFd, ref addr, Marshal.SizeOf(addr));

            log.Debug($"Socket bind => {status}");
            status = Bluez.hci_le_set_scan_parameters(sockFd, 0, 0x10, 0x10, 0, 0, 1000);
            log.Debug($"Bluetooth LE scan parameters => {status}");
            var filter = new Hci_filter
            {
                type_mask  = 0x00000010,
                event_mask = 0x4000000000000000ul,
                opcode     = 0
            };

            status = Linux.setsockopt(sockFd, Consts.SOL_HCI, Consts.HCI_FILTER, ref filter, Marshal.SizeOf(filter));
            log.Debug($"Socket options => {status}");
            status = Bluez.hci_le_set_scan_enable(sockFd, 1, 0, 1000);
            log.Debug($"Bluetooth LE scan enable => {status}");
            watcher = new Thread(() =>
            {
                while (shouldRun)
                {
                    var bytes = new byte[44];
#if !WINRT
                    Mono.Unix.Native.Syscall.recv(sockFd, bytes, (ulong)bytes.Length, 0);
#endif
                    var manu = new byte[16];
                    Array.Copy(bytes, manu, manu.Length);
                    var svcs = new byte[bytes.Length - manu.Length];
                    Array.Copy(bytes, 16, svcs, 0, svcs.Length);
                    log.Debug($"Got {bytes.Length} bytes!");
                    OnBlueEvent?.Invoke(this, new BlueEvent
                    {
                        TimeStamp     = DateTime.UtcNow,
                        Advertisement = new Advertisement
                        {
                            // Address = addr,
                            AddressType = AddressType.Random,
                            // RSSI = args.RawSignalStrengthInDBm,
                            // Connectable = IsConnectable(args.AdvertisementType),
                            // Name = args.Advertisement.LocalName,
                            // Services = bytes,
                            // ID = addr,
                            // UUID = addr,
                            ManufacturerData = manu,
                            ServiceData      = svcs
                        }
                    });
                }
            })
            {
                IsBackground = true,
                Name         = "Watcher"
            };
            watcher.Start();
            log.Debug("Watcher started.");
        }