[IOT-1604] Fix cloud routing code
[iotivity.git] / cloud / stack / src / main / java / org / iotivity / cloud / base / device / CoapDevice.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.base.device;
23
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.Iterator;
28
29 import org.iotivity.cloud.base.connector.CoapClient;
30 import org.iotivity.cloud.base.connector.ConnectorPool;
31 import org.iotivity.cloud.base.exception.ClientException;
32 import org.iotivity.cloud.base.protocols.IRequest;
33 import org.iotivity.cloud.base.protocols.IResponse;
34 import org.iotivity.cloud.base.protocols.MessageBuilder;
35 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
36 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
37 import org.iotivity.cloud.base.protocols.enums.Observe;
38 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
39 import org.iotivity.cloud.util.Bytes;
40 import org.iotivity.cloud.util.Log;
41
42 import io.netty.channel.ChannelHandlerContext;
43
44 public class CoapDevice extends Device {
45     private CoapClient                 mCoapClient         = null;
46     private String                     mUserId             = null;
47     private String                     mDeviceId           = null;
48     private String                     mAccessToken        = null;
49     private Date                       mIssuedTime         = null;
50     private int                        mExpiredPolicy      = 0;
51     private ArrayList<IRequestChannel> mObserveChannelList = new ArrayList<>();
52     private HashMap<Long, IRequest>    mObserveRequestList = new HashMap<>();
53
54     private static final int           INFINITE_TIME       = -1;
55
56     public CoapDevice(ChannelHandlerContext ctx) {
57         super(ctx);
58     }
59
60     public void updateDevice(String did, String uid, String accesstoken) {
61         mDeviceId = did;
62         mUserId = uid;
63         mAccessToken = accesstoken;
64     }
65
66     @Override
67     public String getDeviceId() {
68         return mDeviceId;
69     }
70
71     @Override
72     public String getUserId() {
73         return mUserId;
74     }
75
76     @Override
77     public String getAccessToken() {
78         return mAccessToken;
79     }
80
81     public Date getIssuedTime() {
82         return mIssuedTime;
83     }
84
85     public int getExpiredPolicy() {
86         return mExpiredPolicy;
87     }
88
89     public void setExpiredPolicy(int expiredPolicy) {
90         mIssuedTime = new Date();
91         this.mExpiredPolicy = expiredPolicy;
92     }
93
94     public void setUerId(String userId) {
95         this.mUserId = userId;
96     }
97
98     public void setAccessToken(String accessToken) {
99         this.mAccessToken = accessToken;
100     }
101
102     public void addObserveChannel(IRequestChannel channel) {
103         mObserveChannelList.add(channel);
104     }
105
106     public void removeObserveChannel(IRequestChannel channel)
107             throws ClientException {
108         if (mObserveChannelList.contains(channel)) {
109
110             Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
111             while (iterator.hasNext()) {
112                 Long token = iterator.next();
113                 CoapClient coapClient = (CoapClient) channel;
114                 if (coapClient.isObserveRequest(token) != null) {
115                     coapClient.removeObserve(token);
116                     CoapRequest coapRequest = (CoapRequest) mObserveRequestList
117                             .get(token);
118                     coapRequest.setObserve(Observe.UNSUBSCRIBE);
119                     IResponse response = MessageBuilder.createResponse(
120                             coapRequest, ResponseStatus.CONTENT, null, null);
121                     sendResponse(response);
122                 }
123             }
124             mObserveChannelList.remove(channel);
125         }
126     }
127
128     public void addObserveRequest(Long token, IRequest request) {
129
130         mObserveRequestList.put(token, request);
131     }
132
133     public void removeObserveRequest(Long token) {
134
135         mObserveRequestList.remove(token);
136     }
137
138     // This is called by cloud resource model
139     @Override
140     public void sendResponse(IResponse response) {
141         // This message must converted to CoapResponse
142         CoapResponse coapResponse = (CoapResponse) response;
143
144         Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
145         while (iterator.hasNext()) {
146             Long token = iterator.next();
147             Long respToken = Bytes.bytesToLong(coapResponse.getToken());
148             if (respToken.equals(token)
149                     && coapResponse.getObserve() == Observe.NOTHING) {
150                 iterator.remove();
151             }
152         }
153         ctx.channel().writeAndFlush(response);
154     }
155
156     public IRequestChannel getRequestChannel() {
157         if (mCoapClient == null) {
158             mCoapClient = new CoapClient(ctx.channel());
159         }
160
161         return mCoapClient;
162     }
163
164     public boolean isExpiredTime() {
165
166         if (mExpiredPolicy == INFINITE_TIME) {
167             return false;
168         }
169
170         Date currentTime = new Date();
171         long difference = currentTime.getTime() - mIssuedTime.getTime();
172         long remainTime = mExpiredPolicy - difference / 1000;
173
174         if (remainTime < 0) {
175
176             Log.w("accessToken is expired..");
177             return true;
178         }
179
180         return false;
181     }
182
183     @Override
184     public void onConnected() {
185         mObserveChannelList.addAll(ConnectorPool.getConnectionList());
186     }
187
188     @Override
189     public void onDisconnected() {
190         Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
191         while (iterator.hasNext()) {
192             Long token = iterator.next();
193             for (IRequestChannel serverChannel : mObserveChannelList) {
194                 CoapClient coapClient = (CoapClient) serverChannel;
195                 if (coapClient != null
196                         && coapClient.isObserveRequest(token) != null) {
197                     CoapRequest coapRequest = (CoapRequest) mObserveRequestList
198                             .get(token);
199                     coapRequest.setObserve(Observe.UNSUBSCRIBE);
200                     coapRequest.setToken(Bytes.longTo8Bytes(token));
201                     serverChannel.sendRequest(MessageBuilder.modifyRequest(
202                             coapRequest, null, null, null, null), this);
203                 }
204             }
205         }
206     }
207 }