/* * Copyright (c) 2013, Will Szumski * Copyright (c) 2013, Doug Szumski * * This file is part of Cyclismo. * * Cyclismo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cyclismo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cyclismo. If not, see <http://www.gnu.org/licenses/>. */ import org.cowboycoders.ant.Channel; import org.cowboycoders.ant.NetworkKeys; import org.cowboycoders.ant.Node; import org.cowboycoders.ant.TransferException; import org.cowboycoders.ant.events.BroadcastListener; import org.cowboycoders.ant.events.MessageCondition; import org.cowboycoders.ant.events.MessageConditionFactory; import org.cowboycoders.ant.interfaces.AntTransceiver; import org.cowboycoders.ant.messages.ChannelType; import org.cowboycoders.ant.messages.MasterChannelType; import org.cowboycoders.ant.messages.SlaveChannelType; import org.cowboycoders.ant.messages.StandardMessage; import org.cowboycoders.ant.messages.commands.ChannelRequestMessage; import org.cowboycoders.ant.messages.commands.ChannelRequestMessage.Request; import org.cowboycoders.ant.messages.commands.ResetMessage; import org.cowboycoders.ant.messages.nonstandard.CombinedBurst; import org.cowboycoders.ant.messages.responses.ChannelIdResponse; import org.cowboycoders.ant.utils.ByteUtils; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.ConsoleHandler; import java.util.logging.Level; /** * Hack to test BurstMessage. Requires two ant sticks. * Needs to be converted to proper test. * * @author will */ public class BurstReceiveTest { private static AntTransceiver antchip = new AntTransceiver(0); @BeforeClass public static void beforeClass() { AntTransceiver.LOGGER.setLevel(Level.ALL); ConsoleHandler handler = new ConsoleHandler(); // PUBLISH this level handler.setLevel(Level.ALL); AntTransceiver.LOGGER.addHandler(handler); //Node.LOGGER.setLevel(Level.ALL); //Node.LOGGER.addHandler(handler); StandardMessage msg = new ResetMessage(); //StandardMessage msg = new BroadcastDataMessage(); //antchip.start(); //antchip.send(msg.encode()); //antchip.send(msg.encode()); //antchip.stop(); } @AfterClass public static void afterClass() { antchip.stop(); //antchip.stop(); } @Before public void before() throws InterruptedException { //Thread.sleep(1000); } /* * See ANT+ data sheet for explanation */ private static final int HRM_CHANNEL_PERIOD = 8070; /* * See ANT+ data sheet for explanation */ private static final int HRM_CHANNEL_FREQ = 57; /* * This should match the device you are connecting with. * Some devices are put into pairing mode (which sets this bit). * * Note: Many ANT+ sport devices do not set this bit (eg. HRM strap). * * See ANT+ docs. */ private static final boolean HRM_PAIRING_FLAG = false; /* * Should match device transmission id (0-255). Special rules * apply for shared channels. See ANT+ protocol. * * 0: wildcard, matches any value (slave only) */ private static final int HRM_TRANSMISSION_TYPE = 0; /* * device type for ANT+ heart rate monitor */ private static final int HRM_DEVICE_TYPE = 120; /* * You should make a note of the device id and use it in preference to the wild card * to pair to a specific device. * * 0: wild card, matches all device ids * any other number: match specific device id */ private static final int HRM_DEVICE_ID = 0; public static final Level LOG_LEVEL = Level.OFF; public static void setupLogging() { // set logging level AntTransceiver.LOGGER.setLevel(LOG_LEVEL); ConsoleHandler handler = new ConsoleHandler(); // PUBLISH this level handler.setLevel(LOG_LEVEL); AntTransceiver.LOGGER.addHandler(handler); } public static void printChannelConfig(Channel channel) { // build request ChannelRequestMessage msg = new ChannelRequestMessage(channel.getNumber(), Request.CHANNEL_ID); // response should be an instance of ChannelIdResponse MessageCondition condition = MessageConditionFactory.newInstanceOfCondition(ChannelIdResponse .class); try { // send request (blocks until reply received or timeout expired) ChannelIdResponse response = (ChannelIdResponse) channel.sendAndWaitForMessage( msg, condition, 5L, TimeUnit.SECONDS, null); System.out.println(); System.out.println("Device configuration: "); System.out.println("deviceID: " + response.getDeviceNumber()); System.out.println("deviceType: " + response.getDeviceType()); System.out.println("transmissionType: " + response.getTransmissionType()); System.out.println("pairing flag set: " + response.isPairingFlagSet()); System.out.println(); } catch (Exception e) { // not critical, so just print error e.printStackTrace(); } } BroadcastListener<CombinedBurst> burstListener = new BroadcastListener<CombinedBurst>() { @Override public void receiveMessage(CombinedBurst message) { for (int i : message.getUnsignedData()) { System.out.print(i + " "); } for (CombinedBurst.StatusFlag flag : message.getStatusFlags()) { System.out.println(flag); } } }; @Test public void test() throws InterruptedException { /* * Choose driver: AndroidAntTransceiver or AntTransceiver * * AntTransceiver(int deviceNumber) * deviceNumber : 0 ... number of usb sticks plugged in * 0: first usb ant-stick */ AntTransceiver antchip = new AntTransceiver(0); setupLogging(); // initialises node with chosen driver Node node = new Node(antchip); /* must be called before any configuration takes place */ node.start(); /* sends reset request : resets channels to default state */ node.reset(); Channel channel = node.getFreeChannel(); // Arbitrary name : useful for identifying channel channel.setName("C:HRM"); // choose slave or master type. Constructors exist to set two-way/one-way and // shared/non-shared variants. ChannelType channelType = new SlaveChannelType(); // use ant network key "N:ANT+" channel.assign(NetworkKeys.ANT_SPORT, channelType); /******* start device specific configuration ******/ channel.setId(HRM_DEVICE_ID, HRM_DEVICE_TYPE, HRM_TRANSMISSION_TYPE, HRM_PAIRING_FLAG); channel.setFrequency(HRM_CHANNEL_FREQ); channel.setPeriod(HRM_CHANNEL_PERIOD); /******* end device specific configuration ******/ // timeout before we give up looking for device channel.setSearchTimeout(Channel.SEARCH_TIMEOUT_NEVER); channel.registerBurstListener(burstListener); System.out.println("timeout: " + channel.getBurstTimeout()); // start listening channel.open(); fireBurst(); // Listen for 10 seconds Thread.sleep(20000); // stop listening channel.close(); // resets channel configuration channel.unassign(); //return the channel to the pool of available channels node.freeChannel(channel); // cleans up : gives up control of usb device etc. node.stop(); } public void fireBurst() { new Thread() { public void run() { Node node = new Node(new AntTransceiver(1)); // ANT+ key /* must be called before any configuration takes place */ node.start(); /* sends reset request : resets channels to default state */ node.reset(); Channel channel = node.getFreeChannel(); // Arbitrary name : useful for identifying channel channel.setName("C:HRM"); // choose slave or master type. Constructors exist to set two-way/one-way and // shared/non-shared variants. ChannelType channelType = new MasterChannelType(); // use ant network key "N:ANT+" channel.assign(NetworkKeys.ANT_SPORT, channelType); /******* start device specific configuration ******/ channel.setId(HRM_DEVICE_ID, HRM_DEVICE_TYPE, HRM_TRANSMISSION_TYPE, HRM_PAIRING_FLAG); channel.setFrequency(HRM_CHANNEL_FREQ); channel.setPeriod(HRM_CHANNEL_PERIOD); /******* end device specific configuration ******/ // timeout before we give up looking for device channel.setSearchTimeout(Channel.SEARCH_TIMEOUT_NEVER); channel.open(); try { Thread.sleep(4000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } int length = 248; byte[] test = new byte[length]; for (int i = 0; i < length; i++) { test[i] = (byte) i; } for (int i : ByteUtils.unsignedBytesToInts(ByteUtils.boxArray(test))) { System.out.print(i + " "); } try { channel.sendBurst(test, 10L, TimeUnit.SECONDS); System.out.println("transfer completed"); } catch (TransferException e) { System.out.println(e); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { Thread.sleep(10000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } channel.close(); channel.unassign(); node.freeChannel(channel); node.stop(); } }.start(); } }