powerfun-unity/Assets/Scripts/Devices/Ble/Win/WclBleGattClient.cs

260 lines
9.9 KiB
C#

using Assets.Scripts.Ble.Win.CPPBridge;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace Assets.Scripts.Ble.Win
{
internal class WclBleGattClient
{
public WclBleGattClient(long address, IntPtr radio)
{
this.gattAddress = address;
this.rPtr = radio;
this.CConnectEvent = new WclBleGattClient.GATTCLIENT_CONNECT(this.OnConnected);
this.CDisconnectEvent = new WclBleGattClient.GATTCLIENT_DISCONNECT(this.OnDisconnected);
this.FCharacteristicChangedEvent = new WclBleGattClient.GATTCLIENT_ONCHANGED(this.OnCharacteristicChanged);
this.mPtr = WclBleGattClient.WCLGattClientCreate(this.CConnectEvent, this.CDisconnectEvent, this.FCharacteristicChangedEvent);
}
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientConnect([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr Radio, [MarshalAs(UnmanagedType.I8)][In] long Address);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.SysInt)]
private static extern IntPtr WCLGattClientCreate([MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_CONNECT OnConnect, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_DISCONNECT OnDisconnect, [MarshalAs(UnmanagedType.FunctionPtr)][In] WclBleGattClient.GATTCLIENT_ONCHANGED OnChanged);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
private static extern void WCLGattClientDestroy([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientDisconnect([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
private static extern void WCLGattClientFreeMem([MarshalAs(UnmanagedType.SysInt)][In] IntPtr pMem);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientGetCharacteristics([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattService Service, [In][Out] ref GattCharacteristics Chars);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientGetServices([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In][Out] ref GattServices Services);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.U4)]
private static extern WclBleGattClientState WCLGattClientGetState([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientReadCharacteristicValue([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char, [MarshalAs(UnmanagedType.SysInt)][In][Out] ref IntPtr ppValue, [MarshalAs(UnmanagedType.U4)][In][Out] ref uint pSize);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientSubscribeCharacteristic([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientUnsubscribeCharacteristic([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char);
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.I4)]
private static extern int WCLGattClientWriteCharacteristicValue([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Client, [In] ref GattCharacteristic Char, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr pValue, [MarshalAs(UnmanagedType.U4)][In] uint Size);
public WclBleGattClientState State
{
get
{
return WclBleGattClient.WCLGattClientGetState(this.mPtr);
}
}
public void Connect()
{
if (this.mPtr != IntPtr.Zero)
{
int num = WclBleGattClient.WCLGattClientConnect(this.mPtr, this.rPtr, this.gattAddress);
if (num != 0)
{
this.OnConnected(this.mPtr, num);
}
}
}
public void Disconnect()
{
if (this.mPtr != IntPtr.Zero)
{
//WclBleGattClient.log.Info("Disconnect called", Array.Empty<object>());
int num = WclBleGattClient.WCLGattClientDisconnect(this.mPtr);
//WclBleGattClient.log.Info(string.Format("Disconnect {0:X} response {1}", this.gattAddress, num), Array.Empty<object>());
}
}
public int DiscoverCharacteristics(GattService service, out GattCharacteristics characteristics)
{
characteristics = new GattCharacteristics
{
Count = 0,
Chars = new GattCharacteristic[255]
};
return WclBleGattClient.WCLGattClientGetCharacteristics(this.mPtr, ref service, ref characteristics);
}
public int DiscoverServices(out GattServices services)
{
services = new GattServices
{
Count = 0,
Services = new GattService[255]
};
return WclBleGattClient.WCLGattClientGetServices(this.mPtr, ref services);
}
public int ReadCharacteristicValue(GattCharacteristic characteristic, out byte[] value)
{
value = null;
IntPtr zero = IntPtr.Zero;
uint num = 0U;
int num2 = WclBleGattClient.WCLGattClientReadCharacteristicValue(this.mPtr, ref characteristic, ref zero, ref num);
if (num2 == 0 && zero != IntPtr.Zero && num > 0U)
{
value = new byte[num];
Marshal.Copy(zero, value, 0, (int)num);
WclBleGattClient.WCLGattClientFreeMem(zero);
}
return num2;
}
public int SubscribeCharacteristic(GattCharacteristic characteristic)
{
return WclBleGattClient.WCLGattClientSubscribeCharacteristic(this.mPtr, ref characteristic);
}
public int WriteCharacteristic(GattCharacteristic characteristic, byte[] value)
{
IntPtr intPtr;
try
{
intPtr = Marshal.AllocHGlobal(value.Length);
}
catch
{
intPtr = IntPtr.Zero;
}
if (intPtr == IntPtr.Zero)
{
return 65537;
}
Marshal.Copy(value, 0, intPtr, value.Length);
int result = WclBleGattClient.WCLGattClientWriteCharacteristicValue(this.mPtr, ref characteristic, intPtr, (uint)value.Length);
Marshal.FreeHGlobal(intPtr);
return result;
}
public void Dispose()
{
WclBleGattClient.WCLGattClientDestroy(this.mPtr);
this.mPtr = IntPtr.Zero;
this.rPtr = IntPtr.Zero;
this.CConnectEvent = null;
this.CDisconnectEvent = null;
this.FCharacteristicChangedEvent = null;
}
private void OnCharacteristicChanged(IntPtr sender, ushort handle, IntPtr pValue, uint valueLen)
{
//Debug.Log("char changed");
if (pValue != IntPtr.Zero && valueLen > 0U)
{
byte[] array = new byte[valueLen];
Marshal.Copy(pValue, array, 0, (int)valueLen);
try
{
WclBleGattClient.GattCharacteristicChanged characteristicChanged = this.CharacteristicChanged;
if (characteristicChanged != null)
{
characteristicChanged(this, handle, array);
}
}
catch (Exception arg)
{
//WclBleGattClient.log.Error(string.Format("GattConnection characteristic changed callback processing error - {0}", arg), Array.Empty<object>());
}
}
}
private void OnConnected(IntPtr client, int error)
{
try
{
Debug.Log($"wclbleGattClient onconnected { error }");
WclBleGattClient.GattConnectionChanged connected = this.Connected;
if (connected != null)
{
connected(this, error);
}
}
catch (Exception arg)
{
//WclBleGattClient.log.Error(string.Format("GattConnection connect callback processing error - {0}", arg), Array.Empty<object>());
Debug.LogError(arg);
}
}
private void OnDisconnected(IntPtr client, int reason)
{
try
{
WclBleGattClient.GattConnectionChanged disconnected = this.Disconnected;
if (disconnected != null)
{
disconnected(this, reason);
}
}
catch (Exception arg)
{
//WclBleGattClient.log.Error(string.Format("GattConnection disconnect callback processing error - {0}", arg), Array.Empty<object>());
}
}
public WclBleGattClient.GattCharacteristicChanged CharacteristicChanged;
public WclBleGattClient.GattConnectionChanged Connected;
public WclBleGattClient.GattConnectionChanged Disconnected;
private WclBleGattClient.GATTCLIENT_CONNECT CConnectEvent;
private WclBleGattClient.GATTCLIENT_DISCONNECT CDisconnectEvent;
private WclBleGattClient.GATTCLIENT_ONCHANGED FCharacteristicChangedEvent;
private readonly long gattAddress;
private IntPtr mPtr;
private IntPtr rPtr;
public delegate void GattCharacteristicChanged(WclBleGattClient connection, ushort handle, byte[] value);
public delegate void GattConnectionChanged(WclBleGattClient connection, int error);
[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)]
private delegate void GATTCLIENT_CONNECT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I4)][In] int Error);
[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)]
private delegate void GATTCLIENT_DISCONNECT([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.I4)][In] int Reason);
[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = false)]
private delegate void GATTCLIENT_ONCHANGED([MarshalAs(UnmanagedType.SysInt)][In] IntPtr Sender, [MarshalAs(UnmanagedType.U2)][In] ushort Handle, [MarshalAs(UnmanagedType.SysInt)][In] IntPtr Value, [MarshalAs(UnmanagedType.U4)][In] uint ValueLen);
}
}