device.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package model
  2. import (
  3. "fmt"
  4. "net"
  5. "sync"
  6. "time"
  7. )
  8. // Device represents a peer device.
  9. type Device struct {
  10. mu sync.RWMutex
  11. IP string `json:"ip"`
  12. Version string `json:"version"` // LocalSend protocol version
  13. Port int `json:"port"`
  14. Alias string `json:"alias"`
  15. Protocol ProtocolType `json:"protocol"`
  16. Fingerprint string `json:"fingerprint"`
  17. DeviceModel *string `json:"deviceModel"` // nullable
  18. DeviceType DeviceType `json:"deviceType"`
  19. Download bool `json:"download"` // Whether the device has download server running
  20. LastSeen time.Time `json:"lastSeen"`
  21. Available bool `json:"available"`
  22. }
  23. // NewDevice creates a new Device instance
  24. func NewDevice(info RegisterDto, ip net.IP, detectedPort int, detectedHttps bool) *Device {
  25. // Use registered port/protocol if provided, otherwise use detected ones
  26. port := info.Port
  27. if port <= 0 {
  28. port = detectedPort
  29. }
  30. protocol := ProtocolTypeHTTP
  31. if detectedHttps {
  32. protocol = ProtocolTypeHTTPS
  33. }
  34. return &Device{
  35. IP: ip.String(),
  36. Version: info.Version,
  37. Port: port,
  38. Alias: info.Alias,
  39. Protocol: protocol,
  40. Fingerprint: info.Fingerprint,
  41. DeviceModel: info.DeviceModel,
  42. DeviceType: info.DeviceType,
  43. Download: info.Download,
  44. LastSeen: time.Now(),
  45. Available: true,
  46. }
  47. }
  48. // UpdateLastSeen updates the last seen timestamp for a device
  49. func (d *Device) UpdateLastSeen() {
  50. d.mu.Lock()
  51. d.LastSeen = time.Now()
  52. d.Available = true
  53. d.mu.Unlock()
  54. }
  55. // GetLastSeen returns the last seen timestamp (thread-safe).
  56. func (d *Device) GetLastSeen() time.Time {
  57. d.mu.RLock()
  58. defer d.mu.RUnlock()
  59. return d.LastSeen
  60. }
  61. // GetAvailable returns whether the device is available (thread-safe).
  62. func (d *Device) GetAvailable() bool {
  63. d.mu.RLock()
  64. defer d.mu.RUnlock()
  65. return d.Available
  66. }
  67. // SetLastSeen sets the last seen timestamp (thread-safe).
  68. func (d *Device) SetLastSeen(t time.Time) {
  69. d.mu.Lock()
  70. d.LastSeen = t
  71. d.mu.Unlock()
  72. }
  73. // IsStale checks if a device hasn't been seen recently
  74. func (d *Device) IsStale(staleThreshold time.Duration) bool {
  75. d.mu.RLock()
  76. defer d.mu.RUnlock()
  77. return time.Since(d.LastSeen) > staleThreshold
  78. }
  79. // ToDebugString returns a string representation suitable for debugging
  80. func (d *Device) ToDebugString() string {
  81. shortFingerprint := d.Fingerprint
  82. if len(shortFingerprint) > 8 {
  83. shortFingerprint = shortFingerprint[:8]
  84. }
  85. var deviceModelStr string
  86. if d.DeviceModel != nil {
  87. deviceModelStr = *d.DeviceModel
  88. } else {
  89. deviceModelStr = "nil"
  90. }
  91. return fmt.Sprintf("Device{IP: %s, Protocol: %s, Port: %d, Alias: %s, Fingerprint: %s..., DeviceModel: %s, DeviceType: %s, Download: %t}",
  92. d.IP, d.Protocol, d.Port, d.Alias, shortFingerprint, deviceModelStr, d.DeviceType, d.Download)
  93. }
  94. // ToInfoDto converts a Device to an InfoDto for API responses
  95. func (d *Device) ToInfoDto() InfoDto {
  96. return InfoDto{
  97. Alias: d.Alias,
  98. Version: d.Version,
  99. DeviceModel: d.DeviceModel,
  100. DeviceType: d.DeviceType,
  101. Fingerprint: d.Fingerprint,
  102. Download: d.Download,
  103. }
  104. }
  105. // FromMulticastDto creates a Device from a MulticastDto and source IP
  106. func FromMulticastDto(dto MulticastDto, ip net.IP) *Device {
  107. return &Device{
  108. IP: ip.String(),
  109. Version: dto.Version,
  110. Port: dto.Port,
  111. Alias: dto.Alias,
  112. Protocol: dto.Protocol,
  113. Fingerprint: dto.Fingerprint,
  114. DeviceModel: dto.DeviceModel,
  115. DeviceType: dto.DeviceType,
  116. Download: dto.Download,
  117. LastSeen: time.Now(),
  118. Available: true,
  119. }
  120. }