/** * Makes sure that the response type is correct. The response type for a NON can be NON or CON. * The response type for a CON should either be an ACK with a piggy-backed response or, if an * empty ACK has already be sent, a CON or NON with a separate response. */ @Override public void sendResponse(final Exchange exchange, final Response response) { LOGGER.finer("Send response, failed transmissions: " + exchange.getFailedTransmissionCount()); // If a response type is set, we do not mess around with it. // Only if none is set, we have to decide for one here. Type respType = response.getType(); if (respType == null) { Type reqType = exchange.getCurrentRequest().getType(); if (reqType == Type.CON) { if (exchange.getCurrentRequest().isAcknowledged()) { // send separate response response.setType(Type.CON); } else { exchange.getCurrentRequest().setAcknowledged(true); // send piggy-backed response response.setType(Type.ACK); response.setMID(exchange.getCurrentRequest().getMID()); } } else { // send NON response response.setType(Type.NON); } LOGGER.finest( "Switched response message type from " + respType + " to " + response.getType() + " (request was " + reqType + ")"); } else if (respType == Type.ACK || respType == Type.RST) { response.setMID(exchange.getCurrentRequest().getMID()); } if (response.getType() == Type.CON) { LOGGER.finer("Scheduling retransmission for " + response); prepareRetransmission( exchange, new RetransmissionTask(exchange, response) { public void retransmit() { sendResponse(exchange, response); } }); } super.sendResponse(exchange, response); }
/** * This method is used to apply resource-specific knowledge on the exchange. If the request was * successful, it sets the Observe option for the response. It is important to use the * notificationOrderer of the resource here. Further down the layer, race conditions could cause * local reordering of notifications. If the response has an error code, no observe relation can * be established and if there was one previously it is canceled. When this resource allows to be * observed by clients and the request is a GET request with an observe option, the {@link * ServerMessageDeliverer} already created the relation, as it manages the observing endpoints * globally. * * @param exchange the exchange * @param response the response */ public void checkObserveRelation(Exchange exchange, Response response) { /* * If the request for the specified exchange tries to establish an observer * relation, then the ServerMessageDeliverer must have created such a relation * and added to the exchange. Otherwise, there is no such relation. * Remember that different paths might lead to this resource. */ ObserveRelation relation = exchange.getRelation(); if (relation == null) return; // because request did not try to establish a relation if (CoAP.ResponseCode.isSuccess(response.getCode())) { response.getOptions().setObserve(notificationOrderer.getCurrent()); if (!relation.isEstablished()) { relation.setEstablished(true); addObserveRelation(relation); } else if (observeType != null) { // The resource can control the message type of the notification response.setType(observeType); } } // ObserveLayer takes care of the else case }