func (d *Device) AdvertiseIBeacon(ctx context.Context, u ble.UUID, major, minor uint16, pwr int8) error {
	b := make([]byte, 21)
	copy(b, ble.Reverse(u))                    
	binary.BigEndian.PutUint16(b[16:], major)  
	binary.BigEndian.PutUint16(b[18:], minor)  
	b[20] = uint8(pwr)                         
	return d.AdvertiseIBeaconData(ctx, b)
}
AdvertiseIBeacon advertises iBeacon packet.
package darwin
import (
	"bytes"
	"context"
	"encoding/binary"
	"fmt"
	"log"
	"time"
	"github.com/pkg/errors"
	"github.com/raff/goble/xpc"
	"github.com/rigado/ble"
	"sync"
)
type Device struct {
	pm xpc.XPC  
	cm xpc.XPC  
	role int  
	rspc chan msg
	conns    map[string]*conn
	connLock sync.Mutex
	advHandlerSync bool
	advHandler     ble.AdvHandler
	chConn         chan *conn
	chars map[int]*ble.Characteristic
	base  int
}
func NewDevice(opts ...ble.Option) (*Device, error) {
	err := initXpcIDs()
	if err != nil {
		return nil, err
	}
	d := &Device{
		rspc:   make(chan msg),
		conns:  make(map[string]*conn),
		chConn: make(chan *conn),
		chars:  make(map[int]*ble.Characteristic),
		base:   1,
	}
	if err := d.Option(opts...); err != nil {
		return nil, err
	}
	d.pm = xpc.XpcConnect(serviceID, d)
	d.cm = xpc.XpcConnect(serviceID, d)
	return d, errors.Wrap(d.Init(), "can't init")
}
func (d *Device) Option(opts ...ble.Option) error {
	var err error
	for _, opt := range opts {
		err = opt(d)
	}
	return err
}
func (d *Device) Init() error {
	rsp, err := d.sendReq(d.cm, cmdInit, xpc.Dict{
		"kCBMsgArgName": fmt.Sprintf("gopher-%v", time.Now().Unix()),
		"kCBMsgArgOptions": xpc.Dict{
			"kCBInitOptionShowPowerAlert": 1,
		},
		"kCBMsgArgType": 0,
	})
	if err != nil {
		return err
	}
	s := State(rsp.state())
	if s != StatePoweredOn {
		return fmt.Errorf("state: %s", s)
	}
	rsp, err = d.sendReq(d.pm, cmdInit, xpc.Dict{
		"kCBMsgArgName": fmt.Sprintf("gopher-%v", time.Now().Unix()),
		"kCBMsgArgOptions": xpc.Dict{
			"kCBInitOptionShowPowerAlert": 1,
		},
		"kCBMsgArgType": 1,
	})
	if err != nil {
		return err
	}
	s = State(rsp.state())
	if s != StatePoweredOn {
		return fmt.Errorf("state: %s", s)
	}
	return nil
}
func (d *Device) Advertise(ctx context.Context, adv ble.Advertisement) error {
	rsp, err := d.sendReq(d.pm, cmdAdvertiseStart, xpc.Dict{
		"kCBAdvDataLocalName":    adv.LocalName(),
		"kCBAdvDataServiceUUIDs": adv.Services(),
		"kCBAdvDataAppleMfgData": adv.ManufacturerData(),
	})
	if err != nil {
		return err
	}
	if err := rsp.err(); err != nil {
		return err
	}
	<-ctx.Done()
	_ = d.stopAdvertising()
	return ctx.Err()
}
func (d *Device) AdvertiseMfgData(ctx context.Context, id uint16, md []byte) error {
	l := len(md)
	b := []byte{byte(l + 3), 0xFF, uint8(id), uint8(id >> 8)}
	rsp, err := d.sendReq(d.pm, cmdAdvertiseStart, xpc.Dict{
		"kCBAdvDataAppleMfgData": append(b, md...),
	})
	if err != nil {
		return err
	}
	if err := rsp.err(); err != nil {
		return errors.Wrap(err, "can't advertise")
	}
	<-ctx.Done()
	return ctx.Err()
}
func (d *Device) AdvertiseServiceData16(ctx context.Context, id uint16, b []byte) error {
	l := len(b)
	prefix := []byte{
		0x03, 0x03, uint8(id), uint8(id >> 8),
		byte(l + 3), 0x16, uint8(id), uint8(id >> 8),
	}
	rsp, err := d.sendReq(d.pm, cmdAdvertiseStart, xpc.Dict{
		"kCBAdvDataAppleMfgData": append(prefix, b...),
	})
	if err != nil {
		return err
	}
	if err := rsp.err(); err != nil {
		return errors.Wrap(err, "can't advertise")
	}
	<-ctx.Done()
	return ctx.Err()
}
func (d *Device) AdvertiseNameAndServices(ctx context.Context, name string, ss ...ble.UUID) error {
	rsp, err := d.sendReq(d.pm, cmdAdvertiseStart, xpc.Dict{
		"kCBAdvDataLocalName":    name,
		"kCBAdvDataServiceUUIDs": uuidSlice(ss)},
	)
	if err != nil {
		return err
	}
	if err := rsp.err(); err != nil {
		return err
	}
	<-ctx.Done()
	_ = d.stopAdvertising()
	return ctx.Err()
}
func (d *Device) AdvertiseIBeaconData(ctx context.Context, md []byte) error {
	var utsname xpc.Utsname
	err := xpc.Uname(&utsname)
	if err != nil {
		return err
	}
	if utsname.Release >= "14." {
		ibeaconCode := []byte{0x02, 0x15}
		return d.AdvertiseMfgData(ctx, 0x004C, append(ibeaconCode, md...))
	}
	rsp, err := d.sendReq(d.pm, cmdAdvertiseStart, xpc.Dict{"kCBAdvDataAppleBeaconKey": md})
	if err != nil {
		return err
	}
	if err := rsp.err(); err != nil {
		return err
	}
	<-ctx.Done()
	return d.stopAdvertising()
}