[IOT-1616] CSM signaling supported in CoAP D2S communication
[iotivity.git] / cloud / stack / src / main / java / org / iotivity / cloud / base / protocols / coap / CoapLogHandler.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.protocols.coap;
23
24 import org.iotivity.cloud.util.Log;
25
26 import io.netty.channel.ChannelDuplexHandler;
27 import io.netty.channel.ChannelHandler.Sharable;
28 import io.netty.channel.ChannelHandlerContext;
29 import io.netty.channel.ChannelPromise;
30
31 /**
32  *
33  * This class provides a set of APIs to print out logs for CoAP request and
34  * response.
35  *
36  */
37 @Sharable
38 public class CoapLogHandler extends ChannelDuplexHandler {
39
40     static final int MAX_LOGLEN = 100;
41
42     @Override
43     public void channelActive(ChannelHandlerContext ctx) throws Exception {
44         Log.v(ctx.channel().id().asLongText().substring(26)
45                 + " Connected, Address: "
46                 + ctx.channel().remoteAddress().toString());
47
48         ctx.fireChannelActive();
49     }
50
51     @Override
52     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
53         ctx.fireChannelInactive();
54         Log.v(ctx.channel().id().asLongText().substring(26)
55                 + " Disconnected, Address: "
56                 + ctx.channel().remoteAddress().toString());
57     }
58
59     @Override
60     public void write(ChannelHandlerContext ctx, Object msg,
61             ChannelPromise promise) {
62
63         String log = getCoapLog(ctx, msg);
64
65         Log.v(log);
66
67         ctx.writeAndFlush(msg);
68     }
69
70     @Override
71     public void channelRead(ChannelHandlerContext ctx, Object msg)
72             throws Exception {
73
74         String log = getCoapLog(ctx, msg);
75
76         Log.v(log);
77
78         ctx.fireChannelRead(msg);
79
80     }
81
82     private String getCoapLog(ChannelHandlerContext ctx, Object msg) {
83         if (msg instanceof CoapRequest) {
84             return composeCoapRequest(
85                     ctx.channel().id().asLongText().substring(26),
86                     (CoapRequest) msg);
87         } else if (msg instanceof CoapSignaling) {
88             return composeCoapSignaling(
89                     ctx.channel().id().asLongText().substring(26),
90                     (CoapSignaling) msg);
91         } else {
92             return composeCoapResponse(
93                     ctx.channel().id().asLongText().substring(26),
94                     (CoapResponse) msg);
95         }
96     }
97
98     private String composeCoapSignaling(String channelId,
99             CoapSignaling signaling) {
100         StringBuilder strBuilder = new StringBuilder();
101
102         strBuilder.append(channelId);
103         strBuilder.append(" " + signaling.getTokenString());
104
105         switch (signaling.getSignalingMethod()) {
106             case CSM:
107                 strBuilder.append(" 7.01 CSM");
108                 strBuilder.append(" SERVER-NAME:");
109                 strBuilder.append(signaling.getCsmServerName());
110                 strBuilder.append(" MAX-MESSAGE-SIZE:");
111                 strBuilder.append(signaling.getCsmMaxMessageSize());
112                 strBuilder.append(" BLOCK-WISE-TRANSFER:");
113                 strBuilder.append(signaling.getCsmBlockWiseTransfer());
114                 break;
115             case PING:
116                 strBuilder.append(" 7.02 PING");
117                 break;
118             case PONG:
119                 strBuilder.append(" 7.03 PONG");
120                 break;
121             case RELEASE:
122                 strBuilder.append(" 7.04 RELEASE");
123                 break;
124             case ABORT:
125                 strBuilder.append(" 7.05 ABORT");
126                 break;
127             default:
128                 break;
129         }
130
131         if (signaling.getPayloadSize() > 0) {
132             strBuilder.append(" SZ:" + signaling.getPayloadSize() + " P:"
133                     + new String(signaling.getPayload(), 0,
134                             signaling.getPayloadSize() > MAX_LOGLEN ? MAX_LOGLEN
135                                     : signaling.getPayloadSize()));
136         }
137         return strBuilder.toString();
138     }
139
140     private String composeCoapRequest(String channelId, CoapRequest request) {
141         StringBuilder strBuilder = new StringBuilder();
142
143         strBuilder.append(channelId);
144         strBuilder.append(" " + request.getTokenString());
145
146         switch (request.getMethod()) {
147             case DELETE:
148                 strBuilder.append(" DELETE ");
149                 break;
150             case GET:
151                 switch (request.getObserve()) {
152                     case SUBSCRIBE:
153                         strBuilder.append(" GET OBSERVE ");
154                         break;
155                     case UNSUBSCRIBE:
156                         strBuilder.append(" GET OBSERVE CANCEL ");
157                         break;
158                     default:
159                         strBuilder.append(" GET ");
160                         break;
161                 }
162                 break;
163             case POST:
164                 strBuilder.append(" POST ");
165                 break;
166             case PUT:
167                 strBuilder.append(" PUT ");
168                 break;
169         }
170
171         strBuilder.append(request.getUriPath());
172         String query = request.getUriQuery();
173         if (query != null) {
174             strBuilder.append("/?" + query);
175         }
176
177         if (request.getPayloadSize() > 0) {
178             strBuilder
179                     .append(" SZ:" + request.getPayloadSize() + " P:"
180                             + new String(request.getPayload(), 0,
181                                     request.getPayloadSize() > MAX_LOGLEN
182                                             ? MAX_LOGLEN
183                                             : request.getPayloadSize()));
184         }
185
186         return strBuilder.toString();
187     }
188
189     private String composeCoapResponse(String channelId,
190             CoapResponse response) {
191         StringBuilder strBuilder = new StringBuilder();
192
193         strBuilder.append(channelId);
194         strBuilder.append(" " + response.getTokenString());
195
196         switch (response.getStatus()) {
197             case BAD_GATEWAY:
198                 strBuilder.append(" 5.02 Bad Gateway");
199                 break;
200             case BAD_OPTION:
201                 strBuilder.append(" 4.02 Bad Option");
202                 break;
203             case BAD_REQUEST:
204                 strBuilder.append(" 4.00 Bad Request");
205                 break;
206             case CHANGED:
207                 strBuilder.append(" 2.04 Changed");
208                 break;
209             case CONTENT:
210                 strBuilder.append(" 2.05 Content");
211                 break;
212             case CREATED:
213                 strBuilder.append(" 2.01 Created");
214                 break;
215             case DELETED:
216                 strBuilder.append(" 2.02 Deleted");
217                 break;
218             case FORBIDDEN:
219                 strBuilder.append(" 4.03 Forbidden");
220                 break;
221             case GATEWAY_TIMEOUT:
222                 strBuilder.append(" 5.04 Gateway Timeout");
223                 break;
224             case INTERNAL_SERVER_ERROR:
225                 strBuilder.append(" 5.00 Internal Server Error");
226                 break;
227             case METHOD_NOT_ALLOWED:
228                 strBuilder.append(" 4.05 Method Not Allowed");
229                 break;
230             case NOT_ACCEPTABLE:
231                 strBuilder.append(" 4.06 Not Acceptable");
232                 break;
233             case NOT_FOUND:
234                 strBuilder.append(" 4.04 Not Found");
235                 break;
236             case NOT_IMPLEMENTED:
237                 strBuilder.append(" 5.01 Not Implemented");
238                 break;
239             case PRECONDITION_FAILED:
240                 strBuilder.append(" 4.12 Precondition Failed");
241                 break;
242             case PROXY_NOT_SUPPORTED:
243                 strBuilder.append(" 5.05 Proxying Not Supported");
244                 break;
245             case REQUEST_ENTITY_TOO_LARGE:
246                 strBuilder.append(" 4.13 Request Entity Too Large");
247                 break;
248             case SERVICE_UNAVAILABLE:
249                 strBuilder.append(" 5.03 Service Unavailable");
250                 break;
251             case UNAUTHORIZED:
252                 strBuilder.append(" 4.01 Unauthorized");
253                 break;
254             case UNSUPPORTED_CONTENT_FORMAT:
255                 strBuilder.append(" 4.15 Unsupported Content-Format");
256                 break;
257             case VALID:
258                 strBuilder.append(" 2.03 Valid");
259                 break;
260             default:
261                 break;
262         }
263
264         switch (response.getObserve()) {
265             case SUBSCRIBE:
266                 strBuilder.append(" OBSERVE");
267                 break;
268             case UNSUBSCRIBE:
269                 strBuilder.append(" OBSERVE CANCEL");
270                 break;
271             case SEQUENCE_NUMBER:
272                 strBuilder.append(" OBSERVE SEQ:");
273                 strBuilder.append(response.getSequenceNumber());
274                 break;
275             default:
276                 break;
277         }
278
279         if (response.getPayloadSize() > 0) {
280             strBuilder
281                     .append(" SZ:" + response.getPayloadSize() + " P:"
282                             + new String(response.getPayload(), 0,
283                                     response.getPayloadSize() > MAX_LOGLEN
284                                             ? MAX_LOGLEN
285                                             : response.getPayloadSize()));
286         }
287
288         return strBuilder.toString();
289     }
290 }