module MXAPI implicit none interface integer*2 function Init_MatrixAPI() BIND(C,name='init_matrixapi') end function Init_MatrixAPI end interface interface integer*2 function Release_MatrixAPI() BIND(C,name='release_matrixapi') end function Release_MatrixAPI end interface interface integer*4 function GetVersionAPI() BIND(C,name='getversionapi') end function GetVersionAPI end interface interface integer*4 function GetVersionDRV_USB() BIND(C,name='getversiondrv_usb') end function GetVersionDRV_USB end interface interface integer*2 function Dongle_Count(Port) BIND(C,name='dongle_count') integer*2, value :: Port end function Dongle_Count end interface interface integer*2 function Dongle_MemSize(DngNr, PortNr) BIND(C,name='dongle_memsize') integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_MemSize end interface interface integer*4 function Dongle_Model(DngNr, PortNr) BIND(C,name='dongle_model') integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_Model end interface interface integer*4 function Dongle_Version(DngNr, PortNr) BIND(C,name='dongle_version') integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_Version end interface interface integer*2 function Dongle_ReadData(UserCode, fldData, Count, DngNr, PortNr) BIND(C,name='dongle_readdata') integer*4, value :: UserCode integer*4, dimension(*) :: fldData integer*2, value :: Count integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_ReadData end interface interface integer*2 function Dongle_ReadDataEx(UserCode, fldData, Fpos, Count, DngNr, PortNr) BIND(C,name='dongle_readdataex') integer*4, value :: UserCode integer*4, dimension(*) :: fldData integer*2, value :: Fpos integer*2, value :: Count integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_ReadDataEx end interface interface integer*2 function Dongle_WriteData(UserCode, fldData, Count, DngNr, PortNr) BIND(C,name='dongle_writedata') integer*4, value :: UserCode integer*4, dimension(*) :: fldData integer*2, value :: Count integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_WriteData end interface interface integer*2 function Dongle_WriteDataEx(UserCode, fldData, Fpos, Count, DngNr, PortNr) BIND(C,name='dongle_writedataex') integer*4, value :: UserCode integer*4, dimension(*) :: fldData integer*2, value :: Fpos integer*2, value :: Count integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_WriteDataEx end interface interface integer*4 function Dongle_ReadSerNr(UserCode, DngNr, PortNr) BIND(C,name='dongle_readsernr') integer*4, value :: UserCode integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_ReadSerNr end interface interface integer*2 function Dongle_WriteKey(UserCode, KeyData, DngNr, PortNr) BIND(C,name='dongle_writekey') integer*4, value :: UserCode integer*4, dimension(4) :: KeyData integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_WriteKey end interface interface integer*2 function Dongle_GetKeyFlag(UserCode, DngNr, PortNr) BIND(C,name='dongle_getkeyflag') integer*4, value :: UserCode integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_GetKeyFlag end interface interface integer*2 function Dongle_EncryptData(UserCode, DataBlock, DngNr, PortNr) BIND(C,name='dongle_encryptdata') integer*4, value :: UserCode integer*4, dimension(2) :: DataBlock integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_EncryptData end interface interface integer*2 function Dongle_DecryptData(UserCode, DataBlock, DngNr, PortNr) BIND(C,name='dongle_decryptdata') integer*4, value :: UserCode integer*4, dimension(2) :: DataBlock integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_DecryptData end interface interface integer*2 function Dongle_SetDriverFlag(UserCode, Mode, DngNr, PortNr) BIND(C,name='dongle_setdriverflag') integer*4, value :: UserCode integer*2, value :: Mode integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_SetDriverFlag end interface interface integer*2 function Dongle_GetDriverFlag(UserCode, DngNr, PortNr) BIND(C,name='dongle_getdriverflag') integer*4, value :: UserCode integer*2, value :: DngNr integer*2, value :: PortNr end function Dongle_GetDriverFlag end interface interface integer*2 function SetConfig_MatrixNet( nAccess, nFile ) BIND(C, name='setconfig_matrixnet') use iso_c_binding integer*2, value :: nAccess character(kind=c_char), dimension(*) :: nFile end function SetConfig_MatrixNet end interface interface integer*4 function GetConfig_MatrixNet( Category ) BIND(C, name='getconfig_matrixnet') integer*2, value :: Category end function GetConfig_MatrixNet end interface interface integer*2 function LogIn_MatrixNet(UserCode, AppSlot, DngNr) BIND(C,name='login_matrixnet') integer*4, value :: UserCode integer*2, value :: AppSlot integer*2, value :: DngNr end function LogIn_MatrixNet end interface interface integer*2 function LogOut_MatrixNet(UserCode, AppSlot, DngNr) BIND(C,name='logout_matrixnet') integer*4, value :: UserCode integer*2, value :: AppSlot integer*2, value :: DngNr end function LogOut_MatrixNet end interface contains integer*2 function hiWord( version) integer*4 :: version hiWord=int(rshift(version, 16)) end function hiword integer*2 function loWord( version) integer*4 :: version loWord=int(and(version, X'ffffffff')) end function loword subroutine MxApp_Encrypt( myData_, Key_ ) integer*4,dimension(0:1) :: myData_ integer*4, dimension(0:3) :: Key_ ! Fortran does not support unsigned integer ! So we use 8byte integers for calcuation integer*8,dimension(0:1) :: myData integer*8,dimension(0:3) :: Key integer*8 delta, sum; integer*8 :: three = 3 integer*2 cnt; integer*8 :: mask = X'ffffffff' integer*2 :: i myData(0) = int(myData_(0)) myData(1) = int(myData_(1)) Key(0) = int(Key_(0)) Key(1) = int(Key_(1)) Key(2) = int(Key_(2)) Key(3) = int(Key_(3)) sum = 0; delta = X'9e3779b9' do i=1, 32 myData(0) = myData(0)+ieor( ieor(lshift(myData(1),4), rshift(myData(1),5)) + myData(1), sum + Key( and(sum, three))) myData(0) = and(myData(0), mask) sum = sum + delta myData(1) = myData(1) + ieor( ieor(lshift(myData(0),4), rshift(myData(0),5)) + myData(0), sum + Key( and(rshift(sum,11),three))) myData(1) = and(myData(1), mask) ! 8byte integers are converted back to 4byte integer myData_(0)=int(myData(0)) myData_(1)=int(myData(1)) end do end subroutine MxApp_Encrypt subroutine MxApp_Decrypt( myData_, Key_ ) integer*4,dimension(0:1) :: myData_ integer*4, dimension(0:3) :: Key_ ! Fortran does not support unsigned integer ! So we use 8byte integers for calcuation integer*8,dimension(0:1) :: myData integer*8,dimension(0:3) :: Key integer*8 delta, sum; integer*8 :: three = 3 integer*2 cnt; integer*8 :: mask = X'ffffffff' integer*2 :: i myData(0) = int(myData_(0)) myData(1) = int(myData_(1)) Key(0) = int(Key_(0)) Key(1) = int(Key_(1)) Key(2) = int(Key_(2)) Key(3) = int(Key_(3)) sum = X'C6EF3720'; delta = X'9e3779b9' do i=1, 32 myData(1) = myData(1)-ieor( ieor(lshift(myData(0),4), rshift(myData(0),5)) + myData(0), sum + Key( and(rshift(sum,11),three))) myData(1) = and(myData(1), mask) sum = sum - delta myData(0) = myData(0)-ieor( ieor(lshift(myData(1),4), rshift(myData(1),5)) + myData(1), sum + Key( and(sum, three))) myData(0) = and(myData(0), mask) ! 8byte integers are converted back to 4byte integer myData_(0)=int(myData(0)) myData_(1)=int(myData(1)) end do end subroutine MxApp_Decrypt end module MXAPI program main use MXAPI use iso_c_binding implicit none integer*2 :: r ! return value integer*4 :: r32 integer*4,parameter :: UserCode=1234 integer*4,allocatable,dimension(:) :: fldData integer*2 :: count integer*2,parameter :: port=85 integer*2,parameter :: dngnr=1 integer*2 :: i character(1) :: ch integer*4,dimension(0:1) :: plainData integer*4,dimension(0:3) :: encKey r=Init_MatrixAPI() r32=GetVersionAPI() print *,"API Version -> Major Version:", hiWord(r32), "Minor Version:", loWord(r32) r = Dongle_Count(port) print *, "Dongle Count=", r if( r <= 0 ) then print *, "No Dongle Connected" r = Release_MatrixAPI() stop end if !============================================ ! Acquire Dongle Info !============================================ r32 = Dongle_Model(DngNr, Port) print *,"Dongle Model", r32 r32=Dongle_Version(DngNr, Port) print *,"Dongle Version -> Major Version:", hiWord(r32), "Minor Version:", loWord(r32) r = Dongle_MemSize(DngNr, Port) print *, "MemSize:", r ! Calculate the Field Count count = r/4 print *, "Field Count:", count r32 = Dongle_ReadSerNr(UserCode, DngNr, Port) print *, "Dongle Serial Number:", r32 !============================================ ! Field Read / Write test !============================================ ! allocate fldData big enough to hold all the field data values allocate( fldData(count) ) r = Dongle_ReadData(UserCode, fldData, Count, DngNr, Port) if( r>0 ) then do i=1, r print *, i, fldData(i) end do end if do i=1 ,r fldData(i) = 100+i end do ! write 3 fields only r = Dongle_WriteData(UserCode, fldData, int(3, 2), DngNr, Port ) print *, "Dongle_WriteData Result=", r deallocate( fldData ) !============================================ ! Encrypt / Decrypt test !============================================ ! Encrypt Data plainData(0)=123666444 plainData(1)=42343242 r=Dongle_EncryptData(UserCode, plainData, DngNr, Port) print *, plainData r=Dongle_DecryptData(UserCode, plainData, DngNr, Port) print *, plainData ! If the dongle has the same XTEA key as the followings, ! Dongle_EncryptData / MxApp_Encrypt, Dongle_DecryptData / MxApp_Decrypt ! must output the same results encKey(0) = 123456789 encKey(1) = 234567891 encKey(2) = 3456789 encKey(3) = 456789012 call MxApp_Encrypt(plainData, encKey) print *, plainData call MxApp_Decrypt(plainData, encKey) print *, plainData !============================================ ! Remote API test !============================================ ! enable Remote API r=SetConfig_MatrixNet(int(1,2),"c:\matrix\abc.xxxx"//c_null_char) print *,r print *, "Remote Refresh Time:", GetConfig_MatrixNet(int(1,2)) r = LogIn_MatrixNet( UserCode, int(1,2), DngNr) print *, "LogIn_MatrixNet:", r write (*,"(a)",advance="no") "press any key and return to continue:" read *, ch r = LogOut_MatrixNet( UserCode, int(1,2), DngNr) print *, "LogOut_MatrixNet:", r !Disable Remote API r=SetConfig_MatrixNet(int(0,2),""//c_null_char) r = Release_MatrixAPI() end program main