1f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum/* 2f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * Copyright 2017, The Android Open Source Project 3f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * 4f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * Licensed under the Apache License, Version 2.0 (the "License"); 5f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * you may not use this file except in compliance with the License. 6f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * You may obtain a copy of the License at 7f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * 8f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * http://www.apache.org/licenses/LICENSE-2.0 9f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * 10f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * Unless required by applicable law or agreed to in writing, software 11f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * distributed under the License is distributed on an "AS IS" BASIS, 12f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * See the License for the specific language governing permissions and 14f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * limitations under the License. 15f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum */ 16f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 17f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumpackage com.android.commands.lowpan; 18f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 1967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaumimport android.net.LinkAddress; 20f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.ILowpanInterface; 21f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanBeaconInfo; 22f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanCredential; 23f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanEnergyScanResult; 24f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanException; 25f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanIdentity; 26f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanInterface; 27f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanManager; 28f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanProvision; 29f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.net.lowpan.LowpanScanner; 30f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.os.RemoteException; 31f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.os.ServiceSpecificException; 32f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport android.util.AndroidRuntimeException; 33f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport com.android.internal.os.BaseCommand; 34f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport com.android.internal.util.HexDump; 35f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport java.io.PrintStream; 36f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport java.util.HashMap; 37f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport java.util.Map; 38f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport java.util.concurrent.Semaphore; 39f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumimport java.util.concurrent.TimeUnit; 40f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 41f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaumpublic class LowpanCtl extends BaseCommand { 42f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private LowpanManager mLowpanManager; 43f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private LowpanInterface mLowpanInterface; 44f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private ILowpanInterface mILowpanInterface; 45f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private String mLowpanInterfaceName; 46f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 47f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum /** 48f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * Command-line entry point. 49f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * 50f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum * @param args The command-line arguments 51f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum */ 52f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public static void main(String[] args) { 53f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum new LowpanCtl().run(args); 54f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 55f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 56f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 57f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onShowUsage(PrintStream out) { 58f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum out.println( 59f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum "usage: lowpanctl [options] [subcommand] [subcommand-options]\n" 6041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "options:\n" 6141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -I / --interface <iface-name> ..... Interface Name\n" 6241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "subcommands:\n" 63f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl status\n" 64f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl form\n" 65f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl join\n" 6641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " lowpanctl attach\n" 67f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl leave\n" 6841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " lowpanctl enable\n" 6941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " lowpanctl disable\n" 7041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " lowpanctl show-credential\n" 71f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl scan\n" 72f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl reset\n" 73f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + " lowpanctl list\n" 7441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "\n" 7541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "usage: lowpanctl [options] join/form/attach [network-name]\n" 7641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "subcommand-options:\n" 7741641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " --name <network-name> ............. Network Name\n" 7841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -p / --panid <panid> .............. PANID\n" 7941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -c / --channel <channel> .......... Channel Index\n" 8041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -x / --xpanid <xpanid> ............ XPANID\n" 8141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -k / --master-key <master-key> .... Master Key\n" 8241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " --master-key-index <key-index> .... Key Index\n" 8341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "\n" 8441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "usage: lowpanctl [options] show-credential\n" 8541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + "subcommand-options:\n" 8641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum + " -r / --raw ........................ Print only key contents\n" 87f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum + "\n"); 88f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 89f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 90f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private class CommandErrorException extends AndroidRuntimeException { 91f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public CommandErrorException(String desc) { 92f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum super(desc); 93f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 94f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 95f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 9667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum private class ArgumentErrorException extends IllegalArgumentException { 9767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum public ArgumentErrorException(String desc) { 9867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum super(desc); 9967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 10067a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 10167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 102f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void throwCommandError(String desc) { 103f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum throw new CommandErrorException(desc); 104f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 105f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 10667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum private void throwArgumentError(String desc) { 10767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throw new ArgumentErrorException(desc); 10867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 10967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 11067a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum private LowpanManager getLowpanManager() { 11167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum if (mLowpanManager == null) { 11267a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum mLowpanManager = LowpanManager.getManager(); 11367a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 11467a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum if (mLowpanManager == null) { 11567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum System.err.println(NO_SYSTEM_ERROR_CODE); 11667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwCommandError("Can't connect to LoWPAN service; is the service running?"); 11767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 11867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 11967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum return mLowpanManager; 12067a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } 12167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 122f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private LowpanInterface getLowpanInterface() { 123f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (mLowpanInterface == null) { 124f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (mLowpanInterfaceName == null) { 12567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum String interfaceArray[] = getLowpanManager().getInterfaceList(); 126f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (interfaceArray.length != 0) { 127f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum mLowpanInterfaceName = interfaceArray[0]; 128f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 129f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum throwCommandError("No LoWPAN interfaces are present"); 130f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 131f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 13267a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum mLowpanInterface = getLowpanManager().getInterface(mLowpanInterfaceName); 133f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 134f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (mLowpanInterface == null) { 135f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum throwCommandError("Unknown LoWPAN interface \"" + mLowpanInterfaceName + "\""); 136f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 137f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 138f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum return mLowpanInterface; 139f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 140f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 141f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private ILowpanInterface getILowpanInterface() { 142f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (mILowpanInterface == null) { 143f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum mILowpanInterface = getLowpanInterface().getService(); 144f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 145f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum return mILowpanInterface; 146f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 147f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 148f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 149f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onRun() throws Exception { 150f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum try { 151f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum String op; 152f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum while ((op = nextArgRequired()) != null) { 153f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (op.equals("-I") || op.equals("--interface")) { 154f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum mLowpanInterfaceName = nextArgRequired(); 15567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } else if (op.equals("-h") || op.equals("--help") || op.equals("help")) { 15667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum onShowUsage(System.out); 15767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum break; 158f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.startsWith("-")) { 15967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + op + "\""); 160f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("status") || op.equals("stat")) { 161f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runStatus(); 162f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 163f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("scan") || op.equals("netscan") || op.equals("ns")) { 164f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runNetScan(); 165f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 16641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else if (op.equals("attach")) { 167f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runAttach(); 168f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 16941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else if (op.equals("enable")) { 17041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum runEnable(); 17141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum break; 17241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else if (op.equals("disable")) { 17341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum runDisable(); 17441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum break; 17541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else if (op.equals("show-credential")) { 17641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum runShowCredential(); 177f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 178f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("join")) { 179f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runJoin(); 180f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 181f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("form")) { 182f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runForm(); 183f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 184f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("leave")) { 185f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runLeave(); 186f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 187f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("energyscan") || op.equals("energy") || op.equals("es")) { 188f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runEnergyScan(); 189f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 190f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("list") || op.equals("ls")) { 191f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runListInterfaces(); 192f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 193f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (op.equals("reset")) { 194f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum runReset(); 195f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 196f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 19767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + op + "\""); 198f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum break; 199f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 200f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 201f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } catch (ServiceSpecificException x) { 202f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println( 203f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum "ServiceSpecificException: " + x.errorCode + ": " + x.getLocalizedMessage()); 20467a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throw x; 20567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 20667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } catch (ArgumentErrorException x) { 20767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // Rethrow so we get syntax help. 20867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throw x; 20967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 21067a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum } catch (IllegalArgumentException x) { 21167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // This was an argument exception that wasn't an 21267a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // argument error. We dump our stack trace immediately 21367a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // because this might not be from a command line argument. 21467a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum x.printStackTrace(System.err); 21567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum System.exit(1); 21667a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum 217f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } catch (CommandErrorException x) { 21867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // Command errors are normal errors that just 21967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum // get printed out without any fanfare. 220f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println("error: " + x.getLocalizedMessage()); 22167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum System.exit(1); 222f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 223f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 224f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 225f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runReset() throws LowpanException { 226f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum getLowpanInterface().reset(); 227f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 228f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 22941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum private void runEnable() throws LowpanException { 23041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum getLowpanInterface().setEnabled(true); 23141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } 23241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 23341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum private void runDisable() throws LowpanException { 23441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum getLowpanInterface().setEnabled(false); 23541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } 23641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 237f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private LowpanProvision getProvisionFromArgs(boolean credentialRequired) { 238f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanProvision.Builder builder = new LowpanProvision.Builder(); 239f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum Map<String, Object> properties = new HashMap(); 240f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanIdentity.Builder identityBuilder = new LowpanIdentity.Builder(); 241f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanCredential credential = null; 242f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum String arg; 243f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum byte[] masterKey = null; 244f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum int masterKeyIndex = 0; 245f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum boolean hasName = false; 246f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 247f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum while ((arg = nextArg()) != null) { 248f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (arg.equals("--name")) { 249f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum identityBuilder.setName(nextArgRequired()); 250f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum hasName = true; 251f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.equals("-p") || arg.equals("--panid")) { 252f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum identityBuilder.setPanid(Integer.decode(nextArgRequired())); 253f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.equals("-c") || arg.equals("--channel")) { 254f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum identityBuilder.setChannel(Integer.decode(nextArgRequired())); 255f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.equals("-x") || arg.equals("--xpanid")) { 256f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum identityBuilder.setXpanid(HexDump.hexStringToByteArray(nextArgRequired())); 257f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.equals("-k") || arg.equals("--master-key")) { 258f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum masterKey = HexDump.hexStringToByteArray(nextArgRequired()); 259f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.equals("--master-key-index")) { 260f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum masterKeyIndex = Integer.decode(nextArgRequired()); 261f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (arg.startsWith("-") || hasName) { 26267a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + arg + "\""); 263f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 264f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum // This is the network name 265f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum identityBuilder.setName(arg); 266f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum hasName = true; 267f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 268f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 269f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 270f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (credential == null && masterKey != null) { 271f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (masterKeyIndex == 0) { 272f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum credential = LowpanCredential.createMasterKey(masterKey); 273f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 274f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum credential = LowpanCredential.createMasterKey(masterKey, masterKeyIndex); 275f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 276f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 277f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 278f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (credential != null) { 279f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum builder.setLowpanCredential(credential); 280f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else if (credentialRequired) { 28167a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("No credential (like a master key) was specified!"); 282f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 283f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 284f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum return builder.setLowpanIdentity(identityBuilder.build()).build(); 285f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 286f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 287f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runAttach() throws LowpanException { 288f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanProvision provision = getProvisionFromArgs(true); 289f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 290f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println( 291f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum "Attaching to " + provision.getLowpanIdentity() + " with provided credential"); 292f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 293f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum getLowpanInterface().attach(provision); 294f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 295f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println("Attached."); 296f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 297f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 298f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runLeave() throws LowpanException { 299f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum getLowpanInterface().leave(); 300f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 301f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 302f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runJoin() throws LowpanException { 303f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanProvision provision = getProvisionFromArgs(true); 304f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 305f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println( 306f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum "Joining " + provision.getLowpanIdentity() + " with provided credential"); 307f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 308f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum getLowpanInterface().join(provision); 309f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 310f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println("Joined."); 311f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 312f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 313f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runForm() throws LowpanException { 314f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanProvision provision = getProvisionFromArgs(false); 315f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 316f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (provision.getLowpanCredential() != null) { 317f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println( 31867a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum "Forming " + provision.getLowpanIdentity() + " with provided credential"); 319f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 32041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum System.out.println("Forming " + provision.getLowpanIdentity()); 321f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 322f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 323f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum getLowpanInterface().form(provision); 324f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 325f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println("Formed."); 326f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 327f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 32841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum private void runStatus() throws LowpanException, RemoteException { 32941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum LowpanInterface iface = getLowpanInterface(); 33041641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum StringBuffer sb = new StringBuffer(); 33141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 33241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum sb.append(iface.getName()) 33341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum .append("\t") 334ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum .append(iface.getState()); 33541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 336ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (!iface.isEnabled()) { 337ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append(" DISABLED"); 338f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 339ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } else if (iface.getState() != LowpanInterface.STATE_FAULT) { 340ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append(" (" + iface.getRole() + ")"); 341f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 342ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (iface.isUp()) { 343ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append(" UP"); 344ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 345ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum 346ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (iface.isConnected()) { 347ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append(" CONNECTED"); 348ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 34941641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 350ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (iface.isCommissioned()) { 351ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append(" COMMISSIONED"); 35241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 353ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum LowpanIdentity identity = getLowpanInterface().getLowpanIdentity(); 354ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum 355ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (identity != null) { 356ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append("\n\t").append(identity); 357ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 358ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 359ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum 360ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum if (iface.isUp()) { 361ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum for (LinkAddress addr : iface.getLinkAddresses()) { 362ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum sb.append("\n\t").append(addr); 363ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 364ece938e2a9aff18b430634dea15240f410001b53Robert Quattlebaum } 36541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } 36641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 36741641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum sb.append("\n"); 36841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum System.out.println(sb.toString()); 369f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 370f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 37141641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum private void runShowCredential() throws LowpanException, RemoteException { 37241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum LowpanInterface iface = getLowpanInterface(); 37341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum boolean raw = false; 37441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum String arg; 37541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum while ((arg = nextArg()) != null) { 37641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum if (arg.equals("--raw") || arg.equals("-r")) { 37741641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum raw = true; 37841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else { 37967a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + arg + "\""); 380f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 381f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 38241641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum 38341641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum LowpanCredential credential = iface.getLowpanCredential(); 38441641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum if (raw) { 38541641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum System.out.println(HexDump.toHexString(credential.getMasterKey())); 38641641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } else { 38767a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum System.out.println(iface.getName() + "\t" + credential.toSensitiveString()); 38841641f3e0d7ebccbb18ef1e03898688b50ae3e30Robert Quattlebaum } 389f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 390f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 391f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runListInterfaces() { 39267a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum for (String name : getLowpanManager().getInterfaceList()) { 393f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println(name); 394f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 395f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 396f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 397f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runNetScan() throws LowpanException, InterruptedException { 398f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanScanner scanner = getLowpanInterface().createScanner(); 399f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum String arg; 400f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 401f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum while ((arg = nextArg()) != null) { 402f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (arg.equals("-c") || arg.equals("--channel")) { 403f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.addChannel(Integer.decode(nextArgRequired())); 404f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 40567a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + arg + "\""); 406f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 407f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 408f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 409f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum Semaphore semaphore = new Semaphore(1); 410f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 411f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.setCallback( 412f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum new LowpanScanner.Callback() { 413f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 414f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onNetScanBeacon(LowpanBeaconInfo beacon) { 415f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println(beacon.toString()); 416f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 417f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 418f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 419f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onScanFinished() { 420f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.release(); 421f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 422f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum }); 423f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 424f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.acquire(); 425f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.startNetScan(); 426f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 427f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum // Wait for our scan to complete. 428f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (semaphore.tryAcquire(1, 60L, TimeUnit.SECONDS)) { 429f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.release(); 430f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 431f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum throwCommandError("Timeout while waiting for scan to complete."); 432f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 433f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 434f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 435f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum private void runEnergyScan() throws LowpanException, InterruptedException { 436f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum LowpanScanner scanner = getLowpanInterface().createScanner(); 437f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum String arg; 438f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 439f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum while ((arg = nextArg()) != null) { 440f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (arg.equals("-c") || arg.equals("--channel")) { 441f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.addChannel(Integer.decode(nextArgRequired())); 442f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 44367a620c6f11669ba8509eccec6ebff301f1fc985Robert Quattlebaum throwArgumentError("Unrecognized argument \"" + arg + "\""); 444f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 445f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 446f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 447f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum Semaphore semaphore = new Semaphore(1); 448f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 449f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.setCallback( 450f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum new LowpanScanner.Callback() { 451f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 452f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onEnergyScanResult(LowpanEnergyScanResult result) { 453f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum System.out.println(result.toString()); 454f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 455f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 456f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum @Override 457f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum public void onScanFinished() { 458f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.release(); 459f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 460f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum }); 461f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 462f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.acquire(); 463f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum scanner.startEnergyScan(); 464f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum 465f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum // Wait for our scan to complete. 466f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum if (semaphore.tryAcquire(1, 60L, TimeUnit.SECONDS)) { 467f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum semaphore.release(); 468f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } else { 469f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum throwCommandError("Timeout while waiting for scan to complete."); 470f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 471f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum } 472f15236e9c6adc5f69be5152bc61fe19bc975c222Robert Quattlebaum} 473