예제 #1
0
        internal BluetopiaPacketDebug(BluetopiaFactory fcty, Stream pcapFile)
        {
            _fcty    = fcty;
            _Handler = HandleDebug;
            var ret = NativeMethods.BSC_RegisterDebugCallback(_fcty.StackId, _Handler, 0);

            BluetopiaUtils.Assert(ret, "BSC_RegisterDebugCallback");
            //
            var hundNs = DateTime.UtcNow.Ticks;
            var msec   = Environment.TickCount;

            _tickTimeOffset = hundNs - msec * HundredNsInMsec;
#if RAW_FILE
            _dest = File.Create(@"\packets.dat");
#endif
            _destPcap = pcapFile;
            WritePcapGlobalHeader(_destPcap);
            //
#if DEBUG
            byte testIsByteRange = checked ((byte)StackConsts.HCI_PacketType.__HCIAdditional);
            _sharedBuf[0] = testIsByteRange; // shut-up compiler
#if !NETCF                                   // :-(
            Debug.Assert(new IntPtr(OffsetOfData) == Marshal.OffsetOf(
                             typeof(Structs.HCI_Packet), "_startOf_HCIPacketData"));
#endif
#endif
        }
예제 #2
0
        public void DeleteServiceRecord()
        {
            if (!_hSR.HasValue)
            {
                //throw new InvalidOperationException("No record was created.");
                Debug.Fail("Delete -- No record was created.");
                return;
            }
            var hSR = _hSR.Value;

            _hSR = null;
            var ret = _fcty.Api.SDP_Delete_Service_Record(_fcty.StackId, hSR);

            BluetopiaUtils.Assert(ret, "SDP_Delete_Service_Record");
        }
예제 #3
0
        void ReadVersionsOnce()
        {
            if (_readVersions)
            {
                return;
            }
            _readVersions = true; // Just do once even if error
            BluetopiaError ret;

            try {
                StackConsts.HCI_ERROR_CODE hciStatus;
                ret = _fcty.Api.HCI_Read_Local_Version_Information(_fcty.StackId,
                                                                   out hciStatus, out _hciVersion, out _hciRev,
                                                                   out _lmpVersion, out _manuf, out _lmpSubver);
            } catch (MissingMethodException) { // Function added later to the SDK.
                ret = BluetopiaError.UNSUPPORTED_PLATFORM_ERROR;
            }
            BluetopiaUtils.Assert(ret, "HCI_Read_Local_Version_Information");
            if (!BluetopiaUtils.IsSuccess(ret))
            {
                _hciVersion = HciVersion.Unknown;
                _lmpVersion = LmpVersion.Unknown;
                _manuf      = Manufacturer.Unknown;
                _hciRev     = _lmpSubver = 0;
            }
            var arr = new byte[8];

            try {
                StackConsts.HCI_ERROR_CODE hciStatus;
                ret = _fcty.Api.HCI_Read_Local_Supported_Features(_fcty.StackId,
                                                                  out hciStatus, arr);
            } catch (MissingMethodException) { // Function added later to the SDK.
                ret = BluetopiaError.UNSUPPORTED_PLATFORM_ERROR;
            }
            BluetopiaUtils.Assert(ret, "HCI_Read_Local_Version_Information");
            if (BluetopiaUtils.IsSuccess(ret))
            {
                _lmpFeatures = (LmpFeatures)BitConverter.ToInt64(arr, 0);
            }
            else
            {
                _lmpFeatures = LmpFeatures.None;
            }
        }
예제 #4
0
        internal void CancelAllQueryNames()
        {
            ICollection <BluetoothAddress> addrList;

            lock (_lockDevices) {
                _lastCancelAllQueryNames = DateTime.UtcNow;
                addrList = _nameQueryList.Keys;
                _nameQueryList.Clear();
            }
            Debug.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                          "CancelAllQueryNames: {0} devices.", addrList.Count));
            foreach (var cur in addrList)
            {
                var ret = NativeMethods.GAP_Cancel_Query_Remote_Device_Name(
                    this.StackId, BluetopiaUtils.BluetoothAddressAsInteger(cur));
                BluetopiaUtils.Assert(ret, "GAP_Cancel_Query_Remote_Device_Name");
            }
            if (addrList.Count > 0)
            {
                // Help wait for cancellation to complete?
                Thread.Sleep(250);
            }
        }
