Merge remote-tracking branch 'origin/dev_mobile_ble' into dev_mobile

# Conflicts:
#	Assets/Plugins/Android/AndroidManifest.xml
#	Assets/Plugins/Android/AndroidManifest.xml.meta
#	Assets/Plugins/iOS.meta
#	Assets/Scripts/App.cs
#	Assets/Scripts/Devices/MainDeviceAdapter.cs
#	Assets/Scripts/Scenes/LoginController.cs
#	Assets/Scripts/Scenes/Ride/Scripts/PlayerController.cs
This commit is contained in:
CaiYanPeng 2021-08-25 10:23:51 +08:00
commit f155b2b627
60 changed files with 4602 additions and 65 deletions

View File

@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector" >
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:isGame="true">
<activity android:label="@string/app_name" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false" android:name="com.unity3d.player.UnityPlayerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
<data android:scheme="powerfunx" android:host="app" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application>
</manifest>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
</manifest>

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 506e447c8b55f0449ae2b5b5ed37dd99
guid: 4abd69b18c4ab45ec976851430122248
TextScriptImporter:
externalObjects: {}
userData:

Binary file not shown.

View File

@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: f158ceee465c745bc89002ae57bc033e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,391 @@
using System;
using System.Collections.Generic;
using UnityEngine;
public class BluetoothDeviceScript : MonoBehaviour
{
#if UNITY_IOS
public Dictionary<string, string> BLEStandardUUIDs = new Dictionary<string, string>();
#endif
public List<string> DiscoveredDeviceList;
public Action InitializedAction { get; set; }
public Action DeinitializedAction;
public Action<string> ErrorAction;
public Action<string> ServiceAddedAction;
public Action<int> BleStatusChangedAction;
public Action StartedAdvertisingAction;
public Action StoppedAdvertisingAction;
public Action<string, string> DiscoveredPeripheralAction;
public Action<string, string, int, string[]> DiscoveredPeripheralWithAdvertisingInfoAction;
public Action<BluetoothLEHardwareInterface.iBeaconData> DiscoveredBeaconAction;
public Action<string, string> RetrievedConnectedPeripheralAction;
public Action<string, byte[]> PeripheralReceivedWriteDataAction;
public Action<string> ConnectedPeripheralAction;
public Action<string> ConnectedDisconnectPeripheralAction;
public Action<string> DisconnectedPeripheralAction;
public Action<string, string> DiscoveredServiceAction;
public Action<string, string, string> DiscoveredCharacteristicAction;
public Action<string> DidWriteCharacteristicAction;
public Dictionary<string, Dictionary<string, Action<string>>> DidUpdateNotificationStateForCharacteristicAction;
public Dictionary<string, Dictionary<string, Action<string, string>>> DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction;
public Dictionary<string, Dictionary<string, Action<string, byte[]>>> DidUpdateCharacteristicValueAction;
public Dictionary<string, Dictionary<string, Action<string, string, byte[]>>> DidUpdateCharacteristicValueWithDeviceAddressAction;
public Action<string, int> RequestMtuAction;
// Use this for initialization
void Start ()
{
DiscoveredDeviceList = new List<string> ();
DidUpdateNotificationStateForCharacteristicAction = new Dictionary<string, Dictionary<string, Action<string>>> ();
DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction = new Dictionary<string, Dictionary<string, Action<string, string>>> ();
DidUpdateCharacteristicValueAction = new Dictionary<string, Dictionary<string, Action<string, byte[]>>> ();
DidUpdateCharacteristicValueWithDeviceAddressAction = new Dictionary<string, Dictionary<string, Action<string, string, byte[]>>> ();
#if UNITY_IOS
BLEStandardUUIDs["Heart Rate Measurement"] = "00002A37-0000-1000-8000-00805F9B34FB";
#endif
}
// Update is called once per frame
void Update ()
{
}
const string deviceInitializedString = "Initialized";
const string deviceDeInitializedString = "DeInitialized";
const string deviceErrorString = "Error";
const string deviceServiceAdded = "ServiceAdded";
const string deviceStartedAdvertising = "StartedAdvertising";
const string deviceStoppedAdvertising = "StoppedAdvertising";
const string deviceDiscoveredPeripheral = "DiscoveredPeripheral";
const string deviceDiscoveredBeacon = "DiscoveredBeacon";
const string deviceRetrievedConnectedPeripheral = "RetrievedConnectedPeripheral";
const string devicePeripheralReceivedWriteData = "PeripheralReceivedWriteData";
const string deviceConnectedPeripheral = "ConnectedPeripheral";
const string deviceDisconnectedPeripheral = "DisconnectedPeripheral";
const string deviceDiscoveredService = "DiscoveredService";
const string deviceDiscoveredCharacteristic = "DiscoveredCharacteristic";
const string deviceDidWriteCharacteristic = "DidWriteCharacteristic";
const string deviceDidUpdateNotificationStateForCharacteristic = "DidUpdateNotificationStateForCharacteristic";
const string deviceDidUpdateValueForCharacteristic = "DidUpdateValueForCharacteristic";
const string deviceLog = "Log";
const string deviceRequestMtu = "MtuChanged";
const string bleStatusChanged = "BleStatusChanged";
public void OnBluetoothMessage (string message)
{
if (message != null)
{
char[] delim = new char[] { '~' };
string[] parts = message.Split (delim);
if (parts[0].Equals("DeviceStateChanged"))
{
//throw new Exception("test");
}
if (parts[0].Equals(bleStatusChanged))
{
if (BleStatusChangedAction != null)
{
BleStatusChangedAction(int.Parse(parts[1]));
}
}
for (int i = 0; i < parts.Length; ++i)
BluetoothLEHardwareInterface.Log(string.Format("Part: {0} - {1}", i, parts[i]));
if (message.Length >= deviceInitializedString.Length && message.Substring (0, deviceInitializedString.Length) == deviceInitializedString)
{
if (InitializedAction != null)
InitializedAction ();
}
else if (message.Length >= deviceLog.Length && message.Substring (0, deviceLog.Length) == deviceLog)
{
BluetoothLEHardwareInterface.Log (parts[1]);
}
else if (message.Length >= deviceDeInitializedString.Length && message.Substring (0, deviceDeInitializedString.Length) == deviceDeInitializedString)
{
BluetoothLEHardwareInterface.FinishDeInitialize ();
if (DeinitializedAction != null)
DeinitializedAction ();
}
else if (message.Length >= deviceErrorString.Length && message.Substring (0, deviceErrorString.Length) == deviceErrorString)
{
string error = "";
if (parts.Length >= 2)
error = parts[1];
if (ErrorAction != null)
ErrorAction (error);
}
else if (message.Length >= deviceServiceAdded.Length && message.Substring (0, deviceServiceAdded.Length) == deviceServiceAdded)
{
if (parts.Length >= 2)
{
if (ServiceAddedAction != null)
ServiceAddedAction (parts[1]);
}
}
else if (message.Length >= deviceStartedAdvertising.Length && message.Substring (0, deviceStartedAdvertising.Length) == deviceStartedAdvertising)
{
BluetoothLEHardwareInterface.Log ("Started Advertising");
if (StartedAdvertisingAction != null)
StartedAdvertisingAction ();
}
else if (message.Length >= deviceStoppedAdvertising.Length && message.Substring (0, deviceStoppedAdvertising.Length) == deviceStoppedAdvertising)
{
BluetoothLEHardwareInterface.Log ("Stopped Advertising");
if (StoppedAdvertisingAction != null)
StoppedAdvertisingAction ();
}
else if (message.Length >= deviceDiscoveredPeripheral.Length && message.Substring (0, deviceDiscoveredPeripheral.Length) == deviceDiscoveredPeripheral)
{
if (parts.Length >= 3)
{
// the first callback will only get called the first time this device is seen
// this is because it gets added to the a list in the DiscoveredDeviceList
// after that only the second callback will get called and only if there is
// advertising data available
if (!DiscoveredDeviceList.Contains (parts[1] + "|" + parts[2]))
{
DiscoveredDeviceList.Add (parts[1] + "|" + parts[2]);
if (DiscoveredPeripheralAction != null)
DiscoveredPeripheralAction (parts[1], parts[2]);
}
if (parts.Length >= 5 && DiscoveredPeripheralWithAdvertisingInfoAction != null)
{
// get the rssi from the 4th value
int rssi = 0;
if (!int.TryParse (parts[3], out rssi))
rssi = 0;
List<string> uuidList = new List<string>();
if (parts[4].Contains(","))
{
string[] s = parts[4].Split(',');
foreach (var o in s)
{
if (!string.IsNullOrEmpty(o))
{
uuidList.Add(o);
}
}
}
//// parse the base 64 encoded data that is the 5th value
//byte[] bytes = System.Convert.FromBase64String (parts[4]);
DiscoveredPeripheralWithAdvertisingInfoAction (parts[1], parts[2], rssi, uuidList.ToArray());
}
}
}
else if (message.Length >= deviceDiscoveredBeacon.Length && message.Substring (0, deviceDiscoveredBeacon.Length) == deviceDiscoveredBeacon)
{
if (parts.Length >= 7)
{
var iBeaconData = new BluetoothLEHardwareInterface.iBeaconData ();
iBeaconData.UUID = parts[1];
if (!int.TryParse (parts[2], out iBeaconData.Major))
iBeaconData.Major = 0;
if (!int.TryParse (parts[3], out iBeaconData.Minor))
iBeaconData.Minor = 0;
if (!int.TryParse (parts[4], out iBeaconData.RSSI))
iBeaconData.RSSI = 0;
if (!int.TryParse (parts[5], out iBeaconData.AndroidSignalPower))
iBeaconData.AndroidSignalPower = 0;
int iOSProximity = 0;
if (!int.TryParse (parts[6], out iOSProximity))
iOSProximity = 0;
iBeaconData.iOSProximity = (BluetoothLEHardwareInterface.iOSProximity)iOSProximity;
if (DiscoveredBeaconAction != null)
DiscoveredBeaconAction (iBeaconData);
}
}
else if (message.Length >= deviceRetrievedConnectedPeripheral.Length && message.Substring (0, deviceRetrievedConnectedPeripheral.Length) == deviceRetrievedConnectedPeripheral)
{
if (parts.Length >= 3)
{
DiscoveredDeviceList.Add (parts[1]);
if (RetrievedConnectedPeripheralAction != null)
RetrievedConnectedPeripheralAction (parts[1], parts[2]);
}
}
else if (message.Length >= devicePeripheralReceivedWriteData.Length && message.Substring (0, devicePeripheralReceivedWriteData.Length) == devicePeripheralReceivedWriteData)
{
if (parts.Length >= 3)
OnPeripheralData (parts[1], parts[2]);
}
else if (message.Length >= deviceConnectedPeripheral.Length && message.Substring (0, deviceConnectedPeripheral.Length) == deviceConnectedPeripheral)
{
if (parts.Length >= 2 && ConnectedPeripheralAction != null)
ConnectedPeripheralAction (parts[1]);
}
else if (message.Length >= deviceDisconnectedPeripheral.Length && message.Substring (0, deviceDisconnectedPeripheral.Length) == deviceDisconnectedPeripheral)
{
if (parts.Length >= 2)
{
if (ConnectedDisconnectPeripheralAction != null)
ConnectedDisconnectPeripheralAction (parts[1]);
if (DisconnectedPeripheralAction != null)
DisconnectedPeripheralAction (parts[1]);
}
}
else if (message.Length >= deviceDiscoveredService.Length && message.Substring (0, deviceDiscoveredService.Length) == deviceDiscoveredService)
{
if (parts.Length >= 3 && DiscoveredServiceAction != null)
DiscoveredServiceAction (parts[1], parts[2]);
}
else if (message.Length >= deviceDiscoveredCharacteristic.Length && message.Substring (0, deviceDiscoveredCharacteristic.Length) == deviceDiscoveredCharacteristic)
{
if (parts.Length >= 4 && DiscoveredCharacteristicAction != null)
DiscoveredCharacteristicAction (parts[1], parts[2], parts[3]);
}
else if (message.Length >= deviceDidWriteCharacteristic.Length && message.Substring (0, deviceDidWriteCharacteristic.Length) == deviceDidWriteCharacteristic)
{
if (parts.Length >= 2 && DidWriteCharacteristicAction != null)
DidWriteCharacteristicAction (parts[1]);
}
else if (message.Length >= deviceDidUpdateNotificationStateForCharacteristic.Length && message.Substring (0, deviceDidUpdateNotificationStateForCharacteristic.Length) == deviceDidUpdateNotificationStateForCharacteristic)
{
if (parts.Length >= 3)
{
if (DidUpdateNotificationStateForCharacteristicAction != null && DidUpdateNotificationStateForCharacteristicAction.ContainsKey (parts[1]))
{
var characteristicAction = DidUpdateNotificationStateForCharacteristicAction[parts[1]];
if (characteristicAction != null && characteristicAction.ContainsKey (parts[2]))
{
var action = characteristicAction[parts[2]];
if (action != null)
action (parts[2]);
}
}
if (DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction != null && DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction.ContainsKey (parts[1]))
{
var characteristicAction = DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[parts[1]];
if (characteristicAction != null && characteristicAction.ContainsKey (parts[2]))
{
var action = characteristicAction[parts[2]];
if (action != null)
action (parts[1], parts[2]);
}
}
}
}
else if (message.Length >= deviceDidUpdateValueForCharacteristic.Length && message.Substring (0, deviceDidUpdateValueForCharacteristic.Length) == deviceDidUpdateValueForCharacteristic)
{
if (parts.Length >= 4)
OnBluetoothData (parts[1], parts[2], parts[3]);
}
else if (message.Length >= deviceRequestMtu.Length && message.Substring(0, deviceRequestMtu.Length) == deviceRequestMtu)
{
if (parts.Length >= 3)
{
if (RequestMtuAction != null)
{
int mtu = 0;
if (int.TryParse(parts[2], out mtu))
RequestMtuAction(parts[1], mtu);
}
}
}
}
}
public void OnBluetoothData (string base64Data)
{
OnBluetoothData ("", "", base64Data);
}
public void OnBluetoothData (string deviceAddress, string characteristic, string base64Data)
{
if (base64Data != null)
{
byte[] bytes = System.Convert.FromBase64String (base64Data);
if (bytes.Length > 0)
{
deviceAddress = deviceAddress.ToUpper ();
characteristic = characteristic.ToUpper ();
#if UNITY_IOS
if (BLEStandardUUIDs.ContainsKey(characteristic))
characteristic = BLEStandardUUIDs[characteristic];
#endif
BluetoothLEHardwareInterface.Log ("Device: " + deviceAddress + " Characteristic Received: " + characteristic);
string byteString = "";
foreach (byte b in bytes)
byteString += string.Format ("{0:X2}", b);
BluetoothLEHardwareInterface.Log (byteString);
if (DidUpdateCharacteristicValueAction != null && DidUpdateCharacteristicValueAction.ContainsKey (deviceAddress))
{
var characteristicAction = DidUpdateCharacteristicValueAction[deviceAddress];
#if UNITY_ANDROID
characteristic = characteristic.ToLower ();
#endif
if (characteristicAction != null && characteristicAction.ContainsKey (characteristic))
{
var action = characteristicAction[characteristic];
if (action != null)
action (characteristic, bytes);
}
}
if (DidUpdateCharacteristicValueWithDeviceAddressAction != null && DidUpdateCharacteristicValueWithDeviceAddressAction.ContainsKey (deviceAddress))
{
var characteristicAction = DidUpdateCharacteristicValueWithDeviceAddressAction[deviceAddress];
#if UNITY_ANDROID
characteristic = characteristic.ToLower ();
#endif
if (characteristicAction != null && characteristicAction.ContainsKey (characteristic))
{
var action = characteristicAction[characteristic];
if (action != null)
action (deviceAddress, characteristic, bytes);
}
}
}
}
}
public void OnPeripheralData (string characteristic, string base64Data)
{
if (base64Data != null)
{
byte[] bytes = System.Convert.FromBase64String (base64Data);
if (bytes.Length > 0)
{
BluetoothLEHardwareInterface.Log ("Peripheral Received: " + characteristic);
string byteString = "";
foreach (byte b in bytes)
byteString += string.Format ("{0:X2}", b);
BluetoothLEHardwareInterface.Log (byteString);
if (PeripheralReceivedWriteDataAction != null)
PeripheralReceivedWriteDataAction (characteristic, bytes);
}
}
}
#if UNITY_IOS
private void IncludeCoreLocationFramework()
{
// this method is here because Unity now only includes CoreLocation
// if there are methods in the .cs code that access it
Input.location.Stop ();
}
#endif
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b188ba3ac565e48f58fc50dd5db4818d
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,999 @@
#define EXPERIMENTAL_MACOS_EDITOR
/*
This build includes an experimental implementation for the macOS editor of Unity
It is experiemental because of the way that the Unity editor hangs on to plugin
instances after leaving play mode. This causes this plugin to not free up its
resources and therefore can cause crashes in the Unity editor on macOS.
Since Unity does not give plugins or apps a chance to do anything when the user
hits the play / stop button in the Editor there isn't a chance for the app to
deinitialize this plugin.
What I have found in my own use of this is that if you put a button on your app
somewhere that you can press before hitting the stop button in the editor and
then in that button handler call this plugin's Deinitialize method it seems to
minimize how often the editor crashes.
WARNING: using the macOS editor can cause the editor to crash an loose your work
and settings. Save often. You have been warned, so please don't contact me if
you have lost work becausee of this problem. This is experimental only. Use at
your own risk.
*/
using UnityEngine;
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
#if UNITY_2018_3_OR_NEWER
#if UNITY_ANDROID
using UnityEngine.Android;
#endif
#endif
public class BluetoothLEHardwareInterface
{
public enum CBCharacteristicProperties
{
CBCharacteristicPropertyBroadcast = 0x01,
CBCharacteristicPropertyRead = 0x02,
CBCharacteristicPropertyWriteWithoutResponse = 0x04,
CBCharacteristicPropertyWrite = 0x08,
CBCharacteristicPropertyNotify = 0x10,
CBCharacteristicPropertyIndicate = 0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites = 0x40,
CBCharacteristicPropertyExtendedProperties = 0x80,
CBCharacteristicPropertyNotifyEncryptionRequired = 0x100,
CBCharacteristicPropertyIndicateEncryptionRequired = 0x200,
};
public enum ScanMode
{
LowPower = 0,
Balanced = 1,
LowLatency = 2
}
public enum ConnectionPriority
{
LowPower = 0,
Balanced = 1,
High = 2,
}
public enum iOSProximity
{
Unknown = 0,
Immediate = 1,
Near = 2,
Far = 3,
}
public struct iBeaconData
{
public string UUID;
public int Major;
public int Minor;
public int RSSI;
public int AndroidSignalPower;
public iOSProximity iOSProximity;
}
#if UNITY_ANDROID
public enum CBAttributePermissions
{
CBAttributePermissionsReadable = 0x01,
CBAttributePermissionsWriteable = 0x10,
CBAttributePermissionsReadEncryptionRequired = 0x02,
CBAttributePermissionsWriteEncryptionRequired = 0x20,
};
#else
public enum CBAttributePermissions
{
CBAttributePermissionsReadable = 0x01,
CBAttributePermissionsWriteable = 0x02,
CBAttributePermissionsReadEncryptionRequired = 0x04,
CBAttributePermissionsWriteEncryptionRequired = 0x08,
};
#endif
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
public delegate void UnitySendMessageCallbackDelegate (IntPtr objectName, IntPtr commandName, IntPtr commandData);
[DllImport ("BluetoothLEOSX")]
private static extern void ConnectUnitySendMessageCallback ([MarshalAs (UnmanagedType.FunctionPtr)]UnitySendMessageCallbackDelegate callbackMethod);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLELog (string message);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEInitialize ([MarshalAs (UnmanagedType.Bool)]bool asCentral, [MarshalAs (UnmanagedType.Bool)]bool asPeripheral);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEDeInitialize ();
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEPauseMessages (bool isPaused);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEScanForPeripheralsWithServices (string serviceUUIDsString, bool allowDuplicates, bool rssiOnly, bool clearPeripheralList);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLERetrieveListOfPeripheralsWithServices (string serviceUUIDsString);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEStopScan ();
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEConnectToPeripheral (string name);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEDisconnectAll ();
[DllImport("BluetoothLEOSX")]
private static extern void OSXBluetoothLERequestMtu (string name, int mtu);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEDisconnectPeripheral (string name);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEReadCharacteristic (string name, string service, string characteristic);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEWriteCharacteristic (string name, string service, string characteristic, byte[] data, int length, bool withResponse);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLESubscribeCharacteristic (string name, string service, string characteristic);
[DllImport ("BluetoothLEOSX")]
private static extern void OSXBluetoothLEUnSubscribeCharacteristic (string name, string service, string characteristic);
#endif
#if UNITY_IOS || UNITY_TVOS
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLELog (string message);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEInitialize (bool asCentral, bool asPeripheral);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEDeInitialize ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEPauseMessages (bool isPaused);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEScanForPeripheralsWithServices (string serviceUUIDsString, bool allowDuplicates, bool rssiOnly, bool clearPeripheralList);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLERetrieveListOfPeripheralsWithServices (string serviceUUIDsString);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEStopScan ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEConnectToPeripheral (string name);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEDisconnectPeripheral (string name);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEReadCharacteristic (string name, string service, string characteristic);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEWriteCharacteristic (string name, string service, string characteristic, byte[] data, int length, bool withResponse);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLESubscribeCharacteristic (string name, string service, string characteristic);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEUnSubscribeCharacteristic (string name, string service, string characteristic);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEDisconnectAll ();
#if !UNITY_TVOS
[DllImport("__Internal")]
private static extern void _iOSBluetoothLERequestMtu(string name, int mtu);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEScanForBeacons (string proximityUUIDsString);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEStopBeaconScan ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEPeripheralName (string newName);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLECreateService (string uuid, bool primary);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLERemoveService (string uuid);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLERemoveServices ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLECreateCharacteristic (string uuid, int properties, int permissions, byte[] data, int length);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLERemoveCharacteristic (string uuid);
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLERemoveCharacteristics ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEStartAdvertising ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEStopAdvertising ();
[DllImport ("__Internal")]
private static extern void _iOSBluetoothLEUpdateCharacteristicValue (string uuid, byte[] data, int length);
#endif
#elif UNITY_ANDROID
static AndroidJavaObject _android = null;
#endif
private static BluetoothDeviceScript bluetoothDeviceScript;
public static void Log (string message)
{
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
Debug.Log(message);
#else
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLELog (message);
#elif UNITY_ANDROID
if (_android == null)
{
AndroidJavaClass javaClass = new AndroidJavaClass ("com.shatalmic.unityandroidbluetoothlelib.UnityBluetoothLE");
_android = javaClass.CallStatic<AndroidJavaObject> ("getInstance");
}
if (_android != null)
_android.Call ("androidBluetoothLog", message);
#endif
}
#endif
}
public static BluetoothDeviceScript Initialize (bool asCentral, bool asPeripheral, Action action, Action<string> errorAction, Action<int> statusAction)
{
bluetoothDeviceScript = null;
#if UNITY_2018_3_OR_NEWER
#if UNITY_ANDROID
if (!Permission.HasUserAuthorizedPermission (Permission.FineLocation))
Permission.RequestUserPermission (Permission.FineLocation);
#endif
#endif
GameObject bluetoothLEReceiver = GameObject.Find("BluetoothLEReceiver");
if (bluetoothLEReceiver == null)
bluetoothLEReceiver = new GameObject ("BluetoothLEReceiver");
if (bluetoothLEReceiver != null)
{
bluetoothDeviceScript = bluetoothLEReceiver.GetComponent<BluetoothDeviceScript> ();
if (bluetoothDeviceScript == null)
bluetoothDeviceScript = bluetoothLEReceiver.AddComponent<BluetoothDeviceScript> ();
if (bluetoothDeviceScript != null)
{
bluetoothDeviceScript.BleStatusChangedAction = statusAction;
bluetoothDeviceScript.InitializedAction = action;
bluetoothDeviceScript.ErrorAction = errorAction;
}
}
GameObject.DontDestroyOnLoad (bluetoothLEReceiver);
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
ConnectUnitySendMessageCallback ((objectName, commandName, commandData) => {
string name = Marshal.PtrToStringAuto (objectName);
string command = Marshal.PtrToStringAuto (commandName);
string data = Marshal.PtrToStringAuto (commandData);
GameObject foundObject = GameObject.Find (name);
if (foundObject != null)
foundObject.SendMessage (command, data);
});
BluetoothLEHardwareInterface.OSXBluetoothLEInitialize (asCentral, asPeripheral);
#else
if (Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.SendMessage ("OnBluetoothMessage", "Initialized");
}
else
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEInitialize (asCentral, asPeripheral);
#elif UNITY_ANDROID
if (_android == null)
{
AndroidJavaClass javaClass = new AndroidJavaClass ("com.shatalmic.unityandroidbluetoothlelib.UnityBluetoothLE");
_android = javaClass.CallStatic<AndroidJavaObject> ("getInstance");
}
if (_android != null)
_android.Call ("androidBluetoothInitialize", asCentral, asPeripheral);
#endif
}
#endif
return bluetoothDeviceScript;
}
public static void DeInitialize (Action action)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.DeinitializedAction = action;
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
BluetoothLEHardwareInterface.OSXBluetoothLEDeInitialize ();
#else
if (Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.SendMessage ("OnBluetoothMessage", "DeInitialized");
}
else
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEDeInitialize ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothDeInitialize");
#endif
}
#endif
}
public static void FinishDeInitialize ()
{
GameObject bluetoothLEReceiver = GameObject.Find("BluetoothLEReceiver");
if (bluetoothLEReceiver != null)
GameObject.Destroy(bluetoothLEReceiver);
}
public static void BluetoothEnable (bool enable)
{
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
//_iOSBluetoothLELog (message);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothEnable", enable);
#endif
}
}
public static void BluetoothScanMode (ScanMode scanMode)
{
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothScanMode", (int)scanMode);
#endif
}
}
public static void BluetoothConnectionPriority (ConnectionPriority connectionPriority)
{
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothConnectionPriority", (int)connectionPriority);
#endif
}
}
public static void PauseMessages (bool isPaused)
{
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEPauseMessages (isPaused);
#else
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEPauseMessages (isPaused);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothPause", isPaused);
#endif
}
#endif
}
// scanning for beacons requires that you know the Proximity UUID
public static void ScanForBeacons (string[] proximityUUIDs, Action<iBeaconData> actionBeaconResponse)
{
if (proximityUUIDs != null && proximityUUIDs.Length >= 0)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.DiscoveredBeaconAction = actionBeaconResponse;
string proximityUUIDsString = null;
if (proximityUUIDs != null && proximityUUIDs.Length > 0)
{
proximityUUIDsString = "";
foreach (string proximityUUID in proximityUUIDs)
proximityUUIDsString += proximityUUID + "|";
proximityUUIDsString = proximityUUIDsString.Substring (0, proximityUUIDsString.Length - 1);
}
#if UNITY_IOS
_iOSBluetoothLEScanForBeacons (proximityUUIDsString);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothScanForBeacons", proximityUUIDsString);
#endif
}
}
}
public static void RequestMtu(string name, int mtu, Action<string, int> action)
{
if (bluetoothDeviceScript != null)
{
bluetoothDeviceScript.RequestMtuAction = action;
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
if (mtu > 184)
mtu = 184;
OSXBluetoothLERequestMtu(name, mtu);
#elif UNITY_IOS || UNITY_TVOS
if (mtu > 180)
mtu = 180;
_iOSBluetoothLERequestMtu (name, mtu);
#elif UNITY_ANDROID
if (_android != null)
{
_android.Call ("androidBluetoothRequestMtu", name, mtu);
}
#endif
}
public static void ScanForPeripheralsWithServices (string[] serviceUUIDs, Action<string, string> action = null, Action<string, string, int, string[]> actionAdvertisingInfo = null, bool rssiOnly = false, bool clearPeripheralList = true, int recordType = 0xFF)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
bluetoothDeviceScript.DiscoveredPeripheralAction = action;
bluetoothDeviceScript.DiscoveredPeripheralWithAdvertisingInfoAction = actionAdvertisingInfo;
if (bluetoothDeviceScript.DiscoveredDeviceList != null)
bluetoothDeviceScript.DiscoveredDeviceList.Clear ();
}
string serviceUUIDsString = null;
if (serviceUUIDs != null && serviceUUIDs.Length > 0)
{
serviceUUIDsString = "";
foreach (string serviceUUID in serviceUUIDs)
serviceUUIDsString += serviceUUID + "|";
serviceUUIDsString = serviceUUIDsString.Substring (0, serviceUUIDsString.Length - 1);
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEScanForPeripheralsWithServices (serviceUUIDsString, (actionAdvertisingInfo != null), rssiOnly, clearPeripheralList);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEScanForPeripheralsWithServices (serviceUUIDsString, (actionAdvertisingInfo != null), rssiOnly, clearPeripheralList);
#elif UNITY_ANDROID
if (_android != null)
{
if (serviceUUIDsString == null)
serviceUUIDsString = "";
_android.Call ("androidBluetoothScanForPeripheralsWithServices", serviceUUIDsString, rssiOnly, recordType);
}
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void RetrieveListOfPeripheralsWithServices (string[] serviceUUIDs, Action<string, string> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
bluetoothDeviceScript.RetrievedConnectedPeripheralAction = action;
if (bluetoothDeviceScript.DiscoveredDeviceList != null)
bluetoothDeviceScript.DiscoveredDeviceList.Clear ();
}
string serviceUUIDsString = serviceUUIDs.Length > 0 ? "" : null;
foreach (string serviceUUID in serviceUUIDs)
serviceUUIDsString += serviceUUID + "|";
// strip the last delimeter
serviceUUIDsString = serviceUUIDsString.Substring (0, serviceUUIDsString.Length - 1);
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLERetrieveListOfPeripheralsWithServices (serviceUUIDsString);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLERetrieveListOfPeripheralsWithServices (serviceUUIDsString);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothRetrieveListOfPeripheralsWithServices", serviceUUIDsString);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void StopScan ()
{
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEStopScan ();
#else
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEStopScan ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothStopScan");
#endif
}
#endif
}
public static void StopBeaconScan ()
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLEStopBeaconScan ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothStopBeaconScan");
#endif
}
}
public static void DisconnectAll ()
{
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEDisconnectAll ();
#else
if (!Application.isEditor)
{
#if UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEDisconnectAll ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothDisconnectAll");
#endif
}
#endif
}
public static void ConnectToPeripheral (string name, Action<string> connectAction, Action<string, string> serviceAction, Action<string, string, string> characteristicAction, Action<string> disconnectAction = null)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
bluetoothDeviceScript.ConnectedPeripheralAction = connectAction;
bluetoothDeviceScript.DiscoveredServiceAction = serviceAction;
bluetoothDeviceScript.DiscoveredCharacteristicAction = characteristicAction;
bluetoothDeviceScript.ConnectedDisconnectPeripheralAction = disconnectAction;
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEConnectToPeripheral (name);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEConnectToPeripheral (name);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothConnectToPeripheral", name);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void DisconnectPeripheral (string name, Action<string> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.DisconnectedPeripheralAction = action;
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEDisconnectPeripheral (name);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEDisconnectPeripheral (name);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidBluetoothDisconnectPeripheral", name);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void ReadCharacteristic (string name, string service, string characteristic, Action<string, byte[]> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
if (!bluetoothDeviceScript.DidUpdateCharacteristicValueAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateCharacteristicValueAction[name] = new Dictionary<string, Action<string, byte[]>>();
#if UNITY_IOS || UNITY_TVOS || (EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX))
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] [characteristic] = action;
#elif UNITY_ANDROID
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] [FullUUID (characteristic).ToLower ()] = action;
#endif
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEReadCharacteristic (name, service, characteristic);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEReadCharacteristic (name, service, characteristic);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidReadCharacteristic", name, service, characteristic);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void WriteCharacteristic (string name, string service, string characteristic, byte[] data, int length, bool withResponse, Action<string> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.DidWriteCharacteristicAction = action;
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEWriteCharacteristic(name, service, characteristic, data, length, withResponse);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEWriteCharacteristic (name, service, characteristic, data, length, withResponse);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidWriteCharacteristic", name, service, characteristic, data, length, withResponse);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void SubscribeCharacteristic (string name, string service, string characteristic, Action<string> notificationAction, Action<string, byte[]> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
name = name.ToUpper ();
service = service.ToUpper ();
characteristic = characteristic.ToUpper ();
#if UNITY_IOS || UNITY_TVOS || (EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX))
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction [name] = new Dictionary<string, Action<string>> ();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction [name] [characteristic] = notificationAction;
if (!bluetoothDeviceScript.DidUpdateCharacteristicValueAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] = new Dictionary<string, Action<string, byte[]>> ();
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] [characteristic] = action;
#elif UNITY_ANDROID
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction [name] = new Dictionary<string, Action<string>> ();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction [name] [FullUUID (characteristic).ToLower ()] = notificationAction;
if (!bluetoothDeviceScript.DidUpdateCharacteristicValueAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] = new Dictionary<string, Action<string, byte[]>> ();
bluetoothDeviceScript.DidUpdateCharacteristicValueAction [name] [FullUUID (characteristic).ToLower ()] = action;
#endif
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLESubscribeCharacteristic (name, service, characteristic);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLESubscribeCharacteristic (name, service, characteristic);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidSubscribeCharacteristic", name, service, characteristic);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void SubscribeCharacteristicWithDeviceAddress (string name, string service, string characteristic, Action<string, string> notificationAction, Action<string, string, byte[]> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
name = name.ToUpper ();
service = service.ToUpper ();
characteristic = characteristic.ToUpper ();
#if UNITY_IOS || UNITY_TVOS || (EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX))
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name][characteristic] = notificationAction;
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name] = new Dictionary<string, Action<string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name][characteristic] = null;
if (!bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string, byte[]>>();
bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction[name][characteristic] = action;
#elif UNITY_ANDROID
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name][FullUUID (characteristic).ToLower ()] = notificationAction;
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey(name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name] = new Dictionary<string, Action<string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name][FullUUID (characteristic).ToLower ()] = null;
if (!bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string, byte[]>>();
bluetoothDeviceScript.DidUpdateCharacteristicValueWithDeviceAddressAction[name][FullUUID (characteristic).ToLower ()] = action;
#endif
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLESubscribeCharacteristic (name, service, characteristic);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLESubscribeCharacteristic (name, service, characteristic);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidSubscribeCharacteristic", name, service, characteristic);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void UnSubscribeCharacteristic (string name, string service, string characteristic, Action<string> action)
{
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
if (!Application.isEditor)
{
#endif
if (bluetoothDeviceScript != null)
{
name = name.ToUpper ();
service = service.ToUpper ();
characteristic = characteristic.ToUpper ();
#if UNITY_IOS || UNITY_TVOS || (EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX))
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name][characteristic] = null;
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name] = new Dictionary<string, Action<string>> ();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name][characteristic] = action;
#elif UNITY_ANDROID
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name] = new Dictionary<string, Action<string, string>>();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicWithDeviceAddressAction[name][FullUUID (characteristic).ToLower ()] = null;
if (!bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction.ContainsKey (name))
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name] = new Dictionary<string, Action<string>> ();
bluetoothDeviceScript.DidUpdateNotificationStateForCharacteristicAction[name][FullUUID (characteristic).ToLower ()] = action;
#endif
}
#if EXPERIMENTAL_MACOS_EDITOR && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX)
OSXBluetoothLEUnSubscribeCharacteristic (name, service, characteristic);
#elif UNITY_IOS || UNITY_TVOS
_iOSBluetoothLEUnSubscribeCharacteristic (name, service, characteristic);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidUnsubscribeCharacteristic", name, service, characteristic);
#endif
#if !UNITY_EDITOR_OSX || !EXPERIMENTAL_MACOS_EDITOR
}
#endif
}
public static void PeripheralName (string newName)
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLEPeripheralName (newName);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidPeripheralName", newName);
#endif
}
}
public static void CreateService (string uuid, bool primary, Action<string> action)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.ServiceAddedAction = action;
#if UNITY_IOS
_iOSBluetoothLECreateService (uuid, primary);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidCreateService", uuid, primary);
#endif
}
}
public static void RemoveService (string uuid)
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLERemoveService (uuid);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidRemoveService", uuid);
#endif
}
}
public static void RemoveServices ()
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLERemoveServices ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidRemoveServices");
#endif
}
}
public static void CreateCharacteristic (string uuid, CBCharacteristicProperties properties, CBAttributePermissions permissions, byte[] data, int length, Action<string, byte[]> action)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.PeripheralReceivedWriteDataAction = action;
#if UNITY_IOS
_iOSBluetoothLECreateCharacteristic (uuid, (int)properties, (int)permissions, data, length);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidCreateCharacteristic", uuid, (int)properties, (int)permissions, data, length);
#endif
}
}
public static void RemoveCharacteristic (string uuid)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.PeripheralReceivedWriteDataAction = null;
#if UNITY_IOS
_iOSBluetoothLERemoveCharacteristic (uuid);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidRemoveCharacteristic", uuid);
#endif
}
}
public static void RemoveCharacteristics ()
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLERemoveCharacteristics ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidRemoveCharacteristics");
#endif
}
}
public static void StartAdvertising (Action action)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.StartedAdvertisingAction = action;
#if UNITY_IOS
_iOSBluetoothLEStartAdvertising ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidStartAdvertising");
#endif
}
}
public static void StopAdvertising (Action action)
{
if (!Application.isEditor)
{
if (bluetoothDeviceScript != null)
bluetoothDeviceScript.StoppedAdvertisingAction = action;
#if UNITY_IOS
_iOSBluetoothLEStopAdvertising ();
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidStopAdvertising");
#endif
}
}
public static void UpdateCharacteristicValue (string uuid, byte[] data, int length)
{
if (!Application.isEditor)
{
#if UNITY_IOS
_iOSBluetoothLEUpdateCharacteristicValue (uuid, data, length);
#elif UNITY_ANDROID
if (_android != null)
_android.Call ("androidUpdateCharacteristicValue", uuid, data, length);
#endif
}
}
public static string FullUUID (string uuid)
{
if (uuid.Length == 4)
return "0000" + uuid + "-0000-1000-8000-00805F9B34FB";
return uuid;
}
}

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b8496a9b1a1df40af9ada2311d1d6d09
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -0,0 +1,43 @@
fileFormatVersion: 2
guid: 5383f7d08256547f6b36ee834b840062
folderAsset: yes
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Standalone: OSXIntel
second:
enabled: 1
settings: {}
- first:
Standalone: OSXIntel64
second:
enabled: 1
settings: {}
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 34c7c97d38c834839be439bcf96a0267
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19F101</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>BluetoothLEOSX</string>
<key>CFBundleIdentifier</key>
<string>com.shatalmic.BluetoothLEOSX</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>BluetoothLEOSX</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11E608c</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19E258</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1150</string>
<key>DTXcodeBuild</key>
<string>11E608c</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016 Shatalmic. All rights reserved.</string>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8e7811284d1734fc2ba4b29fccd3ccf7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4e9d68945c9234df3b7855f4e1006f0f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1a83baeb98e0141f587d978b89ecd37d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 673293518de2c4fbf913749ebdb36dd1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2b362acd4e35f4bb380341cd3df2b9c0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +1,5 @@
fileFormatVersion: 2
guid: 7cce98d172bfd2f4fa235200a8c37ffd
guid: 8d3303514acc04853a1fbd8393630e00
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,107 @@
//
// UnityBluetoothLE.h
// Unity-iPhone
//
// Created by Tony Pitman on 03/05/2014.
//
//
#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#if !TARGET_OS_TV
#import <CoreLocation/CoreLocation.h>
@interface UnityBluetoothLE : NSObject <CBCentralManagerDelegate, CBPeripheralManagerDelegate, CBPeripheralDelegate, CLLocationManagerDelegate>
#else
@interface UnityBluetoothLE : NSObject <CBCentralManagerDelegate, CBPeripheralManagerDelegate, CBPeripheralDelegate>
#endif
{
CBCentralManager *_centralManager;
#if !TARGET_OS_TV
CLLocationManager *_locationManager;
#endif
NSMutableDictionary *_peripherals;
#if !TARGET_OS_TV
CBPeripheralManager *_peripheralManager;
NSString *_peripheralName;
NSMutableDictionary *_services;
NSMutableDictionary *_characteristics;
#endif
NSMutableArray *_backgroundMessages;
BOOL _isPaused;
BOOL _alreadyNotified;
BOOL _isInitializing;
BOOL _rssiOnly;
int _recordType;
long _mtu;
unsigned char *_writeCharacteristicBytes;
long _writeCharacteristicLength;
long _writeCharacteristicPosition;
long _writeCharacteristicBytesToWrite;
CBCharacteristicWriteType _writeCharacteristicWithResponse;
int _writeCharacteristicRetries;
}
@property (atomic, strong) NSMutableDictionary *_peripherals;
@property (atomic) BOOL _rssiOnly;
- (void)initialize:(BOOL)asCentral asPeripheral:(BOOL)asPeripheral;
- (void)deInitialize;
- (void)scanForPeripheralsWithServices:(NSArray *)serviceUUIDs options:(NSDictionary *)options clearPeripheralList:(BOOL)clearPeripheralList recordType:(int)recordType;
- (void)stopScan;
- (void)retrieveListOfPeripheralsWithServices:(NSArray *)serviceUUIDs;
- (void)connectToPeripheral:(NSString *)name;
- (void)disconnectPeripheral:(NSString *)name;
- (CBCharacteristic *)getCharacteristic:(NSString *)name service:(NSString *)serviceString characteristic:(NSString *)characteristicString;
- (void)readCharacteristic:(NSString *)name service:(NSString *)serviceString characteristic:(NSString *)characteristicString;
- (void)writeCharacteristic:(NSString *)name service:(NSString *)serviceString characteristic:(NSString *)characteristicString data:(NSData *)data withResponse:(BOOL)withResponse;
- (void)subscribeCharacteristic:(NSString *)name service:(NSString *)serviceString characteristic:(NSString *)characteristicString;
- (void)unsubscribeCharacteristic:(NSString *)name service:(NSString *)serviceString characteristic:(NSString *)characteristicString;
- (void)writeCharactersticBytesReset;
- (void)writeCharactersticBytes:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic data:(NSData *)data withResponse:(CBCharacteristicWriteType)withResponse;
- (void)writeNextPacket:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic;
#if !TARGET_OS_TV
- (void)requestMtu:(NSString *)name mtu:(int)mtu;
- (void)scanForBeacons:(NSArray<CLBeaconRegion *> *)beaconRegions;
- (void)stopBeaconScan;
- (void)peripheralName:(NSString *)newName;
- (void)createService:(NSString *)uuid primary:(BOOL)primary;
- (void)removeService:(NSString *)uuid;
- (void)removeServices;
- (void)createCharacteristic:(NSString *)uuid properties:(CBCharacteristicProperties)properties permissions:(CBAttributePermissions)permissions value:(NSData *)value;
- (void)removeCharacteristic:(NSString *)uuid;
- (void)removeCharacteristics;
- (void)startAdvertising;
- (void)stopAdvertising;
- (void)updateCharacteristicValue:(NSString *)uuid value:(NSData *)value;
#endif
- (void)pauseMessages:(BOOL)isPaused;
- (void)sendUnityMessage:(BOOL)isString message:(NSString *)message;
+ (NSString *) base64StringFromData:(NSData *)data length:(int)length;
@end
@interface UnityMessage : NSObject
{
BOOL _isString;
NSString *_message;
}
- (void)initialize:(BOOL)isString message:(NSString *)message;
- (void)deInitialize;
- (void)sendUnityMessage;
@end

