1
1
from struct import unpack
2
2
from socket import MSG_WAITALL
3
+ from datetime import datetime
3
4
4
5
from util import *
5
6
from protocol import *
9
10
10
11
def get_station_info (s , src , name ):
11
12
dcp .send_request (s , src , PNDCPBlock .NAME_OF_STATION , bytes (name , 'utf-8' ))
12
- ret = dcp .read_response (s , src , want = (PNDCPBlock .IP_ADDRESS , PNDCPBlock .DEVICE_ID ))
13
-
14
- ip = ""
15
- vendorHigh = vendorLow = devHigh = devLow = 0
16
- for block in ret :
17
- if (block .option , block .suboption ) == PNDCPBlock .IP_ADDRESS :
18
- ip = s2ip (block .payload [0 :4 ])
19
- if (block .option , block .suboption ) == PNDCPBlock .DEVICE_ID :
20
- vendorHigh , vendorLow , devHigh , devLow = unpack (">BBBB" , block .payload [0 :4 ])
21
-
22
- return ip , vendorHigh , vendorLow , devHigh , devLow
13
+ resp = list (dcp .read_response (s , src , once = True ).items ())[0 ]
14
+ return dcp .DCPDeviceDescription (* resp )
23
15
24
16
25
17
class RPCCon :
26
- def __init__ (self , ip , vendorHigh , vendorLow , devHigh , devLow ):
27
- self .peer = (ip , 0x8894 )
28
- self .ip = ip
18
+ def __init__ (self , info ):
19
+ self .info = info
20
+ self .peer = (info .ip , 0x8894 )
21
+
22
+ self .ar_uuid = bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ])
23
+ self .activity_uuid = ar_uuid
24
+
25
+ self .local_object_uuid = PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , 0x76 , 0x54 , 0x32 , 0x10 ])
26
+ self .remote_object_uuid = PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , self .info .devHigh , self .info .devLow , self .info .vendorHigh , self .info .vendorLow ])
27
+
28
+ self .live = None
29
+
29
30
self .u = socket (AF_INET , SOCK_DGRAM )
30
- self .vendorHigh , self .vendorLow , self .devHigh , self .devLow = vendorHigh , vendorLow , devHigh , devLow
31
31
32
- def read (self , api , slot , subslot , idx ):
33
- block = PNBlockHeader (PNBlockHeader .IDOReadRequestHeader , 60 , 0x01 , 0x00 )
34
- iod = PNIODHeader (bytes (block ), 0 ,
35
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]),
36
- api , slot , subslot , 0 , idx , 4096 , bytes (16 ), bytes (8 ), payload = bytes ())
37
- nrd = PNNRDData (1500 , len (iod ), 1500 , 0 , len (iod ), payload = iod )
38
- rpc = PNRPCHeader (0x04 , PNRPCHeader .REQUEST ,
32
+
33
+ def _create_rpc (self , operation , nrd ):
34
+ return PNRPCHeader (0x04 , PNRPCHeader .REQUEST ,
39
35
0x20 , # Flags1
40
36
0x00 , # Flags2
41
37
bytes ([0x00 , 0x00 , 0x00 ]), # DRep
42
38
0x00 , # Serial High
43
- PNRPCHeader . OBJECT_UUID_PREFIX + bytes ([ 0x00 , 0x01 , self .devHigh , self . devLow , self . vendorHigh , self . vendorLow ]), # ObjectUUID
39
+ self .remote_object_uuid ,
44
40
PNRPCHeader .IFACE_UUID_DEVICE ,
45
- bytes ([ 0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]), # ActivityUUID
41
+ self . activity_uuid ,
46
42
0 , # ServerBootTime
47
43
1 , # InterfaceVersion
48
44
0 , # SequenceNumber
49
- PNRPCHeader . READ , # OperationNumber
45
+ operation ,
50
46
0xFFFF , # InterfaceHint
51
47
0xFFFF , # ActivityHint
52
- len (nrd ), # LengthOfBody
48
+ len (nrd ),
53
49
0 , # FragmentNumber
54
50
0 , # AuthenticationProtocol
55
51
0 , # SerialLow
56
52
payload = nrd
57
53
)
54
+
55
+ def _create_nrd (self , payload ):
56
+ return PNNRDData (1500 , len (payload ), 1500 , 0 , len (payload ), payload = payload )
57
+
58
+ def _check_timeout (self ):
59
+ if (datetime .now () - self .live ).seconds >= 10 :
60
+ self .connect ()
61
+
62
+
63
+ def connect (self , src_mac = None ):
64
+ if self .live is None :
65
+ self .src_mac = src_mac
66
+
67
+ block = PNBlockHeader (0x0101 , PNARBlockRequest .fmt_size - 2 , 0x01 , 0x00 )
68
+ ar = PNARBlockRequest (bytes (block ),
69
+ 0x0006 , # AR Type
70
+ self .ar_uuid , # AR UUID
71
+ 0x1234 , # Session key
72
+ src_mac ,
73
+ self .local_object_uuid ,
74
+ 0x131 , # AR Properties
75
+ 100 , # Timeout factor
76
+ 0x8892 , # udp port?
77
+ 2 ,
78
+ bytes ("tp" , encoding = "utf-8" ), payload = bytes ()
79
+ )
80
+ nrd = self ._create_nrd (ar )
81
+ rpc = self ._create_rpc (PNRPCHeader .CONNECT , nrd )
58
82
self .u .sendto (bytes (rpc ), self .peer )
59
83
60
84
data = self .u .recvfrom (4096 )[0 ]
61
- rpc = PNRPCHeader (data )
62
- nrd = PNNRDData (rpc .payload )
63
- iod = PNIODHeader (nrd .payload )
64
- block = PNBlockHeader (iod .block_header )
85
+ # ignore response
86
+ #rpc = PNRPCHeader(data)
87
+ #nrd = PNNRDData(rpc.payload)
88
+ #ar = PNARBlockRequest(nrd.payload)
89
+ #block = PNBlockHeader(iod.block_header)
65
90
66
- return iod
91
+ self . live = datetime . now ()
67
92
68
- def write (self , api , slot , subslot , idx , data ):
69
- block = PNBlockHeader (0x8 , 60 , 0x01 , 0x00 )
70
- iod = PNIODHeader (bytes (block ), 0 ,
71
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]),
72
- api , slot , subslot , 0 , idx , len (data ), bytes (16 ), bytes (8 ), payload = bytes (data ))
73
- nrd = PNNRDData (1500 , len (iod ), 1500 , 0 , len (iod ), payload = iod )
74
- rpc = PNRPCHeader (0x04 , PNRPCHeader .REQUEST ,
75
- 0x20 , # Flags1
76
- 0x00 , # Flags2
77
- bytes ([0x00 , 0x00 , 0x00 ]), # DRep
78
- 0x00 , # Serial High
79
- PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , self .devHigh , self .devLow , self .vendorHigh , self .vendorLow ]), # ObjectUUID
80
- PNRPCHeader .IFACE_UUID_DEVICE ,
81
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]), # ActivityUUID
82
- 0 , # ServerBootTime
83
- 1 , # InterfaceVersion
84
- 0 , # SequenceNumber
85
- PNRPCHeader .WRITE , # OperationNumber
86
- 0xFFFF , # InterfaceHint
87
- 0xFFFF , # ActivityHint
88
- len (nrd ), # LengthOfBody
89
- 0 , # FragmentNumber
90
- 0 , # AuthenticationProtocol
91
- 0 , # SerialLow
92
- payload = nrd
93
- )
93
+ def read (self , api , slot , subslot , idx ):
94
+ self ._check_timeout ()
95
+
96
+ block = PNBlockHeader (PNBlockHeader .IDOReadRequestHeader , 60 , 0x01 , 0x00 )
97
+ iod = PNIODHeader (bytes (block ), 0 , self .ar_uuid , api , slot , subslot , 0 , idx , 4096 , bytes (16 ), bytes (8 ), payload = bytes ())
98
+ nrd = self ._create_nrd (iod )
99
+ rpc = self ._create_rpc (PNRPCHeader .READ , nrd )
94
100
self .u .sendto (bytes (rpc ), self .peer )
95
101
96
102
data = self .u .recvfrom (4096 )[0 ]
103
+ rpc = PNRPCHeader (data )
104
+ nrd = PNNRDData (rpc .payload )
105
+ iod = PNIODHeader (nrd .payload )
106
+ block = PNBlockHeader (iod .block_header )
107
+
108
+ self .live = datetime .now ()
97
109
98
110
return iod
99
111
100
112
def read_implicit (self , api , slot , subslot , idx ):
101
113
block = PNBlockHeader (PNBlockHeader .IDOReadRequestHeader , 60 , 0x01 , 0x00 )
102
114
iod = PNIODHeader (bytes (block ), 0 , bytes (16 ), api , slot , subslot , 0 , idx , 4096 , bytes (16 ), bytes (8 ), payload = bytes ())
103
- nrd = PNNRDData (1500 , len (iod ), 1500 , 0 , len (iod ), payload = iod )
104
- rpc = PNRPCHeader (0x04 , PNRPCHeader .REQUEST ,
105
- 0x20 , # Flags1
106
- 0x00 , # Flags2
107
- bytes ([0x00 , 0x00 , 0x00 ]), # DRep
108
- 0x00 , # Serial High
109
- PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , self .devHigh , self .devLow , self .vendorHigh , self .vendorLow ]), # ObjectUUID
110
- PNRPCHeader .IFACE_UUID_DEVICE ,
111
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]), # ActivityUUID
112
- 0 , # ServerBootTime
113
- 1 , # InterfaceVersion
114
- 0 , # SequenceNumber
115
- PNRPCHeader .IMPLICIT_READ , # OperationNumber
116
- 0xFFFF , # InterfaceHint
117
- 0xFFFF , # ActivityHint
118
- len (nrd ), # LengthOfBody
119
- 0 , # FragmentNumber
120
- 0 , # AuthenticationProtocol
121
- 0 , # SerialLow
122
- payload = nrd
123
- )
115
+ nrd = self ._create_nrd (iod )
116
+ rpc = self ._create_rpc (PNRPCHeader .IMPLICIT_READ , nrd )
124
117
self .u .sendto (bytes (rpc ), self .peer )
125
118
126
119
data = self .u .recvfrom (4096 )[0 ]
@@ -131,51 +124,20 @@ def read_implicit(self, api, slot, subslot, idx):
131
124
132
125
return iod
133
126
134
- def connect (self , src_mac ):
135
- block = PNBlockHeader (0x0101 , PNARBlockRequest .fmt_size - 2 , 0x01 , 0x00 )
136
- ar = PNARBlockRequest (bytes (block ),
137
- 0x0006 , # AR Type
138
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]), # AR UUID
139
- 0x1234 , # Session key
140
- src_mac ,
141
- PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , 0x76 , 0x54 , 0x32 , 0x10 ]),
142
- 0x131 , # AR Properties
143
- 100 , # Timeout factor
144
- 0x8892 , # udp port?
145
- 2 ,
146
- bytes ("tp" , encoding = "utf-8" ), payload = bytes ()
147
- )
148
- nrd = PNNRDData (1500 , len (ar ), 1500 , 0 , len (ar ), payload = ar )
149
- rpc = PNRPCHeader (0x04 , PNRPCHeader .REQUEST ,
150
- 0x20 , # Flags1
151
- 0x00 , # Flags2
152
- bytes ([0x00 , 0x00 , 0x00 ]), # DRep
153
- 0x00 , # Serial High
154
- PNRPCHeader .OBJECT_UUID_PREFIX + bytes ([0x00 , 0x01 , self .devHigh , self .devLow , self .vendorHigh , self .vendorLow ]), # ObjectUUID
155
- PNRPCHeader .IFACE_UUID_DEVICE ,
156
- bytes ([0x00 , 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ]), # ActivityUUID
157
- 0 , # ServerBootTime
158
- 1 , # InterfaceVersion
159
- 0 , # SequenceNumber
160
- PNRPCHeader .CONNECT , # OperationNumber
161
- 0xFFFF , # InterfaceHint
162
- 0xFFFF , # ActivityHint
163
- len (nrd ), # LengthOfBody
164
- 0 , # FragmentNumber
165
- 0 , # AuthenticationProtocol
166
- 0 , # SerialLow
167
- payload = nrd
168
- )
127
+ def write (self , api , slot , subslot , idx , data ):
128
+ self ._check_timeout ()
129
+ block = PNBlockHeader (0x8 , 60 , 0x01 , 0x00 )
130
+ iod = PNIODHeader (bytes (block ), 0 , self .ar_uuid , api , slot , subslot , 0 , idx , len (data ), bytes (16 ), bytes (8 ), payload = bytes (data ))
131
+ nrd = self ._create_nrd (iod )
132
+ rpc = self ._create_rpc (PNRPCHeader .WRITE , nrd )
169
133
self .u .sendto (bytes (rpc ), self .peer )
170
134
171
135
data = self .u .recvfrom (4096 )[0 ]
172
- #rpc = PNRPCHeader(data)
173
- #nrd = PNNRDData(rpc.payload)
174
- #ar = PNARBlockRequest(nrd.payload)
175
- #block = PNBlockHeader(iod.block_header)
136
+ # ignore response
176
137
177
- return ar
178
-
138
+ self .live = datetime .now ()
139
+
140
+
179
141
def read_inm0filter (self ):
180
142
data = self .read (api = 0 , slot = 0 , subslot = 0 , idx = 0xF840 ).payload
181
143
block = PNBlockHeader (data )
0 commit comments