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 }