-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathptpip.go
More file actions
116 lines (96 loc) · 2.58 KB
/
ptpip.go
File metadata and controls
116 lines (96 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package ptpip
import (
"fmt"
"net"
"github.com/atotto/ptpip/packet"
"github.com/atotto/ptpip/ptp"
)
type Client struct {
commandConn net.Conn
eventConn net.Conn
config *Config
responder Responder
}
type ErrInvalidArgs struct {
message string
}
//
func (e *ErrInvalidArgs) Error() string {
return fmt.Sprintf("invalid argument: %s", e.message)
}
type Config struct {
GUID string
FriendlyName string
}
type Responder struct {
Addr string
GUID string
FriendlyName string
}
// NewConfig creates a new PTP-IP config for client connection.
// If guid argument less than 16, return ErrInvalidArgs.
// If friendlyName argument less than 20, return ErrInvalidArgs.
func NewConfig(guid, friendlyName string) (config *Config, err error) {
config = new(Config)
if len(guid) < 16 {
return nil, &ErrInvalidArgs{message: fmt.Sprintf("guid length must 16, got %d", len(guid))}
}
config.GUID = guid
if len(friendlyName) < 20 {
return nil, &ErrInvalidArgs{message: fmt.Sprintf("name length should be less than 20, got %d", len(friendlyName))}
}
config.FriendlyName = friendlyName
return
}
// Dial dial PTP-IP supported device.
// Default PTP-IP port number is 15740.
func DialConfig(addr string, config *Config) (c *Client, err error) {
c = new(Client)
c.config = config
err = c.initConnection(addr)
return
}
//
func (c *Client) initConnection(addr string) (err error) {
// CommandDataConnection
commandConn, err := net.Dial("tcp", addr)
if err != nil {
return
}
if err = packet.SendInitCommand(commandConn, c.config.GUID, c.config.FriendlyName); err != nil {
return
}
sessionID, guid, friendlyName, err := packet.RecvInitCommand(commandConn)
if err != nil {
return
}
c.commandConn = commandConn
c.responder.GUID = guid
c.responder.FriendlyName = friendlyName
// EventConnection
eventConn, err := net.Dial("tcp", addr)
if err != nil {
return
}
if err = packet.SendInitEvent(eventConn, sessionID); err != nil {
return
}
if err = packet.RecvInitEvent(eventConn); err != nil {
return
}
c.eventConn = eventConn
return
}
const (
kUNKNOWN_DATA_PHASE uint32 = 0x00000000
kNO_DATA_OR_DATA_IN_PHASE uint32 = 0x00000001
kDATA_OUT_PHASE uint32 = 0x00000002
)
func (c *Client) OperationSimple(operationCode ptp.OperationCode, transactionID uint32, parameters []uint32) (err error) {
dataPheseInfo := kNO_DATA_OR_DATA_IN_PHASE
if err = packet.SendOperationRequest(c.commandConn, dataPheseInfo, operationCode, transactionID, parameters); err != nil {
return
}
_, _, _, err = packet.RecvOperationResponse(c.commandConn)
return
}