[Networking] Add missing Mac OS X APIs. (#7426)

Add missing APIs and complete the bindings for Xcode 11.
This commit is contained in:
Manuel de la Pena 2019-11-22 15:21:39 -05:00 коммит произвёл GitHub
Родитель 88dc8642f0
Коммит dadf69e97e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 222 добавлений и 12 удалений

Просмотреть файл

@ -0,0 +1,193 @@
//
// NWEthernetChannel.cs: Bindings the Network nw_ethernet_channel_t API.
//
// Authors:
// Manuel de la Pena (mandel@microsoft.com)
//
// Copyright 2019 Microsoft
//
#if MONOMAC
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using ObjCRuntime;
using Foundation;
using CoreFoundation;
using OS_nw_ethernet_channel=System.IntPtr;
using OS_nw_interface=System.IntPtr;
using OS_dispatch_data=System.IntPtr;
namespace Network {
[NoWatch, NoTV, NoiOS, Mac (10,15)]
public delegate void NWEthernetChannelReceiveDelegate (DispatchData content, ushort vlanTag, string localAddress, string remoteAddress);
[NoWatch, NoTV, NoiOS, Mac (10,15)]
public enum NWEthernetChannelState
{
Invalid = 0,
Waiting = 1,
Preparing = 2,
Ready = 3,
Failed = 4,
Cancelled = 5,
}
[NoWatch, NoTV, NoiOS, Mac (10,15)]
public class NWEthernetChannel : NativeObject {
internal NWEthernetChannel (IntPtr handle, bool owns) : base (handle, owns) {}
[DllImport (Constants.NetworkLibrary)]
static extern OS_nw_ethernet_channel nw_ethernet_channel_create (ushort ether_type, OS_nw_interface networkInterface);
// we cannot pass an enum! As per docs in the headers:
// The custom EtherType to be used for all Ethernet frames in this channel. The
// EtherType is the two-octet field in an Ethernet frame, indicating the protocol
// encapsulated in the payload of the frame. This parameter is in little-endian
// byte order. Only custom EtherType values are supported. This parameter cannot
// be an EtherType already handled by the system, such as IPv4, IPv6, ARP, VLAN Tag,
// or 802.1x.
//
// Calling processes must hold the "com.apple.developer.networking.custom-protocol"
// entitlement.
public NWEthernetChannel (ushort ethernetType, NWInterface networkInterface)
{
if (networkInterface == null)
throw new ArgumentNullException (nameof (networkInterface));
InitializeHandle (nw_ethernet_channel_create (ethernetType, networkInterface.Handle));
}
[DllImport (Constants.NetworkLibrary)]
static extern void nw_ethernet_channel_start (OS_nw_ethernet_channel ethernet_channel);
public void Start () => nw_ethernet_channel_start (GetCheckedHandle ());
[DllImport (Constants.NetworkLibrary)]
static extern void nw_ethernet_channel_cancel (OS_nw_ethernet_channel ethernet_channel);
public void Cancel () => nw_ethernet_channel_cancel (GetCheckedHandle ());
[DllImport (Constants.NetworkLibrary)]
static extern void nw_ethernet_channel_set_queue (OS_nw_ethernet_channel ethernet_channel, IntPtr queue);
public void SetQueue (DispatchQueue queue)
{
if (queue == null)
throw new ArgumentNullException (nameof (queue));
nw_ethernet_channel_set_queue (GetCheckedHandle (), queue.Handle);
}
[DllImport (Constants.NetworkLibrary)]
static extern void nw_ethernet_channel_send (OS_nw_ethernet_channel ethernet_channel, OS_dispatch_data content, ushort vlan_tag, string remote_address, ref BlockLiteral completion);
delegate void nw_ethernet_channel_send_completion_t (IntPtr block, IntPtr error);
static nw_ethernet_channel_send_completion_t static_SendCompletion = TrampolineSendCompletion;
[MonoPInvokeCallback (typeof (nw_ethernet_channel_send_completion_t))]
static void TrampolineSendCompletion (IntPtr block, IntPtr error)
{
var del = BlockLiteral.GetTarget<Action<NWError>> (block);
if (del != null) {
var err = error == IntPtr.Zero ? null : new NWError (error, owns: false);
del (err);
err?.Dispose ();
}
}
[BindingImpl (BindingImplOptions.Optimizable)]
public void Send (ReadOnlySpan<byte> content, ushort vlanTag, string remoteAddress, Action<NWError> callback)
{
if (callback == null)
throw new ArgumentNullException (nameof (callback));
using (var dispatchData = DispatchData.FromByteBuffer (content.ToArray (), 0, content.Length)) {
BlockLiteral block_handler = new BlockLiteral ();
block_handler.SetupBlockUnsafe (static_SendCompletion, callback);
try {
nw_ethernet_channel_send (GetCheckedHandle (), dispatchData.GetHandle (), vlanTag, remoteAddress, ref block_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
[DllImport (Constants.NetworkLibrary)]
unsafe static extern void nw_ethernet_channel_set_receive_handler (OS_nw_ethernet_channel ethernet_channel, /* [NullAllowed] */ BlockLiteral *handler);
delegate void nw_ethernet_channel_receive_handler_t (IntPtr block, OS_dispatch_data content, ushort vlan_tag, byte[] local_address, byte[] remote_address);
static nw_ethernet_channel_receive_handler_t static_ReceiveHandler = TrampolineReceiveHandler;
[MonoPInvokeCallback (typeof (nw_ethernet_channel_receive_handler_t))]
static void TrampolineReceiveHandler (IntPtr block, OS_dispatch_data content, ushort vlanTag, byte[] localAddress, byte[] remoteAddress)
{
var del = BlockLiteral.GetTarget<NWEthernetChannelReceiveDelegate> (block);
if (del != null) {
var dispatchData = (content == IntPtr.Zero) ? null : new DispatchData (content, owns: false);
var local = (localAddress == null) ? null : Encoding.UTF8.GetString (localAddress);
var remote = (remoteAddress == null) ? null : Encoding.UTF8.GetString (remoteAddress);
del (dispatchData, vlanTag, local, remote);
}
}
[BindingImpl (BindingImplOptions.Optimizable)]
public void SetReceiveHandler (NWEthernetChannelReceiveDelegate handler)
{
unsafe {
if (handler == null) {
nw_ethernet_channel_set_receive_handler (GetCheckedHandle (), null);
return;
}
BlockLiteral block_handler = new BlockLiteral ();
block_handler.SetupBlockUnsafe (static_ReceiveHandler, handler);
try {
nw_ethernet_channel_set_receive_handler (GetCheckedHandle (), &block_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
[DllImport (Constants.NetworkLibrary)]
unsafe static extern void nw_ethernet_channel_set_state_changed_handler (OS_nw_ethernet_channel ethernet_channel, /* [NullAllowed] */ BlockLiteral *handler);
delegate void nw_ethernet_channel_state_changed_handler_t (IntPtr block, NWEthernetChannelState state, IntPtr error);
static nw_ethernet_channel_state_changed_handler_t static_StateChangesHandler = TrampolineStateChangesHandler;
[MonoPInvokeCallback (typeof (nw_ethernet_channel_state_changed_handler_t))]
static void TrampolineStateChangesHandler (IntPtr block, NWEthernetChannelState state, IntPtr error)
{
var del = BlockLiteral.GetTarget<Action<NWEthernetChannelState, NWError>> (block);
if (del != null) {
var nwError = (error == IntPtr.Zero) ? null : new NWError (error, owns: false);
del (state, nwError);
}
}
[BindingImpl (BindingImplOptions.Optimizable)]
public void SetStateChangesHandler (Action<NWBrowserState, NWError> handler)
{
unsafe {
if (handler == null) {
nw_ethernet_channel_set_state_changed_handler (GetCheckedHandle (), null);
return;
}
BlockLiteral block_handler = new BlockLiteral ();
block_handler.SetupBlockUnsafe (static_StateChangesHandler, handler);
try {
nw_ethernet_channel_set_state_changed_handler (GetCheckedHandle (), &block_handler);
} finally {
block_handler.CleanupBlock ();
}
}
}
}
}
#endif

Просмотреть файл

@ -177,6 +177,31 @@ namespace Network {
return new NWParameters (ptr, owns: true);
}
#if MONOMAC
[NoWatch, NoTV, NoiOS, Mac (10,15)]
[DllImport (Constants.NetworkLibrary)]
unsafe static extern IntPtr nw_parameters_create_custom_ip (byte custom_ip_protocol_number, BlockLiteral *configure_ip);
[NoWatch, NoTV, NoiOS, Mac (10,15)]
public unsafe static NWParameters CreateCustomIP (byte protocolNumber, Action<NWProtocolOptions> configureCustomIP = null)
{
var ipHandler = new BlockLiteral ();
var ipPtr = &ipHandler;
if (configureCustomIP == null)
ipPtr = DEFAULT_CONFIGURATION ();
else
ipHandler.SetupBlockUnsafe (static_ConfigureHandler, configureCustomIP);
var ptr = nw_parameters_create_custom_ip (protocolNumber, ipPtr);
if (configureCustomIP != null)
ipPtr->CleanupBlock ();
return new NWParameters (ptr, owns: true);
}
#endif
[DllImport (Constants.NetworkLibrary)]
static extern nw_parameters_t nw_parameters_create ();

Просмотреть файл

@ -1173,6 +1173,7 @@ NETWORK_SOURCES = \
Network/NWConnection.cs \
Network/NWContentContext.cs \
Network/NWDataTransferReport.cs \
Network/NWEthernetChannel.cs \
Network/NWEstablishmentReport.cs \
Network/NWEndpoint.cs \
Network/NWError.cs \

Просмотреть файл

@ -32,3 +32,6 @@
## xcode 10.0 backlog
!missing-pinvoke! nw_endpoint_get_address is not bound
## no documentation from apple. So we do nothing, specially with the _ prefix. Leak?
!missing-field! _nw_data_transfer_report_all_paths not bound

Просмотреть файл

@ -1 +0,0 @@
!missing-field! _nw_data_transfer_report_all_paths not bound

Просмотреть файл

@ -1,9 +0,0 @@
!missing-field! _nw_data_transfer_report_all_paths not bound
!missing-pinvoke! nw_ethernet_channel_cancel is not bound
!missing-pinvoke! nw_ethernet_channel_create is not bound
!missing-pinvoke! nw_ethernet_channel_send is not bound
!missing-pinvoke! nw_ethernet_channel_set_queue is not bound
!missing-pinvoke! nw_ethernet_channel_set_receive_handler is not bound
!missing-pinvoke! nw_ethernet_channel_set_state_changed_handler is not bound
!missing-pinvoke! nw_ethernet_channel_start is not bound
!missing-pinvoke! nw_parameters_create_custom_ip is not bound

Просмотреть файл

@ -1 +0,0 @@
!missing-field! _nw_data_transfer_report_all_paths not bound

Просмотреть файл

@ -1 +0,0 @@
!missing-field! _nw_data_transfer_report_all_paths not bound