예제 #5
0
        protected override void DoPortClose(bool disposing)
        {
            // We have the event handle now run all our code on a threadpool
            // thread so there can't be any deadlock, but leave this
            //    // We saw an apparent deadlock
            //    // ThreadB: BTPS->HandleSpp_Event_Callback->HandleCONNECT_ERR -> Monitor.Enter
            //    // ThreadA: MeThreadPool->...
            //    //   ->CommonRfcommStream.Dispose [Holding Monitor]->DoPortClose->SPP_Close_Port
            //    ThreadPool.QueueUserWorkItem(PortClose_Runner, disposing);
            //}
            //
            //void PortClose_Runner(object state)
            //{
            //    bool disposing = (bool)state;
            if (_hPortClient.HasValue)
            {
                var portId = _hPortClient.Value;
                _hPortClient = null;
                var ret = _fcty.Api.SPP_Close_Port(_fcty.StackId, portId);
                if (m_state_ == State.PeerDidClose)
                {
                    // Get here in two cases: real-PeerDidClose *and* Timeout!
                    // So *need* to close the latter case so will get a SUCCESS then.
                    Debug.Assert(ret == BluetopiaError.INVALID_PARAMETER, "INFO: SPP_Close_Port expecting IP (state: " + m_state_ + ")");
                }
                else if (m_state_ == State.Closed)
                {
                    // Likely the Finalizer thread called us at the same time
                    // as an app thread did, so there's a race on accessing/overwriting
                    // _hPortClient.  Just spat the error.
                    // Ideally we'd solve  the race by Interlock.Exchang-ing
                    // _hPortClient or by locking.  But closing twice is not
                    // really a problem.
                    Debug.Assert(ret == BluetopiaError.RFCOMM_INVALID_DLCI, "INFO: SPP_Close_Port expecting RID (state: " + m_state_ + ")");

                    /*
                     *  The thread 0x85ac1746 has exited with code 0 (0x0).
                     *  The thread 0x85ac1746 has exited with code 0 (0x0).
                     *  CONNECT_ERR DEBUGID, m_state: Connected, m_arConnect (null)
                     *  HandlePortEvent: closed when open.
                     *  14:56:38: RemovePort from CloseInternal (state: Connected)
                     *  Function: InTheHand.Net.Bluetooth.StonestreetOne.BluetopiaRfcommStream.DoPortClose(bool), Thread: 0x85AC1746 <No Name>; m_state_: Connected
                     ** Function: InTheHand.Net.Bluetooth.StonestreetOne.BluetopiaRfcommStream.DoPortClose(bool), Thread: 0x8711DFC6 GC Finalizer Thread; m_state_: Closed
                     ** The thread '<No Name>' (0x8711dfc6) has exited with code 0 (0x0).
                     */
                }
                else
                {
                    BluetopiaUtils.Assert(ret, "SPP_Close_Port expecting OK (state: " + m_state_ + ")");
                }
            }
            if (_hPortServer.HasValue)
            {
                var portId = _hPortServer.Value;
                _hPortServer = null;
                var ret = _fcty.Api.SPP_Close_Server_Port(_fcty.StackId, portId);
                if (m_state_ == State.PeerDidClose)
                {
                    // Get here in two cases: real-PeerDidClose *and* Timeout!
                    // So *need* to close the latter case so will get a SUCCESS then.
                    Debug.Assert(ret == BluetopiaError.INVALID_PARAMETER, "SPP_Close_Server_Port expecting IP  (state: " + m_state_ + ")");
                }
                else if (m_state_ == State.Closed)
                {
                    // Likely the Finalizer thread called us at the same time
                    // as an app thread did, so there's a race on accessing/overwriting
                    // _hPortClient.  Just splat the assert.  See above.
                    Debug.Assert(ret == BluetopiaError.RFCOMM_INVALID_DLCI, "INFO: SPP_Close_Server_Port expecting RID (state: " + m_state_ + ")");
                }
                else
                {
                    BluetopiaUtils.Assert(ret, "SPP_Close_Server_Port expecting OK (state: " + m_state_ + ")");
                }
            }
        }