View File

@ -0,0 +1,95 @@
fileFormatVersion: 2
guid: 89fad22a839074ac08f9f7ffc9dbce4e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Linux
second:
enabled: 0
settings:
CPU: x86
- first:
'': OSXIntel
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
'': OSXIntel64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Android: Android
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
iPhone: iOS
second:
enabled: 1
settings:
CompileFlags:
FrameworkDependencies:
- first:
tvOS: tvOS
second:
enabled: 1
settings: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
fileFormatVersion: 2
guid: 6a40ca1fe2b7a48e5b257178dfdca41e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 0
- first:
: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
: OSXIntel
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
: OSXIntel64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
iPhone: iOS
second:
enabled: 1
settings:
AddToEmbeddedBinaries: false
CompileFlags: -fno-objc-arc
FrameworkDependencies: CoreBluetooth;
- first:
tvOS: tvOS
second:
enabled: 1
settings:
CompileFlags: -fno-objc-arc
FrameworkDependencies: CoreBluetooth;
userData:
assetBundleName:
assetBundleVariant:

View File

@ -11,7 +11,7 @@ using Assets.Scripts.Devices;
public static class App
{
public static string Host = "http://192.168.0.101:5084/";
public static string Host = "http://192.168.0.101:5083/";
public static string AppVersion = Application.version;

View File

@ -17,7 +17,7 @@ namespace Assets.Scripts.Devices.Ble
public abstract class BleDevice : AbstractDevice
{
protected BleWinHwInterface hwInterface;
protected IBleWinHwInterface hwInterface;
protected BlePeripheralInfo peripheralInfo;
private readonly HashSet<BleService> services = new HashSet<BleService>();
@ -32,7 +32,7 @@ namespace Assets.Scripts.Devices.Ble
}
public List<ICharacteristic> Characteristics { get; protected set; } = new List<ICharacteristic>();
public BleDevice(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface, SensorType sensor) : base(peripheralInfo.Address, NetworkType.BLE)
public BleDevice(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface, SensorType sensor) : base(peripheralInfo.Address, NetworkType.BLE)
{
this.hwInterface = bleWinHwInterface;
this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent;
@ -50,7 +50,7 @@ namespace Assets.Scripts.Devices.Ble
Characteristics.Add(new ModelNumberCharacteristic());
}
private void HwInterface_PeripheralDisconnectedEvent(BleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect)
private void HwInterface_PeripheralDisconnectedEvent(IBleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect)
{
if (!peripheral.MatchAddress(this.peripheralInfo.Address))
{
@ -93,7 +93,7 @@ namespace Assets.Scripts.Devices.Ble
}
}
private void PeripheralConnectedAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse response)
private void PeripheralConnectedAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse response)
{
Debug.Log($"连接{ this.Name }"+response.IsSuccess);
if (response.IsSuccess)
@ -123,7 +123,7 @@ namespace Assets.Scripts.Devices.Ble
Debug.Log("断开设备" + this.Name);
//App.MainDeviceAdapter.PrintStatus();
this.State = DeviceState.Disconnected;
this.hwInterface.DisconnectPeripheral(this.peripheralInfo, () => {
//App.MainDeviceAdapter.PrintStatus();
@ -136,7 +136,7 @@ namespace Assets.Scripts.Devices.Ble
private void ServicesDiscoveredAction(BleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response)
private void ServicesDiscoveredAction(IBleWinHwInterface hwInterface, BlePeripheralInfo sender, BleResponse<List<BleServiceInfo>> response)
{
//Debug.Log("搜索service");
if(!response.IsSuccess || !response.Data.Any())
@ -211,7 +211,7 @@ namespace Assets.Scripts.Devices.Ble
{
}
private void BluetoothStateChangedEvent(BleWinHwInterface hwInterface, BleState state)
private void BluetoothStateChangedEvent(IBleWinHwInterface hwInterface, BleState state)
{
switch (state)
{

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Ble.Service;
using Assets.Scripts.Devices.Ble.Devices;
using Assets.Scripts.Devices.Ble.Interfaces;
using Assets.Scripts.UI.Prefab.Device;
using System;
using System.Collections.Generic;
@ -17,15 +18,16 @@ namespace Assets.Scripts.Devices.Ble
private IDictionary<string, BleDevice> discoveredDevices = new Dictionary<string, BleDevice>();
private BleWinHwInterface hwInterface;
public BleDeviceAdapter()
private IBleWinHwInterface hwInterface { get; set; }
public BleDeviceAdapter(IBleWinHwInterface bleWinHwInterface)
{
hwInterface = BleWinHwInterface.GetInterface();
hwInterface = bleWinHwInterface;// BleWinHwInterface.GetInterface();
hwInterface.BluetoothStateChangedEvent += HwInterface_BluetoothStateChangedEvent;
}
private void HwInterface_BluetoothStateChangedEvent(BleWinHwInterface hwInterface, BleState bleState)
private void HwInterface_BluetoothStateChangedEvent(IBleWinHwInterface hwInterface, BleState bleState)
{
//Debug.Log("22222222222222" + bleState);
if(bleState == BleState.Off)

View File

@ -37,5 +37,10 @@ namespace Assets.Scripts.Devices.Ble
{
return base.ToString() + "\n" + this.Data;
}
}
public static implicit operator BleResponse<T>(BleResponse<List<BleServiceInfo>> v)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,6 +7,6 @@ using System.Threading.Tasks;
namespace Assets.Scripts.Ble
{
public delegate void BluetoothStateChangedCallback(BleWinHwInterface hwInterface, BleState bleState);
public delegate void BluetoothStateChangedCallback(IBleWinHwInterface hwInterface, BleState bleState);
}

View File

@ -1,4 +1,5 @@
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,5 +8,5 @@ using System.Threading.Tasks;
namespace Assets.Scripts.Ble
{
public delegate void CharacteristicReadCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response);
public delegate void CharacteristicReadCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response);
}

View File

@ -1,4 +1,5 @@
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,5 +8,5 @@ using System.Threading.Tasks;
namespace Assets.Scripts.Ble
{
public delegate void CharacteristicsDiscoveredCallback(BleWinHwInterface hwInterface, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response);
public delegate void CharacteristicsDiscoveredCallback(IBleWinHwInterface hwInterface, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response);
}

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -14,7 +15,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
{
private List<BleServiceInfo> Services;
private CyclingPowerMeasurement cyclingPowerMeasurement;
public CyclingPower(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Power)
public CyclingPower(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Power)
{
Priority = 2;
cyclingPowerMeasurement = new CyclingPowerMeasurement(1920);
@ -49,7 +50,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
//Debug.Log("power main call" + string.Join(",", response.Data));

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -21,7 +22,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
private List<BleServiceInfo> Services;
private BleCharacteristicInfo controlPointCharacteristic;
public Ftms(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
public Ftms(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
{
this._ftmsIndoorBikeData = new FtmsIndoorBikeData();
base.Characteristics.Add(this._ftmsIndoorBikeData);
@ -60,7 +61,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
}
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
foreach (var item in base.Characteristics)
{

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -16,7 +17,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
private List<BleServiceInfo> Services;
private HeartRateMeasurement heartRateMeasurement;
public HeartRate(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.HeartRate)
public HeartRate(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.HeartRate)
{
Priority = 2;
heartRateMeasurement = new HeartRateMeasurement();
@ -73,7 +74,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
});
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
//Debug.Log("heart rate main call" + string.Join(",", response.Data));

View File

@ -1,6 +1,7 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -18,7 +19,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
private double _wheelCircumference;
private List<BleServiceInfo> Services;
public SpeedCadence(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.SpeedCadence)
public SpeedCadence(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.SpeedCadence)
{
Debug.Log("创建速度踏频设备");
Priority = 1;
@ -81,7 +82,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
//Debug.Log("power main call" + string.Join(",", response.Data));

View File

@ -2,6 +2,7 @@
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -30,7 +31,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
/// </summary>
private double _grade = 0;
public Tacx(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
public Tacx(BlePeripheralInfo peripheralInfo, IBleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
{
tacxFecNotify = new TacxFecNotify();
base.Characteristics.Add(tacxFecNotify);
@ -75,7 +76,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
}
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
foreach (var item in base.Characteristics)
{

View File

@ -2,6 +2,7 @@
using Assets.Scripts.Ble.Service;
using Assets.Scripts.Commands;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -36,12 +37,12 @@ namespace Assets.Scripts.Ble.HeartRate
}
}
private void HrmCharacteristicSubscribed(BleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse response)
private void HrmCharacteristicSubscribed(IBleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse response)
{
}
private void HrmCharacteristicRead(BleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void HrmCharacteristicRead(IBleWinHwInterface winHwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
HeartRateMeasurementValue heartRateMeasurementValue;
if(base.CheckCharacteristicResponse<HeartRateMeasurementValue>(characteristic, response, (BleCharacteristicInfo info, BleResponse<byte[]> bleResponse) => new HeartRateMeasurementValue(bleResponse.Data), out heartRateMeasurementValue) != CommandResponseCode.Success)

View File

@ -0,0 +1,28 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Ble.Scan;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assets.Scripts.Devices.Ble.Interfaces
{
public interface IBleWinHwInterface
{
void StartScan(Action<BleAdvertisementInfo> discoveredCallBack);
void ConnectPeripheral(BlePeripheralInfo info, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse> callback);
void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback);
void DiscoverServices(BlePeripheralInfo peripheral, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>> callback);
void DiscoverCharacteristic(BleServiceInfo service, CharacteristicsDiscoveredCallback callback);
void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse> callback);
void WriteCharacteristic(BleCharacteristicInfo characteristic, byte[] data);
void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback);
void Dispose();
BleState BleState { get; set; }
Dictionary<string, BleAdvertisementInfo> pCache { get; set; }
event BluetoothStateChangedCallback BluetoothStateChangedEvent;
event CharacteristicReadCallback CharacteristicReadEvent;
event PeripheralDisconnectedCallback PeripheralDisconnectedEvent;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86216427171ac784296ca577b921b2e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,5 +8,5 @@ using System.Threading.Tasks;
namespace Assets.Scripts.Devices.Ble
{
public delegate void PeripheralDisconnectedCallback(BleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect);
public delegate void PeripheralDisconnectedCallback(IBleWinHwInterface hwInterface, BlePeripheralInfo peripheral, BleResponse response, bool manualDisconnect);
}

View File

@ -8,6 +8,7 @@ using Assets.Scripts.Ble.Commands;
using Assets.Scripts.Commands;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Extension;
using Assets.Scripts.Devices.Ble.Interfaces;
using UnityEngine;
namespace Assets.Scripts.Ble.Service
@ -18,7 +19,7 @@ namespace Assets.Scripts.Ble.Service
private BleServiceInfo serviceInfo;
private List<BleCharacteristicInfo> characteristics;
private readonly Dictionary<Guid, Action<BleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>>> registeredCharacteristicReadEvents = new Dictionary<Guid, Action<BleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>>>();
private readonly Dictionary<Guid, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>>> registeredCharacteristicReadEvents = new Dictionary<Guid, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>>>();
public IReadOnlyList<BleCharacteristicInfo> Characteristics
{
@ -58,7 +59,7 @@ namespace Assets.Scripts.Ble.Service
this.hwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
}
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
private void CharacteristicReadMainCallback(IBleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
{
//Debug.Log("read main callback");
if (this.registeredCharacteristicReadEvents.ContainsKey(characteristic.Id) && characteristic.Service.Equals(this.serviceInfo))
@ -79,7 +80,7 @@ namespace Assets.Scripts.Ble.Service
this.CheckCharacteristicDiscoveredResponse(this.hwInterface, this.serviceInfo, scanCharacteristicsResponse);
}
private void CheckCharacteristicDiscoveredResponse(BleWinHwInterface hwInterface, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response)
private void CheckCharacteristicDiscoveredResponse(IBleWinHwInterface hwInterface, BleServiceInfo service, BleResponse<List<BleCharacteristicInfo>> response)
{
if (!service.Equals(this.serviceInfo))
{
@ -98,8 +99,8 @@ namespace Assets.Scripts.Ble.Service
protected abstract void CharacteristicsDiscovered(BleResponse<List<BleCharacteristicInfo>> response);
protected void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<BleWinHwInterface, BleCharacteristicInfo, BleResponse> notificationCallback,
Action<BleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>> readCallback)
protected void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse> notificationCallback,
Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse<byte[]>> readCallback)
{
this.hwInterface.SubscribeCharacteristic(characteristic, (hw, info, response) =>
{

View File

@ -2,6 +2,7 @@
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using Assets.Scripts.Devices.Ble.Win;
using System;
using System.Collections.Generic;
@ -12,13 +13,24 @@ using UnityEngine;
namespace Assets.Scripts.Ble
{
public sealed class BleWinHwInterface
public sealed class BleWinHwInterface: IBleWinHwInterface
{
private static BleWinHwInterface hwInterface;
private WclBleMainThread wclBleMainThread;
public readonly Dictionary<string, BleAdvertisementInfo> pCache = new Dictionary<string, BleAdvertisementInfo>();
private Dictionary<string, BleAdvertisementInfo> _pCache;
public Dictionary<string, BleAdvertisementInfo> pCache
{
get
{
if (_pCache == null)
{
_pCache = new Dictionary<string, BleAdvertisementInfo>();
}
return _pCache;
}
set { _pCache = value; }
}
private Action<BleAdvertisementInfo> _discoveredCallback;
private Dictionary<BlePeripheralInfo, Action<BleWinHwInterface, BlePeripheralInfo, BleResponse>> callbacks = new Dictionary<BlePeripheralInfo, Action<BleWinHwInterface, BlePeripheralInfo, BleResponse>>();
@ -43,6 +55,7 @@ namespace Assets.Scripts.Ble
}
}
private BluetoothStateChangedCallback bluetoothStateChanged;
public event BluetoothStateChangedCallback BluetoothStateChangedEvent
{
@ -55,7 +68,7 @@ namespace Assets.Scripts.Ble
this.bluetoothStateChanged -= value;
}
}
private BleState nativeState;
public BleState BleState
{
@ -63,7 +76,7 @@ namespace Assets.Scripts.Ble
{
return this.nativeState;
}
private set
set
{
if(this.nativeState != value)
{
@ -201,7 +214,7 @@ namespace Assets.Scripts.Ble
return wclBleGattThread;
}
internal void ConnectPeripheral(BlePeripheralInfo info, Action<BleWinHwInterface, BlePeripheralInfo, BleResponse> callback)
public void ConnectPeripheral(BlePeripheralInfo info, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse> callback)
{
this.callbacks.Add(info, callback);
WclBleGattThread wclBleGattThread = this.wclBleMainThread.GetGattThread(info);
@ -229,8 +242,8 @@ namespace Assets.Scripts.Ble
//});
}
internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
public void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
{
var gattThread = this.wclBleMainThread.GetGattThread(peripheral);
if(gattThread != null && gattThread.CanLoadWork)
@ -372,7 +385,7 @@ namespace Assets.Scripts.Ble
}
}
public void DiscoverServices(BlePeripheralInfo peripheral, Action<BleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>> callback)
public void DiscoverServices(BlePeripheralInfo peripheral, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>> callback)
{
WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(peripheral);
if(gattThread == null)
@ -420,7 +433,7 @@ namespace Assets.Scripts.Ble
this.GattCharacteristicsDiscovered(gattThread, service, response);
}
public void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<BleWinHwInterface, BleCharacteristicInfo, BleResponse> callback)
public void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse> callback)
{
WclBleGattThread gattThread = this.wclBleMainThread.GetGattThread(characteristic.Peripheral);

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9fa2f8906f5360c47b807eaef8d42263
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,399 @@
using Assets.Scripts.Ble.Scan;
using Assets.Scripts.Ble.Win;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using Assets.Scripts.Devices.Ble.Win;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Ble
{
public sealed class BleMobileInterface : IBleWinHwInterface
{
private static BleMobileInterface hwInterface;
private BleMobileThread bleMobileThread;
private Dictionary<string, BleAdvertisementInfo> _pCache;
public Dictionary<string, BleAdvertisementInfo> pCache
{
get
{
if (_pCache == null)
{
_pCache = new Dictionary<string, BleAdvertisementInfo>();
}
return _pCache;
}
set { _pCache = value; }
}
private Action<BleAdvertisementInfo> _discoveredCallback;
private Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse>> callbacks = new Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse>>();
private Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>>> servicesCallbacks = new Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>>>();
//private Dictionary<BlePeripheralInfo, Action<BleWinHwInterface, BleServiceInfo, BleResponse<List<BleCharacteristicInfo>>>> characteristicsCallbacks = new Dictionary<BlePeripheralInfo, Action<BleWinHwInterface, BleServiceInfo, BleResponse<List<BleCharacteristicInfo>>>>();
private Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse>> characteristicNotificationCallbacks = new Dictionary<BlePeripheralInfo, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse>>();
private Dictionary<BleCharacteristicInfo, CharacteristicReadCallback> characteristicReadCallbacks = new Dictionary<BleCharacteristicInfo, CharacteristicReadCallback>();
private Dictionary<BleServiceInfo, CharacteristicsDiscoveredCallback> characteristicsDiscoveredCallbacks = new Dictionary<BleServiceInfo, CharacteristicsDiscoveredCallback>();
private Dictionary<BlePeripheralInfo, Action> disconnectedCallback = new Dictionary<BlePeripheralInfo, Action>();
private CharacteristicReadCallback characteristicReadEvent;
public event CharacteristicReadCallback CharacteristicReadEvent
{
add
{
this.characteristicReadEvent += value;
}
remove
{
this.characteristicReadEvent -= value;
}
}
private BluetoothStateChangedCallback bluetoothStateChanged;
public event BluetoothStateChangedCallback BluetoothStateChangedEvent
{
add
{
this.bluetoothStateChanged += value;
}
remove
{
this.bluetoothStateChanged -= value;
}
}
private BleState nativeState;
public BleState BleState
{
get
{
return this.nativeState;
}
set
{
if (this.nativeState != value)
{
this.nativeState = value;
this.bluetoothStateChanged?.Invoke(this, this.nativeState);
}
}
}
private PeripheralDisconnectedCallback peripheralDisconnectedEvent;
public event PeripheralDisconnectedCallback PeripheralDisconnectedEvent
{
add
{
this.peripheralDisconnectedEvent += value;
}
remove
{
this.peripheralDisconnectedEvent -= value;
}
}
private BleMobileInterface()
{
bleMobileThread = new BleMobileThread();
bleMobileThread.ManagerInitialized += BleMobileThread_ManagerInitialized;
bleMobileThread.ManagerStatusChanged += ManagerStatusChanged;
bleMobileThread.ScanInfoReceived += WatcherScanInfoReceived;
}
private void BleMobileThread_ManagerInitialized(BleMobileThread thread)
{
this.BleState = BleState.On;
}
private void ManagerStatusChanged(BleMobileThread sender, WclBleManagerStatus status)
{
this.BleState = BleMobileInterface.StateFromNativeState(status);
}
private void WatcherScanInfoReceived(BleMobileThread sender, string address, string name, int rssi,string[] uuids)
{
SensorType sensor = SensorType.None;
List<Guid> services = new List<Guid>();
if (uuids != null && uuids.Length > 0)
{
foreach (var item in uuids)
{
services.Add(new Guid(item));
}
foreach (var item in ServiceUuids.Services)
{
if (!uuids.Contains(item.IdGuid.ToString()))
{
continue;
}
if (item.IdByteArray == ServiceUuids.Ftms)
{
sensor = SensorType.Trainer;
}
else if (item.IdByteArray == ServiceUuids.HeartRate)
{
sensor = SensorType.HeartRate;
}
else if (item.IdByteArray == ServiceUuids.CyclingPower)
{
sensor = SensorType.Power;
//sensor = SensorType.Trainer;
}
else if (item.IdByteArray == ServiceUuids.CyclingSpeedCadence)
{
sensor = SensorType.SpeedCadence;
}
else if (item.IdByteArray == ServiceUuids.TacxBle)
{
sensor = SensorType.Trainer;
}
}
};
var addressStr = address;
if (!pCache.ContainsKey(addressStr))
{
var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(addressStr, name), rssi, true, services, null, sensor);
pCache.Add(addressStr, device);
}
if (!string.IsNullOrWhiteSpace(name))
{
(pCache[addressStr].Peripheral as WinBlePeripheralInfo).SetName(name);
}
if (sensor == SensorType.None)
{
return;
}
pCache[addressStr].SensorType = sensor;
pCache[addressStr].Rssi = rssi;
//Debug.Log(sensor);
//pCache[address.ToString()].SensorType = sensor;
foreach (var item in uuids)
{
pCache[addressStr].TryAddService(new Guid(item));
}
pCache[addressStr].Index++;
if (pCache[addressStr].SensorType == SensorType.Power && pCache[addressStr].Services.Any(s => s.Equals(ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid)))
{
pCache[addressStr].SensorType = SensorType.Trainer;
//Debug.Log("纠正为trainer, "+ pCache[address.ToString()].Index);
}
if (pCache[addressStr].SensorType == SensorType.Power)
{
if (pCache[addressStr].Index > 4)
{
_discoveredCallback?.Invoke(pCache[addressStr]);
}
}
else if (pCache[addressStr].SensorType != SensorType.None)
{
_discoveredCallback?.Invoke(pCache[addressStr]);
}
}
//private WclBleGattThread SetUpGattClient(BlePeripheralInfo peripheral)
//{
// WclBleGattThread wclBleGattThread = this.wclBleMainThread.CreateGattThread(peripheral);
// wclBleGattThread.GattConnected += this.GattConnected;
// wclBleGattThread.GattDisconnected += this.GattDisconnected;
// wclBleGattThread.GattServicesDiscovered += this.GattServicesDiscovered;
// wclBleGattThread.GattCharacteristicsDiscovered += this.GattCharacteristicsDiscovered;
// wclBleGattThread.GattCharacteristicSubscribed += this.GattCharacteristicSubscribed;
// wclBleGattThread.GattCharacteristicRead += this.GattCharacteristicRead;
// wclBleGattThread.GattCharacteristicWrote += this.GattCharacteristicWrote;
// wclBleGattThread.GattCharacteristicChanged += this.GattCharacteristicChanged;
// wclBleGattThread.Start();
// return wclBleGattThread;
//}
List<BleServiceInfo> servicelist = new List<BleServiceInfo>();
List<BleCharacteristicInfo> characteristilist = new List<BleCharacteristicInfo>();
public void ConnectPeripheral(BlePeripheralInfo info, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse> callback)
{
BleResponse s = new BleResponse();
s.IsSuccess = true;
s.Error = null;
var self = this;
BluetoothLEHardwareInterface.ConnectToPeripheral(info.Address, (address) =>
{
callback?.Invoke(self, info, s);
}, (address, service) => {
if (servicesCallbacks.Where(c => c.Key.Address == address).Any())
{
var serviceCallback = servicesCallbacks.Where(c => c.Key.Address == address).FirstOrDefault();
List<BleServiceInfo> servicelist = new List<BleServiceInfo>();
servicelist.Add(new WinBleServiceInfo(serviceCallback.Key,new Guid(service)));
BleResponse<List<BleServiceInfo>> response = new BleResponse<List<BleServiceInfo>>
{
IsSuccess = true,
Error = null,
Data = servicelist,
};
serviceCallback.Value?.Invoke(this, serviceCallback.Key, response);
}
}, (address, service, characteristic) =>
{
if (characteristicsDiscoveredCallbacks.Where(c => c.Key.Peripheral.Address == address).Any())
{
var characteristicCallback = characteristicsDiscoveredCallbacks.Where(c => c.Key.Peripheral.Address == address).FirstOrDefault();
List<BleCharacteristicInfo> characteristiclist = new List<BleCharacteristicInfo>();
characteristiclist.Add(new WinBleCharacteristicInfo(new Guid(characteristic), new WinBleServiceInfo(characteristicCallback.Key.Peripheral, new Guid(service)),0));
BleResponse<List<BleCharacteristicInfo>> response = new BleResponse<List<BleCharacteristicInfo>>
{
IsSuccess = true,
Error = null,
Data = characteristiclist,
};
characteristicCallback.Value?.Invoke(this, characteristicCallback.Key, response);
}
}, null);
}
//设备断开连接
public void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
{
BluetoothLEHardwareInterface.DisconnectPeripheral(peripheral.Address, (address) =>
{
//peripheralDisconnectedEvent(this, peripheral, null, true);
callback?.Invoke();
});
}
public static BleMobileInterface GetInterface()
{
if(hwInterface == null)
{
hwInterface = new BleMobileInterface();
}
return hwInterface;
}
//扫描设备
public void StartScan(Action<BleAdvertisementInfo> discoveredCallBack)
{
pCache.Clear();
_discoveredCallback = discoveredCallBack;
bleMobileThread.StartWatcher();
}
//发现服务列表
public void DiscoverServices(BlePeripheralInfo peripheral, Action<IBleWinHwInterface, BlePeripheralInfo, BleResponse<List<BleServiceInfo>>> callback)
{
this.servicesCallbacks.Add(peripheral, callback);
}
//发现特征值
public void DiscoverCharacteristic(BleServiceInfo service, CharacteristicsDiscoveredCallback callback)
{
this.characteristicsDiscoveredCallbacks.Add(service, callback);
}
//订阅特征值
public void SubscribeCharacteristic(BleCharacteristicInfo characteristic, Action<IBleWinHwInterface, BleCharacteristicInfo, BleResponse> callback)
{
this.characteristicNotificationCallbacks.Add(characteristic.Peripheral, callback);
BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(characteristic.Peripheral.Address, characteristic.Service.ToString(), characteristic.Id.ToString(), null, (deviceAddress, characteristric, bytes) =>
{
if (characteristicReadEvent != null)
{
BleResponse<byte[]> response = new BleResponse<byte[]>
{
IsSuccess = true,
Error = null,
Data = bytes,
};
characteristicReadEvent.Invoke(this, characteristic, response);
}
});
}
//写入特征值
public void WriteCharacteristic(BleCharacteristicInfo characteristic, byte[] data)
{
BluetoothLEHardwareInterface.WriteCharacteristic(characteristic.Peripheral.Address, characteristic.Service.Id.ToString(), characteristic.Id.ToString(), data, data.Length, false, (characteristicUUID) => {
BluetoothLEHardwareInterface.Log("Write Succeeded");
});
}
public void Dispose()
{
bleMobileThread.ManagerInitialized -= BleMobileThread_ManagerInitialized;
bleMobileThread.ManagerStatusChanged -= ManagerStatusChanged;
bleMobileThread.ScanInfoReceived -= WatcherScanInfoReceived;
bleMobileThread.Stop();
bleMobileThread = null;
hwInterface = null;
pCache.Clear();
}
public void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback)
{
BluetoothLEHardwareInterface.ReadCharacteristic(characteristic.Peripheral.Address, characteristic.Service.Id.ToString(), characteristic.Id.ToString(), (c, bytes) => {
BleResponse<byte[]> response = new BleResponse<byte[]>
{
IsSuccess = true,
Error = null,
Data = bytes,
};
callback?.Invoke(this, characteristic, response);
});
}
private static BleState StateFromNativeState(WclBleManagerStatus status)
{
switch (status)
{
case WclBleManagerStatus.RadioOff:
return BleState.Off;
case WclBleManagerStatus.RadioOn:
return BleState.On;
case WclBleManagerStatus.Unknown:
return BleState.Unknown;
default:
return BleState.Unavailable;
}
}
private class WinBlePeripheralInfo : BlePeripheralInfo
{
// Token: 0x06003F35 RID: 16181 RVA: 0x000E9FBF File Offset: 0x000E81BF
public WinBlePeripheralInfo(string address, string name) : base(address, name)
{
}
// Token: 0x06003F36 RID: 16182 RVA: 0x000E9FC9 File Offset: 0x000E81C9
public void SetName(string name)
{
base.Name = name;
}
}
private class WinBleServiceInfo : BleServiceInfo
{
// Token: 0x06003F86 RID: 16262 RVA: 0x000EA27F File Offset: 0x000E847F
public WinBleServiceInfo(BlePeripheralInfo peripheral, Guid id) : base(id, peripheral)
{
}
}
private class WinBleCharacteristicInfo : BleCharacteristicInfo
{
// Token: 0x06003F86 RID: 16262 RVA: 0x000EA27F File Offset: 0x000E847F
public WinBleCharacteristicInfo(Guid id, BleServiceInfo service, BleCharacteristicProperties properties) : base(id,service, properties)
{
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e5257ea169e69a498a3e4d935a51306
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,80 @@
using Assets.Scripts.Ble;
using System.Timers;
namespace Assets.Scripts.Devices.Ble
{
internal class BleMobileThread
{
public delegate void WclInitializedDelegate(BleMobileThread sender);
private BleMobileThread.WclInitializedDelegate managerInitialized;
public event BleMobileThread.WclInitializedDelegate ManagerInitialized
{
add
{
this.managerInitialized += value;
}
remove
{
this.managerInitialized -= value;
}
}
public delegate void WclAdvertisementPacketDelegate(BleMobileThread sender, string address, string name, int rssi, string[] uuids);
public BleMobileThread.WclAdvertisementPacketDelegate ScanInfoReceived;
internal delegate void ManagerStatusChangedCallback(BleMobileThread thread, WclBleManagerStatus status);
private BleMobileThread.ManagerStatusChangedCallback managerStatusChanged;
public event BleMobileThread.ManagerStatusChangedCallback ManagerStatusChanged
{
add
{
this.managerStatusChanged += value;
}
remove
{
this.managerStatusChanged -= value;
}
}
internal BleMobileThread() {
var self = this;
//初始蓝牙
BluetoothLEHardwareInterface.Initialize(true, false, () => {
managerInitialized?.Invoke(self);
},
(error) => {
BluetoothLEHardwareInterface.Log("Error: " + error);
if (error.Contains("Bluetooth LE Not Enabled"))
BluetoothLEHardwareInterface.BluetoothEnable(true);
}, (status) => {
var statusEnum = WclBleManagerStatus.RadioOn;
switch (status)
{
case 13:
statusEnum = WclBleManagerStatus.RadioOff;
break;
case 11:
statusEnum = WclBleManagerStatus.RadioOn;
break;
}
if (managerStatusChanged != null)
{
managerStatusChanged.Invoke(self, statusEnum);
}
});
}
public void StartWatcher() {
BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null, null, (address, name, rssi, bytes) =>
{
ScanInfoReceived?.Invoke(this, address, name, rssi, bytes);
}, true);
}
public void Stop()
{
BluetoothLEHardwareInterface.StopScan();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cec5e50ac67fde54196ea58f5b1b790b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ble;
using System;
using System.Collections.Generic;
@ -14,10 +15,12 @@ namespace Assets.Scripts.Devices
private List<DeviceAdapter> adapters = new List<DeviceAdapter>();
public MainDeviceAdapter()
{
#if !(UNITY_IOS || UNITY_ANDROID)
this.CreateAntAdapter();
#if UNITY_IOS || UNITY_TVOS || UNITY_ANDROID
this.CreateBleAdapter();
#endif
#else
this.CreateBleAdapter();
this.CreateAntAdapter();
#endif
}
private void CreateAntAdapter()
@ -27,7 +30,11 @@ namespace Assets.Scripts.Devices
private void CreateBleAdapter()
{
adapters.Add(new BleDeviceAdapter());
#if UNITY_IOS || UNITY_TVOS || UNITY_ANDROID
adapters.Add(new BleDeviceAdapter(BleMobileInterface.GetInterface()));
#else
adapters.Add(new BleDeviceAdapter(BleWinHwInterface.GetInterface()));
#endif
}
public void StartScan()

View File

@ -330,6 +330,7 @@ public class LoginController : MonoBehaviour
{
wxReturnLogin();
});
#if !(UNITY_IOS || UNITY_ANDROID)
wxBrowser = wxLogin1.Find("Browser (GUI)").GetComponent<Browser>();
if (wxBrowser != null)
{
@ -941,7 +942,9 @@ public class LoginController : MonoBehaviour
void wxReturnLogin()
{
wxLock = true;
#if !(UNITY_IOS || UNITY_ANDROID)
wxBrowser.LoadHTML("<div/>");
#endif
//wxBrowser.Url = "chrome://version/";
wxLogin1.DOLocalMoveY(-573, 0.3f).onComplete = () =>
{

View File

@ -56,7 +56,7 @@ namespace Assets.Scenes.Ride.Scripts
weight = App.CurrentUser.Weight;
bicycleWeight = App.CurrentUser.BicycleWeight;
//#if UNITY_EDITOR
power = 500;
//power = 500;
//#endif
mainController.TrackResistance(currentSlope * App.RideSetting.Sensitivity / 100);
}

8
Assets/Shatalmic.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fcef0f33b95c6fd4d9b2f5a0dcd0d564
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

439
Assets/Shatalmic/Demo.unity Normal file
View File

@ -0,0 +1,439 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &53270293
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 53270296}
- component: {fileID: 53270295}
- component: {fileID: 53270294}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &53270294
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 53270293}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &53270295
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 53270293}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &53270296
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 53270293}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &344612123
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 344612127}
- component: {fileID: 344612126}
- component: {fileID: 344612125}
- component: {fileID: 344612124}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &344612124
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 344612123}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &344612125
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 344612123}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!223 &344612126
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 344612123}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &344612127
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 344612123}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 601672577}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!1 &601672576
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 601672577}
- component: {fileID: 601672579}
- component: {fileID: 601672578}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &601672577
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 601672576}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 344612127}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &601672578
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 601672576}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 72
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 7
m_MaxSize: 72
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Due to the new Unity asset publishing requirements you must follow the instructions
in the README file to unpack this plugin.
--- !u!222 &601672579
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 601672576}
m_CullTransparentMesh: 0
--- !u!1 &1655223073
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1655223076}
- component: {fileID: 1655223075}
- component: {fileID: 1655223074}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1655223074
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1655223073}
m_Enabled: 1
--- !u!20 &1655223075
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1655223073}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 1, g: 1, b: 1, a: 0}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_GateFitMode: 2
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1655223076
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1655223073}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0149d806ed996492787b9cb44993fd5b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 87247c18c42564aceaf454206a3ef873
folderAsset: yes
DefaultImporter:
userData:

