gobot.io/x/gobot/v2@v2.1.0/system/syscall_mock.go (about) 1 package system 2 3 import ( 4 "syscall" 5 "unsafe" 6 ) 7 8 // mockSyscall represents the mock Syscall used for unit tests 9 type mockSyscall struct { 10 lastTrap uintptr 11 lastFile File 12 lastSignal uintptr 13 devAddress uintptr 14 smbus *i2cSmbusIoctlData 15 sliceSize uint8 16 dataSlice []byte 17 Impl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) 18 } 19 20 // Syscall calls the user defined implementation, used for tests, implements the SystemCaller interface 21 func (sys *mockSyscall) syscall(trap uintptr, f File, signal uintptr, payload unsafe.Pointer) (r1, r2 uintptr, err syscall.Errno) { 22 sys.lastTrap = trap // points to the used syscall (e.g. "SYS_IOCTL") 23 sys.lastFile = f // a character device file (e.g. file to path "/dev/i2c-1") 24 sys.lastSignal = signal // points to used function type (e.g. I2C_SMBUS, I2C_RDWR) 25 26 if signal == I2C_SLAVE { 27 // in this case the uintptr corresponds the address 28 sys.devAddress = uintptr(payload) 29 } 30 31 if signal == I2C_SMBUS { 32 // set the I2C smbus data object reference to payload and fill with some data 33 sys.smbus = (*i2cSmbusIoctlData)(payload) 34 if sys.smbus.data != nil { 35 sys.sliceSize = sys.retrieveSliceSize() 36 37 if sys.smbus.readWrite == I2C_SMBUS_WRITE { 38 // get the data object payload as byte slice 39 sys.dataSlice = unsafe.Slice((*byte)(unsafe.Pointer(sys.smbus.data)), sys.sliceSize) 40 } 41 42 if sys.smbus.readWrite == I2C_SMBUS_READ { 43 // fill data object with data from given slice to simulate reading 44 if sys.dataSlice != nil { 45 slc := unsafe.Slice((*byte)(unsafe.Pointer(sys.smbus.data)), sys.sliceSize) 46 if sys.smbus.protocol == I2C_SMBUS_BLOCK_DATA || sys.smbus.protocol == I2C_SMBUS_I2C_BLOCK_DATA { 47 copy(slc[1:], sys.dataSlice) 48 } else { 49 copy(slc, sys.dataSlice) 50 } 51 } 52 } 53 } 54 } 55 56 // call mock implementation 57 if sys.Impl != nil { 58 return sys.Impl(trap, f.Fd(), signal, uintptr(unsafe.Pointer(payload))) 59 } 60 return 0, 0, 0 61 } 62 63 func (sys *mockSyscall) retrieveSliceSize() uint8 { 64 switch sys.smbus.protocol { 65 case I2C_SMBUS_BYTE: 66 return 1 67 case I2C_SMBUS_BYTE_DATA: 68 return 1 69 case I2C_SMBUS_WORD_DATA: 70 return 2 71 default: 72 // for I2C_SMBUS_BLOCK_DATA, I2C_SMBUS_I2C_BLOCK_DATA 73 return *(*byte)(unsafe.Pointer(sys.smbus.data)) + 1 // first data element contains data size 74 } 75 }