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 }
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"); }
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; } }
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); } }
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_ + ")"); } } }