View File

@ -0,0 +1,30 @@
#if UNITY_IOS
using UnityEditor.Callbacks;
using UnityEditor;
using UnityEditor.iOS.Xcode;
using System.IO;
public class BluetoothPostProcessBuild
{
[PostProcessBuild]
public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
{
if (buildTarget == BuildTarget.iOS)
{
// Get plist
string plistPath = pathToBuiltProject + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
// Get root
PlistElementDict rootDict = plist.root;
rootDict.SetString("NSBluetoothPeripheralUsageDescription", "Uses BLE to communicate with devices.");
rootDict.SetString("NSBluetoothAlwaysUsageDescription", "Uses BLE to communicate with devices.");
// Write to file
File.WriteAllText(plistPath, plist.WriteToString());
}
}
}
#endif

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1695b640ed1354053a8cdd9e0186f57f
timeCreated: 1493664761
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,93 @@
#!/usr/bin/perl
use File::Copy;
print ("\n*** Starting PostprocessBuildPlayer ***\n");
my $installPath = $ARGV[0];
#values to watch for already existing
my $requiredDeviceCapsString = "UIRequiredDeviceCapabilities";
my $backgroundModesString = "UIBackgroundModes";
my $bluetoothLEString = "bluetooth-le";
#go through the info.plist file line by line until you find this one:
my $endOfPlist = "</dict>";
# The type of player built:
# "dashboard", "standaloneWin32", "standaloneOSXIntel", "standaloneOSXPPC", "standaloneOSXUniversal", "webplayer", "iPhone"
my $target = $ARGV[1];
print ("\n*** PostprocessBuildPlayer - Building at '$installPath' with target: $target ***\n");
################################################################
# This modifies info.plist to add the external accessory #
# entries #
################################################################
#open this file
$oplistPath = $installPath."/Info.plist";
$nplistPath = $installPath."/Info.plist.tmp";
open OLDPLIST, "<", $oplistPath or die("Cannot open Info.plist");
open NEWPLIST, ">", $nplistPath or die("Cannot create new Info.plist");
my $nextLine = 0;
my $requiredDeviceCapsFound = 0;
my $backgroundModesFound = 0;
while(<OLDPLIST>)
{
if ($nextLine == 1)
{
if ($_ =~ m/$bluetoothLEString/)
{
}
else
{
$_ =~ s|</array>|\n\t<string>bluetooth-le</string></array>|
}
$nextLine = 0;
}
################################################################
# Check for required device caps string already exists #
################################################################
if ($_ =~ m/$requiredDeviceCapsString/ )
{
$nextLine = 1;
}
################################################################
# Check for background modes string already exists #
################################################################
if ($_ =~ m/$backgroundModesString/ )
{
$backgroundModesFound = 1;
}
################################################################
# Add any key/value pairs you want at the end of Info.plist #
################################################################
if ($_ =~ m/$endOfPlist/ && $backgrounModesFound == 0)
{
my $keys = "";
$keys .= " <key>UIBackgroundModes</key>\n";
$keys .= " <array>\n";
$keys .= " <string>bluetooth-central</string>\n";
$keys .= " <string>bluetooth-peripheral</string>\n";
$keys .= " </array>\n";
$_ = $keys . $_;
}
print NEWPLIST $_;
}
close OLDPLIST;
close NEWPLIST;
`mv \'$nplistPath\' \'$oplistPath\'`;

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 3c726eecf85fe4a88a7e7d57812ff455
timeCreated: 1515198229
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1 @@
You must double click on the unity package file called Plugin.unitypackage in order to unpack the plugin files.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3465e0116537642f78e4b288b23c461c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1a70f37e2f13e4df0ac477f3c3eb451b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: