7ab584e5841b96e203430c0554241a61406421fe
[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
104         if (channel != null) {
105             mObserveChannelList.add(channel);
106         }
107     }
108
109     public void removeObserveChannel(IRequestChannel channel)
110             throws ClientException {
111         if (channel != null && mObserveChannelList.contains(channel)) {
112
113             Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
114             while (iterator.hasNext()) {
115                 Long token = iterator.next();
116                 CoapClient coapClient = (CoapClient) channel;
117                 if (coapClient.isObserveRequest(token) != null) {
118                     IRequest getRequest = mObserveRequestList.get(token);
119
120                     CoapRequest coapRequest = (CoapRequest) getRequest;
121                     coapRequest.setObserve(Observe.UNSUBSCRIBE);
122
123                     coapClient.onResponseReceived(MessageBuilder.createResponse(
124                             coapRequest, ResponseStatus.CONTENT, null, null));
125                 }
126             }
127             mObserveChannelList.remove(channel);
128         }
129     }
130
131     public void addObserveRequest(Long token, IRequest request) {
132
133         mObserveRequestList.put(token, request);
134     }
135
136     public void removeObserveRequest(Long token) {
137
138         mObserveRequestList.remove(token);
139     }
140
141     // This is called by cloud resource model
142     @Override
143     public void sendResponse(IResponse response) {
144         // This message must converted to CoapResponse
145         CoapResponse coapResponse = (CoapResponse) response;
146
147         Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
148         while (iterator.hasNext()) {
149             Long token = iterator.next();
150             Long respToken = Bytes.bytesToLong(coapResponse.getToken());
151             if (respToken.equals(token)
152                     && coapResponse.getSequenceNumber() == -1) {
153                 iterator.remove();
154             }
155         }
156         ctx.channel().writeAndFlush(response);
157     }
158
159     public IRequestChannel getRequestChannel() {
160         if (mCoapClient == null) {
161             mCoapClient = new CoapClient(ctx.channel());
162         }
163
164         return mCoapClient;
165     }
166
167     public boolean isExpiredTime() {
168
169         if (mExpiredPolicy == INFINITE_TIME) {
170             return false;
171         }
172
173         Date currentTime = new Date();
174         long difference = currentTime.getTime() - mIssuedTime.getTime();
175         long remainTime = mExpiredPolicy - difference / 1000;
176
177         if (remainTime < 0) {
178
179             Log.w("accessToken is expired..");
180             return true;
181         }
182
183         return false;
184     }
185
186     @Override
187     public void onConnected() {
188         mObserveChannelList.addAll(ConnectorPool.getConnectionList());
189     }
190
191     @Override
192     public void onDisconnected() {
193         for (IRequestChannel serverChannel : mObserveChannelList) {
194             Iterator<Long> iterator = mObserveRequestList.keySet().iterator();
195             while (iterator.hasNext()) {
196                 Long token = iterator.next();
197                 CoapClient coapClient = (CoapClient) serverChannel;
198
199                 if (coapClient.isObserveRequest(token) != null) {
200                     CoapRequest coapRequest = (CoapRequest) mObserveRequestList
201                             .get(token);
202                     coapRequest.setObserve(Observe.UNSUBSCRIBE);
203                     coapRequest.setToken(Bytes.longTo8Bytes(token));
204                     serverChannel.sendRequest(MessageBuilder.modifyRequest(
205                             coapRequest, null, null, null, null), this);
206                 }
207             }
208         }
209     }
210 }