forked from Coccodrillo/apns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeedback.go
81 lines (65 loc) · 1.76 KB
/
feedback.go
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
package apns
import (
"bytes"
"crypto/tls"
"encoding/binary"
"net"
"time"
)
// Wait at most this many seconds for feedback data from Apple.
const FEEDBACK_TIMEOUT_SECONDS = 5
// FeedbackChannel will receive individual responses from Apple.
var FeedbackChannel = make(chan (*FeedbackResponse))
// If there's nothing to read, ShutdownChannel gets a true.
var ShutdownChannel = make(chan bool)
type FeedbackResponse struct {
Timestamp uint32
DeviceToken string
}
// Constructor.
func NewFeedbackResponse() (resp *FeedbackResponse) {
resp = new(FeedbackResponse)
return
}
// Connect to the Apple Feedback Service and check for feedback.
// Feedback consists of device identifiers that should
// not be sent to in the future; Apple does monitor that
// you respect this so you should be checking it ;)
func (this *Client) ListenForFeedback() (err error) {
cert, err := tls.LoadX509KeyPair(this.CertificateFile, this.KeyFile)
if err != nil {
return err
}
conf := &tls.Config{
Certificates: []tls.Certificate{cert},
}
conn, err := net.Dial("tcp", this.Gateway)
if err != nil {
return err
}
defer conn.Close()
conn.SetReadDeadline(time.Now().Add(FEEDBACK_TIMEOUT_SECONDS * time.Second))
tlsConn := tls.Client(conn, conf)
err = tlsConn.Handshake()
if err != nil {
return err
}
var tokenLength uint16
buffer := make([]byte, 38, 38)
deviceToken := make([]byte, 32, 32)
for {
_, err := conn.Read(buffer)
if err != nil {
ShutdownChannel <- true
break
}
resp := NewFeedbackResponse()
r := bytes.NewReader(buffer)
binary.Read(r, binary.BigEndian, &resp.Timestamp)
binary.Read(r, binary.BigEndian, &tokenLength)
binary.Read(r, binary.BigEndian, &deviceToken)
resp.DeviceToken = string(deviceToken)
FeedbackChannel <- resp
}
return nil
}