github.com/racerxdl/gonx@v0.0.0-20210103083128-c5afc43bcbd2/services/vi/vi.go (about)

     1  package vi
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/racerxdl/gonx/internal"
     6  	"github.com/racerxdl/gonx/nx/nxerrors"
     7  	"github.com/racerxdl/gonx/services/ipc"
     8  	"github.com/racerxdl/gonx/services/sm"
     9  	"unsafe"
    10  )
    11  
    12  const (
    13  	viDebug = false
    14  )
    15  
    16  var viDomain *ipc.Domain
    17  var imrsObject ipc.Object   // nn::visrv::sf::IManagerRootService
    18  var iadsObject ipc.Object   // nn::visrv::sf::IApplicationDisplayService
    19  var imdsObject ipc.Object   // nn::visrv::sf::IManagerDisplayService
    20  var isdsObject ipc.Object   // nn::visrv::sf::ISystemDisplayService
    21  var ihosbdObject ipc.Object // nn::visrv::sf::IHOSBinderDriver
    22  
    23  var viInitializations = 0
    24  
    25  func GetObject(iface ipc.Object, command int) (ipc.Object, error) {
    26  	if viDebug {
    27  		fmt.Printf("VI::GetObject(--, %d)\n", command)
    28  	}
    29  	if viInitializations <= 0 {
    30  		return ipc.Object{}, nxerrors.VINotInitialized
    31  	}
    32  
    33  	rq := ipc.MakeDefaultRequest(uint32(command))
    34  	rs := ipc.ResponseFmt{}
    35  	rs.Objects = make([]ipc.Object, 1)
    36  
    37  	err := ipc.Send(iface, &rq, &rs)
    38  	if err != nil {
    39  		return ipc.Object{}, err
    40  	}
    41  
    42  	return rs.Objects[0], nil
    43  }
    44  
    45  func Init() (err error) {
    46  	if viDebug {
    47  		println("VI::Init()")
    48  	}
    49  	viInitializations++
    50  	if viInitializations > 1 {
    51  		return nil
    52  	}
    53  
    54  	smInit := false
    55  	imrsInit := false
    56  	domainInit := false
    57  	iadsInit := false
    58  	ihosbdInit := false
    59  	isdsInit := false
    60  
    61  	defer func() {
    62  		if err != nil {
    63  			viInitializations--
    64  
    65  			if isdsInit {
    66  				_ = ipc.Close(&isdsObject)
    67  			}
    68  			if ihosbdInit {
    69  				_ = ipc.Close(&ihosbdObject)
    70  			}
    71  			if iadsInit {
    72  				_ = ipc.Close(&iadsObject)
    73  			}
    74  			if imrsInit {
    75  				_ = ipc.Close(&imrsObject)
    76  			}
    77  			if domainInit {
    78  				_ = ipc.CloseSession(viDomain.Session)
    79  				viDomain = nil
    80  			}
    81  		}
    82  
    83  		if smInit {
    84  			sm.Finalize()
    85  		}
    86  	}()
    87  
    88  	if viDebug {
    89  		println("VI::Init() - SM Initialize")
    90  	}
    91  	// SM Initialize
    92  	err = sm.Init()
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	smInit = true
    98  
    99  	if viDebug {
   100  		println("VI::Init() - VI:M Initialize")
   101  	}
   102  	// vi:m initialize
   103  	err = sm.GetService(&imrsObject, "vi:m")
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	imrsInit = true
   109  
   110  	if viDebug {
   111  		println("VI::Init() - VI:M Convert to Domain")
   112  	}
   113  	// Domain Initialize
   114  	viDomain, err = ipc.ConvertToDomain(&imrsObject)
   115  	if err != nil {
   116  		return err
   117  	}
   118  	domainInit = true
   119  
   120  	if viDebug {
   121  		println("VI::Init() - IADS Init")
   122  	}
   123  	// iads initialize
   124  	rq := ipc.MakeDefaultRequest(2)
   125  	rq.SetRawDataFromUint32Slice([]uint32{1})
   126  
   127  	rs := ipc.ResponseFmt{}
   128  	rs.Objects = make([]ipc.Object, 1)
   129  
   130  	err = ipc.Send(imrsObject, &rq, &rs)
   131  	if err != nil {
   132  		return err
   133  	}
   134  
   135  	iadsObject = rs.Objects[0]
   136  	iadsInit = true
   137  
   138  	if viDebug {
   139  		println("VI::Init() - IHOSBD Init")
   140  	}
   141  	ihosbdObject, err = GetObject(iadsObject, 100)
   142  	if err != nil {
   143  		return err
   144  	}
   145  	ihosbdInit = true
   146  
   147  	if viDebug {
   148  		println("VI::Init() - ISDS Init")
   149  	}
   150  	isdsObject, err = GetObject(iadsObject, 101)
   151  	if err != nil {
   152  		return err
   153  	}
   154  	isdsInit = true
   155  
   156  	if viDebug {
   157  		println("VI::Init() - IMDS Init")
   158  	}
   159  	imdsObject, err = GetObject(iadsObject, 102)
   160  	if err != nil {
   161  		return err
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func TransactParcel(handle int32, transaction, flags uint32, rqParcel []byte, rsParcel []byte) error {
   168  	if viDebug {
   169  		fmt.Printf("VI::TransactParcel(%d, %d, %d, [%d]byte, [%d]byte)\n", handle, transaction, flags, len(rqParcel), len(rsParcel))
   170  	}
   171  	if viInitializations <= 0 {
   172  		return nxerrors.VINotInitialized
   173  	}
   174  
   175  	rqBuffer := ipc.Buffer{
   176  		Addr: uintptr(unsafe.Pointer(&rqParcel[0])),
   177  		Size: uint64(len(rqParcel)),
   178  		Type: 5,
   179  	}
   180  
   181  	rsBuffer := ipc.Buffer{
   182  		Addr: uintptr(unsafe.Pointer(&rsParcel[0])),
   183  		Size: uint64(len(rsParcel)),
   184  		Type: 6,
   185  	}
   186  
   187  	raw := struct {
   188  		handle      int32
   189  		transaction uint32
   190  		flags       uint32
   191  	}{
   192  		handle:      handle,
   193  		transaction: transaction,
   194  		flags:       flags,
   195  	}
   196  
   197  	rq := ipc.MakeDefaultRequest(0)
   198  	rq.Buffers = []*ipc.Buffer{&rqBuffer, &rsBuffer}
   199  	rq.RawData = make([]byte, unsafe.Sizeof(raw))
   200  	internal.Memcpy(unsafe.Pointer(&rq.RawData[0]), unsafe.Pointer(&raw), uintptr(len(rq.RawData)))
   201  
   202  	rs := ipc.ResponseFmt{}
   203  
   204  	return ipc.Send(ihosbdObject, &rq, &rs)
   205  }
   206  
   207  func AdjustRefCount(handle, addVal, Type int32) error {
   208  	if viDebug {
   209  		fmt.Printf("VI::AdjustRefCount(%d, %d, %d)\n", handle, addVal, Type)
   210  	}
   211  	if viInitializations <= 0 {
   212  		return nxerrors.VINotInitialized
   213  	}
   214  
   215  	rq := ipc.MakeDefaultRequest(1)
   216  	rq.SetRawDataFromUint32Slice([]uint32{uint32(handle), uint32(addVal), uint32(Type)})
   217  
   218  	rs := ipc.ResponseFmt{}
   219  
   220  	return ipc.Send(ihosbdObject, &rq, &rs)
   221  }
   222  
   223  func forceFinalize() {
   224  	if viDebug {
   225  		println("VI::ForceFinalize()")
   226  	}
   227  	_ = ipc.Close(&isdsObject)
   228  	_ = ipc.Close(&ihosbdObject)
   229  	_ = ipc.Close(&iadsObject)
   230  	_ = ipc.Close(&imrsObject)
   231  	if viDomain != nil {
   232  		_ = ipc.CloseSession(viDomain.Session)
   233  		viDomain = nil
   234  	}
   235  	viInitializations = 0
   236  }
   237  
   238  func Finalize() {
   239  	if viDebug {
   240  		println("VI::Finalize()")
   241  	}
   242  	viInitializations--
   243  	if viInitializations < 0 {
   244  		forceFinalize()
   245  	}
   246  }