core.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. package Core
  2. /*
  3. #cgo CFLAGS: -I../include
  4. #cgo LDFLAGS: -lHCCore -lhcnetsdk -lhpr -lNPQos -lSuperRender
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stddef.h>
  8. #include "HCNetSDK.h"
  9. extern void fSerialDataCallBackGo(LONG lSerialHandle,LONG lChannel,char *pRecvDataBuffer,DWORD dwBufSize,void *pUser);
  10. void FSerialDataCallBackCGo(LONG lSerialHandle,LONG lChannel,char *pRecvDataBuffer,DWORD dwBufSize,void *pUser){
  11. fSerialDataCallBackGo(lSerialHandle, lChannel, pRecvDataBuffer, dwBufSize,pUser);
  12. };
  13. // 异常回调函数
  14. extern void fExceptionCallBackGo(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser);
  15. void FExceptionCallBackCgo(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
  16. {
  17. fExceptionCallBackGo(dwType, lUserID, lHandle, pUser);
  18. }
  19. */
  20. import "C"
  21. import (
  22. "math"
  23. "unsafe"
  24. )
  25. // Init 初始化SDK,调用其他SDK函数的前提。
  26. func Init() error {
  27. if C.NET_DVR_Init() != 1 {
  28. return LastError("NET_DVR_Init")
  29. }
  30. return nil
  31. }
  32. // Cleanup 释放SDK资源,在程序结束之前调用。在调用时不能同时调用其他任何SDK接口。 Init 和 Cleanup 需要配对使用,即程序里面调用多少次 Init ,退出时就需要调用多少次 Cleanup。
  33. func Cleanup() error {
  34. if C.NET_DVR_Cleanup() != 1 {
  35. return LastError("NET_DVR_Cleanup")
  36. }
  37. return nil
  38. }
  39. func Login(Ip string, Port int, Username string, Password string) (LONG, NET_DVR_DEVICEINFO_V30, error) {
  40. cIp := C.CString(Ip)
  41. defer C.free(unsafe.Pointer(cIp))
  42. cUsername := C.CString(Username)
  43. defer C.free(unsafe.Pointer(cUsername))
  44. cPassword := C.CString(Password)
  45. defer C.free(unsafe.Pointer(cPassword))
  46. var DeviceInfo C.NET_DVR_DEVICEINFO_V30
  47. cUserId := C.NET_DVR_Login_V30(cIp, C.WORD(Port), cUsername, cPassword, &DeviceInfo)
  48. if LONG(cUserId) == -1 {
  49. return -1, NET_DVR_DEVICEINFO_V30{}, LastError("NET_DVR_Login_V30")
  50. }
  51. DATA := CNET_DVR_DEVICEINFO_V30ToGO(&DeviceInfo)
  52. return LONG(cUserId), DATA, nil
  53. }
  54. func Logout(userId LONG) error {
  55. if userId > -1 {
  56. cResult := C.NET_DVR_Logout(C.LONG(userId))
  57. if cResult != 1 {
  58. return LastError("NET_DVR_Logout")
  59. }
  60. }
  61. return nil
  62. }
  63. func SerialStart(UserId LONG, CallBack serialDataCallBack) (LONG, error) {
  64. SerialStartParam := C.NET_DVR_SERIALSTART_V40{}
  65. SerialStartParam.dwSize = C.DWORD(unsafe.Sizeof(SerialStartParam))
  66. SerialStartParam.dwSerialType = C.DWORD(2) //1:232串口;2:485串口
  67. SerialStartParam.bySerialNum = C.BYTE(1) //串口编号(设备支持多个RS232串口时有效)
  68. // 填充 byRes 字段
  69. for i := 0; i < 255; i++ {
  70. SerialStartParam.byRes[i] = C.BYTE(0) // 示例值,逐个赋值
  71. }
  72. SerialStartHandle := C.NET_DVR_SerialStart_V40(C.LONG(UserId), unsafe.Pointer(&SerialStartParam), C.LONG(unsafe.Sizeof(SerialStartParam)), C.fSerialDataCallBack(C.FSerialDataCallBackCGo), nil)
  73. if LONG(SerialStartHandle) == -1 {
  74. return -1, LastError("NET_DVR_SerialStart_V40")
  75. }
  76. serialCallBackHooks[LONG(SerialStartHandle)] = CallBack
  77. return LONG(SerialStartHandle), nil
  78. }
  79. func SerialSend(lSerialHandle LONG, hexbyte []byte) error {
  80. if C.NET_DVR_SerialSend(C.LONG(lSerialHandle), 1, (*C.char)(unsafe.Pointer(&hexbyte[0])), C.DWORD(len(hexbyte))) == C.FALSE {
  81. return LastError("NET_DVR_SerialSend")
  82. }
  83. return nil
  84. }
  85. func SerialStop(lSerialHandle LONG) error {
  86. if int(C.NET_DVR_SerialStop(C.LONG(lSerialHandle))) != 1 {
  87. return LastError("SerialStop")
  88. }
  89. delete(serialCallBackHooks, lSerialHandle)
  90. return nil
  91. }
  92. type CDVR_PTZPOS C.NET_DVR_PTZPOS
  93. func (d *CDVR_PTZPOS) Go() DVR_PTZPOS {
  94. return DVR_PTZPOS{
  95. WAction: 1,
  96. WPanPos: HEX2DEC(WORD(d.wPanPos)),
  97. WTiltPos: HEX2DEC(WORD(d.wTiltPos)),
  98. WZoomPos: HEX2DEC(WORD(d.wZoomPos)),
  99. }
  100. }
  101. func (d *CDVR_PTZPOS) Set(Action, PanPos, TiltPos, ZoomPos float64) {
  102. //a1 := DEC2HEX(Action)
  103. //a2 := DEC2HEX(PanPos)
  104. //a3 := DEC2HEX(TiltPos)
  105. //a4 := DEC2HEX(ZoomPos)
  106. //println(a1, a2, a3, a4)
  107. d.wAction = C.WORD(Action)
  108. d.wPanPos = C.WORD(DEC2HEX(PanPos))
  109. d.wTiltPos = C.WORD(DEC2HEX(TiltPos))
  110. d.wZoomPos = C.WORD(DEC2HEX(ZoomPos))
  111. //d.wAction = C.WORD(1)
  112. //d.wPanPos = C.WORD(0x77)
  113. //d.wTiltPos = C.WORD(0x88)
  114. //d.wZoomPos = C.WORD(0x99)
  115. }
  116. type DVR_PTZPOS struct {
  117. WAction int
  118. WPanPos float64
  119. WTiltPos float64
  120. WZoomPos float64
  121. }
  122. // DEC2HEX 将十进制浮点数转换为十六进制整数
  123. func DEC2HEX(dec float64) WORD {
  124. // 提取千位(对应十进制的百位)
  125. bai := uint16(dec / math.Pow(10, 2))
  126. dec -= float64(bai) * math.Pow(10, 2)
  127. // 提取百位(对应十进制的十位)
  128. shi := uint16(dec / math.Pow(10, 1))
  129. dec -= float64(shi) * math.Pow(10, 1)
  130. // 提取十位(对应十进制的个位)
  131. ge := uint16(dec / math.Pow(10, 0))
  132. dec -= float64(ge) * math.Pow(10, 0)
  133. // 提取个位(对应十进制的十分位)
  134. xiao := uint16(dec * 10)
  135. // 合成十六进制数
  136. hex := WORD(bai)<<12 | WORD(shi)<<8 | WORD(ge)<<4 | WORD(xiao)
  137. return hex
  138. }
  139. // HEX2DEC 将十六进制整数转换为十进制浮点数
  140. func HEX2DEC(hex WORD) float64 {
  141. // 提取十六进制数的千位(对应十进制的百位)
  142. bai := byte(hex >> 12)
  143. hex = hex - WORD(bai)*WORD(math.Pow(16, 3))
  144. // 提取十六进制数的百位(对应十进制的十位)
  145. shi := byte(hex >> 8)
  146. hex = hex - WORD(shi)*WORD(math.Pow(16, 2))
  147. // 提取十六进制数的十位(对应十进制的个位)
  148. ge := byte(hex >> 4)
  149. hex = hex - WORD(ge)*WORD(math.Pow(16, 1))
  150. // 提取十六进制数的个位(对应十进制的十分位)
  151. xiao := byte(hex)
  152. // 计算对应的十进制浮点数
  153. return float64(bai)*math.Pow(10, 2) + float64(shi)*math.Pow(10, 1) + float64(ge)*math.Pow(10, 0) + float64(xiao)*math.Pow(10, -1)
  154. }
  155. func GetDVRConfig(lUserID LONG, dwCommand DWORD, lChannel LONG, lpOutBuffer unsafe.Pointer, dwOutBufferSize DWORD) error {
  156. bytesReturned := C.DWORD(0)
  157. cResult := C.NET_DVR_GetDVRConfig(C.LONG(lUserID), C.DWORD(dwCommand), C.LONG(lChannel), C.LPVOID(lpOutBuffer), C.DWORD(dwOutBufferSize), &bytesReturned)
  158. if cResult != 1 {
  159. return LastError("NET_DVR_GetDVRConfig")
  160. }
  161. return nil
  162. }
  163. func SetDVRConfig(lUserID LONG, dwCommand DWORD, lChannel LONG, lpInBuffer unsafe.Pointer, dwOutBufferSize DWORD) error {
  164. cResult := C.NET_DVR_SetDVRConfig(C.LONG(lUserID), C.DWORD(dwCommand), C.LONG(lChannel), C.LPVOID(lpInBuffer), C.DWORD(dwOutBufferSize))
  165. if cResult != 1 {
  166. return LastError("NET_DVR_SetDVRConfig")
  167. }
  168. return nil
  169. }
  170. func LastError(funcName string) error {
  171. cCode := C.NET_DVR_GetLastError()
  172. if cCode == 0 {
  173. return nil
  174. }
  175. var text string
  176. if cCode == 3 {
  177. text = "sdk not init."
  178. } else {
  179. cCode2 := C.LONG(cCode)
  180. cText := C.NET_DVR_GetErrorMsg(&cCode2)
  181. text = C.GoString(cText)
  182. }
  183. return NewHcnetError(int(cCode), text, funcName)
  184. }
  185. func PTZControlWithSpeed_Other(lUserID LONG, lChannel LONG, dwPTZCommand DWORD, dwStop DWORD, dwSpeed DWORD) error {
  186. state := C.NET_DVR_PTZControlWithSpeed_Other(C.LONG(lUserID), C.LONG(lChannel), C.DWORD(dwPTZCommand), C.DWORD(dwStop), C.DWORD(dwSpeed))
  187. if state == C.FALSE {
  188. return LastError("NET_DVR_PTZControlWithSpeed_Other")
  189. }
  190. return nil
  191. }
  192. func CNET_DVR_DEVICEINFO_V30ToGO(CData *C.NET_DVR_DEVICEINFO_V30) NET_DVR_DEVICEINFO_V30 {
  193. var goData NET_DVR_DEVICEINFO_V30
  194. // Copy the SSerialNumber field
  195. for i := 0; i < 48; i++ {
  196. goData.SSerialNumber[i] = BYTE(byte(CData.sSerialNumber[i]))
  197. }
  198. // Copy other fields
  199. goData.ByAlarmInPortNum = BYTE(CData.byAlarmInPortNum)
  200. goData.ByAlarmOutPortNum = BYTE(CData.byAlarmOutPortNum)
  201. goData.ByDiskNum = BYTE(CData.byDiskNum)
  202. goData.ByDVRType = BYTE(CData.byDVRType)
  203. goData.ByChanNum = BYTE(CData.byChanNum)
  204. goData.ByStartChan = BYTE(CData.byStartChan)
  205. goData.ByAudioChanNum = BYTE(CData.byAudioChanNum)
  206. goData.ByIPChanNum = BYTE(CData.byIPChanNum)
  207. goData.ByZeroChanNum = BYTE(CData.byZeroChanNum)
  208. goData.ByMainProto = BYTE(CData.byMainProto)
  209. goData.BySubProto = BYTE(CData.bySubProto)
  210. goData.BySupport = BYTE(CData.bySupport)
  211. goData.BySupport1 = BYTE(CData.bySupport1)
  212. goData.BySupport2 = BYTE(CData.bySupport2)
  213. goData.WDevType = WORD(CData.wDevType)
  214. goData.BySupport3 = BYTE(CData.bySupport3)
  215. goData.ByMultiStreamProto = BYTE(CData.byMultiStreamProto)
  216. goData.ByStartDChan = BYTE(CData.byStartDChan)
  217. goData.ByStartDTalkChan = BYTE(CData.byStartDTalkChan)
  218. goData.ByHighDChanNum = BYTE(CData.byHighDChanNum)
  219. goData.BySupport4 = BYTE(CData.bySupport4)
  220. goData.ByLanguageType = BYTE(CData.byLanguageType)
  221. goData.ByVoiceInChanNum = BYTE(CData.byVoiceInChanNum)
  222. goData.ByStartVoiceInChanNo = BYTE(CData.byStartVoiceInChanNo)
  223. return goData
  224. }