*
* @param rxResponse
* the {@linkplain RxResponse16}
*/
protected void handleRxResponse16(final RxResponse16 rxResponse) {
final RemoteNode rn = findRemoteNode(rxResponse);
if (rn == null) {
return;
}
final Command command = extractCommand(rxResponse);
if (command == null) {
log.error(String.format("An unrecognized %1$s command was received from %2$s",
rxResponse.getData()[0], rn.getAddress()));
return;
}
final int failures = rxResponse.getData()[1]; // TODO : Handle cases where failures exist
final RxData.Status status = failures == 0 ? RxData.Status.NORMAL : RxData.Status.GENERAL_FAILURE;
log.info(String.format("======= Recieved %1$s command from wireless address %2$s (signal strength: %3$s) with (%4$s) failures =======",
command, rn.getAddress(), rxResponse.getRssi(), failures));
if (command == Command.CAM_TAKE_PIC) {
ImageCapture ic;
RxTxImage rxTxImage = imgMap.containsKey(rn.getAddress()) ? imgMap.get(rn.getAddress()) : null;
if (rxTxImage == null || rxTxImage.hasTimedOut()) {
if (rxTxImage != null) {
rxTxImage.resetRxTxAttempts();
ic = rxTxImage.createImageSegmentsSnapshot();
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_FAILED, command, ic,
RS.rbLabel(KEY.SERVICE_RX_IMAGE_TIMEOUT, ic));
}
// TODO : add check for what sensor tripped the image and image format detection (instead of using just JPEG)
rxTxImage = new RxTxJPEG(rn, status, rxResponse.getRssi(), null);
imgMap.put(rn.getAddress(), rxTxImage);
ic = rxTxImage.createImageSegmentsSnapshot();
log.info(String.format("======= Receiving chunked image data (%1$s) =======", rxTxImage));
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_MULTIPART, command, ic,
RS.rbLabel(KEY.SERVICE_RX_IMAGE_MULTPART, ic));
}
int[] imageChunk = rxTxImage.addImageSegment(rxResponse.getData(), IMAGE_START_INDEX);
if (log.isDebugEnabled()) {
log.debug(String.format("Sensor Tripped (%1$s, LENGTH: %2$s, RAW LENGTH: %3$s) DATA: %4$s",
rxTxImage, imageChunk.length, rxResponse.getLength().getLength(), ByteUtils.toBase16(imageChunk)));
}
if (rxTxImage.isEof()) {
if (rxTxImage.getStatus() != RxData.Status.NORMAL) {
final int retries = rn.getCamImgCaptureRetryCnt();
ic = rxTxImage.createImageSegmentsSnapshot();
if (retries != 0 && rxTxImage.getRxTxAttempts() <= retries) {
rxTxImage.incRxTxAttempts();
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_FAILED_RETRYING, command, ic,
RS.rbLabel(KEY.SERVICE_RX_IMAGE_LOST_PACKETS_RETRY, ic, rxTxImage.getRxTxAttempts(), retries));
ServiceProvider.IMPL.getWirelessService().sendData(rn, command, 0, false);
} else {
try {
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_FAILED, command, ic,
RS.rbLabel(KEY.SERVICE_RX_IMAGE_LOST_PACKETS, ic, rxTxImage.getRxTxAttempts()));
} finally {
imgMap.remove(rn.getAddress());
}
}
} else {
try {
ic = rxTxImage.writeImageSegments();
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_SUCCESS, command, ic,
RS.rbLabel(KEY.SERVICE_RX_IMAGE_SUCCESS, ic));
} catch (IOException e) {
log.info("Cannot save image ID: " + UGateUtil.calFormat(rxTxImage.getCreatedTime()), e);
} finally {
imgMap.remove(rn.getAddress());
}
}
}
} else if (command == Command.ACCESS_PIN_CHANGE) {
//final int hasFailures = rxResponse.getData()[1];
final KeyCodes kc = new KeyCodes(rn, status, rxResponse.getRssi(), rxResponse.getData()[1],
rxResponse.getData()[2], rxResponse.getData()[3]);
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_SUCCESS, command, kc,
RS.rbLabel(KEY.SERVICE_RX_KEYCODES, kc));
} else if (command == Command.SERVO_LASER_CALIBRATE) {
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_SUCCESS, command,
new RxRawData<Void>(rn, status, rxResponse.getRssi(), null),
failures > 0 ? RS.rbLabel(KEY.LASER_CALIBRATION_FAILED) : RS.rbLabel(KEY.LASER_CALIBRATION_SUCCESS));
} else if (command == Command.SENSOR_GET_READINGS || command == Command.GATE_TOGGLE_OPEN_CLOSE) {
int i = 1;
final RemoteNodeReading rnr = new RemoteNodeReading();
rnr.setRemoteNode(rn);
rnr.setReadDate(new Date());
rnr.setSignalStrength(rxResponse.getRssi());
rnr.setSonarFeet(rxResponse.getData()[++i]);
rnr.setSonarInches(rxResponse.getData()[++i]);
rnr.setMicrowaveCycleCount(rxResponse.getData()[++i]);
rnr.setPirIntensity(rxResponse.getData()[++i]);
rnr.setLaserFeet(rxResponse.getData()[++i]);
rnr.setLaserInches(rxResponse.getData()[++i]);
rnr.setGateState(rxResponse.getData()[++i]);
final RxTxRemoteNodeReadingDTO sr = new RxTxRemoteNodeReadingDTO(rnr, status);
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_SUCCESS, command, sr,
RS.rbLabel(KEY.SERVICE_RX_READINGS, sr));
} else if (command == Command.SENSOR_GET_SETTINGS) {
// the number of response data and their order is important!!!
int i = 1;
final int[] sd = new int[RemoteNodeType.canRemoteCount()];
for (int j = 0; j<RemoteNodeType.canRemoteCount(); j++) {
sd[j] = rxResponse.getData()[++i];
}
// create a detached state remote node w/o modifying the existing local instance
final RemoteNode rnFromRemote = RemoteNodeType.newDefaultRemoteNode(rn.getHost());
final RxTxRemoteNodeDTO dto = new RxTxRemoteNodeDTO(rnFromRemote, status,
rxResponse.getRssi(), sd);
processData(rn, UGateEvent.Type.WIRELESS_DATA_RX_SUCCESS, command, dto,
RS.rbLabel(KEY.SERVICE_RX_SETTINGS, dto));
} else {