1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.kuali.mobility.push.dao;
16
17 import java.io.ByteArrayOutputStream;
18 import java.io.InputStream;
19 import java.sql.Timestamp;
20
21 import javax.net.ssl.SSLSocket;
22
23 import org.apache.commons.pool.impl.GenericObjectPool;
24 import org.apache.log4j.Logger;
25 import org.kuali.mobility.push.entity.Device;
26 import org.kuali.mobility.push.service.DeviceService;
27 import org.springframework.beans.factory.annotation.Autowired;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class DeviceFeedbackMonitor {
43
44
45 private static final Logger LOG = Logger.getLogger(DeviceFeedbackMonitor.class);
46
47
48
49
50
51 @Autowired
52 private DeviceService deviceService;
53
54
55 @Autowired
56 private GenericObjectPool<SSLSocket> iOSFeedbackConnectionPool;
57
58
59
60
61
62
63 public void checkDeviceFeedback(){
64 LOG.info("Checking Device Feedback");
65 checkiOSDeviceFeedback();
66 checkAndroidDeviceFeedback();
67 checkBlackberryDeviceFeedback();
68 }
69
70
71
72
73
74 private void checkiOSDeviceFeedback(){
75 LOG.info("Checking iOS Device Feedback");
76 final int cFEEDBACKTUPLESIZE = 38;
77 final int cBLOCKSIZE = 1024;
78 final int cBYTEMASK = 0x000000FF;
79
80
81
82 SSLSocket feedbackSocket = null;
83 try {
84 feedbackSocket = iOSFeedbackConnectionPool.borrowObject();
85 } catch (Exception e) {
86 LOG.info("Was unable to borrow SSQLSocket from Pool");
87 }
88
89 if(null == feedbackSocket){
90 LOG.info("APNS Feedback Socket is NOT connected.");
91 }else{
92 LOG.info("APNS Feedback Socket is connected. Checking Feedback.");
93 try{
94 InputStream in = feedbackSocket.getInputStream();
95
96
97 byte[] b = new byte[cBLOCKSIZE];
98 ByteArrayOutputStream message = new ByteArrayOutputStream();
99 int nbBytes = 0;
100
101
102 while ((nbBytes = in.read(b, 0, cBLOCKSIZE)) != -1) {
103 message.write(b, 0, nbBytes);
104 }
105
106 byte[] listOfDevices = message.toByteArray();
107 int nbDevices = listOfDevices.length / cFEEDBACKTUPLESIZE;
108 LOG.info(nbDevices + " devices had feedback.");
109
110 for (int j = 0; j < nbDevices; j++) {
111 int offset = j * cFEEDBACKTUPLESIZE;
112
113
114 int index = 0;
115 int firstByte = 0;
116 int secondByte = 0;
117 int thirdByte = 0;
118 int fourthByte = 0;
119 long anUnsignedInt = 0;
120
121
122
123 firstByte = (cBYTEMASK & ((int) listOfDevices[offset]));
124 secondByte = (cBYTEMASK & ((int) listOfDevices[offset + 1]));
125 thirdByte = (cBYTEMASK);
126 fourthByte = (cBYTEMASK & ((int) listOfDevices[offset + 3]));
127 index = index + 4;
128 anUnsignedInt = ((long) (firstByte << 24 | secondByte << 16 | thirdByte << 8 | fourthByte)) & 0xFFFFFFFFL;
129 Timestamp timestamp = new Timestamp(anUnsignedInt * 1000);
130
131
132 int deviceTokenLength = listOfDevices[offset + 4] << 8 | listOfDevices[offset + 5];
133
134
135 String deviceToken = "";
136 int octet = 0;
137 for (int k = 0; k < 32; k++) {
138 octet = (cBYTEMASK & ((int) listOfDevices[offset + 6 + k]));
139 deviceToken = deviceToken.concat(String.format("%02x", octet));
140 }
141
142 LOG.info(timestamp);
143 LOG.info(deviceToken);
144 Device dtoDelete = deviceService.findDeviceByRegId(deviceToken);
145 if(deviceService.removeDevice(dtoDelete)){
146 LOG.info("Deleted " + dtoDelete.getDeviceName());
147 }
148 }
149
150
151 }catch(Exception e){
152
153
154 }finally{
155 try{
156 feedbackSocket.close();
157 }catch(Exception e){
158
159 }
160 }
161 }
162 }
163
164
165
166
167
168
169 private void checkAndroidDeviceFeedback(){
170 LOG.info("Checking Android Device Feedback - STUB");
171 }
172
173
174
175
176
177 private void checkBlackberryDeviceFeedback(){
178 LOG.info("Checking Blackberry Device Feedback - STUB");
179 }
180
181
182
183
184
185
186 public DeviceService getDeviceService() {
187 return deviceService;
188 }
189
190
191
192
193
194 public void setDeviceService(DeviceService deviceService) {
195 this.deviceService = deviceService;
196 }
197 }