diff --git a/apps/AntiTheft/Nodes/antitheft.h b/apps/AntiTheft/Nodes/antitheft.h index b1757a8a04..a90410a140 100644 --- a/apps/AntiTheft/Nodes/antitheft.h +++ b/apps/AntiTheft/Nodes/antitheft.h @@ -1,47 +1,48 @@ -// $Id: antitheft.h,v 1.3 2007-04-04 22:06:22 idgay Exp $ -/* - * Copyright (c) 2007 Intel Corporation - * All rights reserved. - * - * This file is distributed under the terms in the attached INTEL-LICENSE - * file. If you do not find these files, copies can be found by writing to - * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, - * 94704. Attention: Intel License Inquiry. - */ -/** - * - * @author David Gay - */ #ifndef ANTITHEFT_H #define ANTITHEFT_H enum { - ALERT_LEDS = 1, - ALERT_SOUND = 2, - ALERT_RADIO = 4, - ALERT_ROOT = 8, + ALERT_LEDS = 1 << 0, // Use bit shift for clarity + ALERT_SOUND = 1 << 1, + ALERT_RADIO = 1 << 2, + ALERT_ROOT = 1 << 3, - DETECT_DARK = 1, - DETECT_ACCEL = 2, - - AM_SETTINGS = 54, - AM_THEFT = 99, - AM_ALERT = 22, - DIS_SETTINGS = 42, - COL_ALERTS = 11, + DETECT_DARK = 1 << 0, // Use bit shift for clarity + DETECT_ACCEL = 1 << 1, DEFAULT_ALERT = ALERT_LEDS, DEFAULT_DETECT = DETECT_DARK, DEFAULT_CHECK_INTERVAL = 1000 }; +// Use enum for message types to avoid magic numbers +typedef enum { + AM_SETTINGS = 54, + AM_THEFT = 99, + AM_ALERT = 22, + DIS_SETTINGS = 42, + COL_ALERTS = 11 +} message_types_t; + +// Struct to hold anti-theft system settings typedef nx_struct settings { - nx_uint8_t alert, detect; - nx_uint16_t checkInterval; + nx_uint8_t alert; // Bitmask for alert types (e.g., ALERT_LEDS | ALERT_SOUND) + nx_uint8_t detect; // Bitmask for detection types (e.g., DETECT_DARK | DETECT_ACCEL) + nx_uint16_t checkInterval; // Time interval for checking } settings_t; +// Struct for alert messages typedef nx_struct alert { - nx_uint16_t stolenId; + nx_uint16_t stolenId; // ID of the stolen item } alert_t; +// Utility macros for setting and checking bitmask flags +#define SET_ALERT_TYPE(settings, type) ((settings).alert |= (type)) +#define CLEAR_ALERT_TYPE(settings, type) ((settings).alert &= ~(type)) +#define IS_ALERT_TYPE_SET(settings, type) ((settings).alert & (type)) + +#define SET_DETECT_TYPE(settings, type) ((settings).detect |= (type)) +#define CLEAR_DETECT_TYPE(settings, type) ((settings).detect &= ~(type)) +#define IS_DETECT_TYPE_SET(settings, type) ((settings).detect & (type)) + #endif diff --git a/apps/AntiTheft/java/AntiTheftGui.java b/apps/AntiTheft/java/AntiTheftGui.java index 4d3e5163ae..e8ee301ce2 100644 --- a/apps/AntiTheft/java/AntiTheftGui.java +++ b/apps/AntiTheft/java/AntiTheftGui.java @@ -49,188 +49,187 @@ * @author David Gay */ -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import net.tinyos.message.*; -import net.tinyos.packet.*; -import net.tinyos.util.*; - -public class AntiTheftGui implements MessageListener, Messenger { - MoteIF mote; // For talking to the antitheft root node - - /* Various swing components we need to use after initialisation */ - JFrame frame; // The whole frame - JTextArea mssgArea; // The message area - JTextField fieldInterval; // The requested check interval - - /* The checkboxes for the requested settings */ - JCheckBox detDarkCb, detAccelCb, repLedCb, repSirenCb, repServerCb, - repNeighboursCb; - - public AntiTheftGui() { - try { - guiInit(); - /* Setup communication with the mote and request a messageReceived - callback when an AlertMsg is received */ - mote = new MoteIF(this); - mote.registerListener(new AlertMsg(), this); - } - catch(Exception e) { - e.printStackTrace(); - System.exit(2); - } - } - - /* Build up the GUI using Swing magic. Nothing very exciting here - the - BagPanel class makes the code a bit cleaner/easier to read. */ - private void guiInit() throws Exception { - JPanel mainPanel = new JPanel(new BorderLayout()); - mainPanel.setMinimumSize(new Dimension(500, 250)); - mainPanel.setPreferredSize(new Dimension(500, 300)); - - /* The message area */ - JScrollPane mssgPanel = new JScrollPane(); - mssgPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); - mssgPanel.setAutoscrolls(true); - mssgArea = new JTextArea(); - mssgArea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 20)); - mainPanel.add(mssgPanel, BorderLayout.CENTER); - mssgPanel.getViewport().add(mssgArea, null); - - /* The button area */ - BagPanel buttonPanel = new BagPanel(); - GridBagConstraints c = buttonPanel.c; - - c.fill = GridBagConstraints.HORIZONTAL; - c.gridwidth = GridBagConstraints.REMAINDER; - - buttonPanel.makeLabel("Detection", JLabel.CENTER); - c.gridwidth = GridBagConstraints.RELATIVE; - detDarkCb = buttonPanel.makeCheckBox("Dark", true); - c.gridwidth = GridBagConstraints.REMAINDER; - detAccelCb = buttonPanel.makeCheckBox("Movement", false); - buttonPanel.makeSeparator(SwingConstants.HORIZONTAL); - - - buttonPanel.makeLabel("Theft Reports", JLabel.CENTER); - c.gridwidth = GridBagConstraints.RELATIVE; - repLedCb = buttonPanel.makeCheckBox("LED", true); - c.gridwidth = GridBagConstraints.REMAINDER; - repSirenCb = buttonPanel.makeCheckBox("Siren", false); - c.gridwidth = GridBagConstraints.RELATIVE; - repServerCb = buttonPanel.makeCheckBox("Server", false); - c.gridwidth = GridBagConstraints.REMAINDER; - repNeighboursCb = buttonPanel.makeCheckBox("Neighbours", false); - buttonPanel.makeSeparator(SwingConstants.HORIZONTAL); - - buttonPanel.makeLabel("Interval", JLabel.CENTER); - fieldInterval = buttonPanel.makeTextField(10, null); - fieldInterval.setText(Integer.toString(Constants.DEFAULT_CHECK_INTERVAL)); - - ActionListener settingsAction = new ActionListener() { - public void actionPerformed(ActionEvent e) { - updateSettings(); - } - }; - buttonPanel.makeButton("Update", settingsAction); - - mainPanel.add(buttonPanel, BorderLayout.EAST); - - /* The frame part */ - frame = new JFrame("AntiTheft"); - frame.setSize(mainPanel.getPreferredSize()); - frame.getContentPane().add(mainPanel); - frame.setVisible(true); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { System.exit(0); } - }); - } - - /* Add a message to the message area, auto-scroll to end */ - public synchronized void message(String s) { - mssgArea.append(s + "\n"); - mssgArea.setCaretPosition(mssgArea.getDocument().getLength()); - } - - /* Popup an error message */ - void error(String msg) { - JOptionPane.showMessageDialog(frame, msg, "Error", - JOptionPane.ERROR_MESSAGE); - } - - /* User pressed the "Update" button. Read the GUI fields and - send a SettingsMsg with the requested values. When the - requested settings are bad, we silently update them to sane - values. */ - public void updateSettings() { - SettingsMsg smsg = new SettingsMsg(); - short alert = 0; - short detect = 0; - int checkInterval = Constants.DEFAULT_CHECK_INTERVAL; - - /* Extract current interval value, fixing bad values */ - String intervalS = fieldInterval.getText().trim(); - try { - int newInterval = Integer.parseInt(intervalS); - if (newInterval < 10) throw new NumberFormatException(); - checkInterval = newInterval; - } - catch (NumberFormatException e) { - /* Reset field when value is bad */ - fieldInterval.setText("" + checkInterval); - } - - /* Extract alert settings */ - if (repLedCb.isSelected()) - alert |= Constants.ALERT_LEDS; - if (repSirenCb.isSelected()) - alert |= Constants.ALERT_SOUND; - if (repNeighboursCb.isSelected()) - alert |= Constants.ALERT_RADIO; - if (repServerCb.isSelected()) - alert |= Constants.ALERT_ROOT; - if (alert == 0) { - /* If nothing select, force-select LEDs */ - alert = Constants.ALERT_LEDS; - repLedCb.setSelected(true); - } - - /* Extract detection settings */ - if (detDarkCb.isSelected()) - detect |= Constants.DETECT_DARK; - if (detAccelCb.isSelected()) - detect |= Constants.DETECT_ACCEL; - if (detect == 0) { - /* If no detection selected, force-select dark */ - detect = Constants.DETECT_DARK; - detDarkCb.setSelected(true); - } - - /* Build and send settings message */ - smsg.set_alert(alert); - smsg.set_detect(detect); - smsg.set_checkInterval(checkInterval); - try { - mote.send(MoteIF.TOS_BCAST_ADDR, smsg); - } - catch (IOException e) { - error("Cannot send message to mote"); - } - } - - /* Message received from mote network. Update message area if it's - a theft message. */ - public void messageReceived(int dest_addr, Message msg) { - if (msg instanceof AlertMsg) { - AlertMsg alertMsg = (AlertMsg)msg; - message("Theft of " + alertMsg.get_stolenId()); - } - } - - /* Just start the app... */ - public static void main(String[] args) { - AntiTheftGui me = new AntiTheftGui(); - } -} + import javax.swing.*; + import java.awt.*; + import java.awt.event.*; + import java.io.*; + import net.tinyos.message.*; + import net.tinyos.packet.*; + import net.tinyos.util.*; + + public class AntiTheftGui implements MessageListener, Messenger { + MoteIF mote; // For talking to the antitheft root node + + /* Various swing components we need to use after initialization */ + JFrame frame; // The whole frame + JTextArea mssgArea; // The message area + JTextField fieldInterval; // The requested check interval + + /* The checkboxes for the requested settings */ + JCheckBox detDarkCb, detAccelCb, repLedCb, repSirenCb, repServerCb, + repNeighboursCb; + + public AntiTheftGui() { + try { + guiInit(); + /* Setup communication with the mote and request a messageReceived + callback when an AlertMsg is received */ + mote = new MoteIF(this); + mote.registerListener(new AlertMsg(), this); + } catch (Exception e) { + e.printStackTrace(); + System.exit(2); + } + } + + /* Build up the GUI using Swing magic. */ + private void guiInit() throws Exception { + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.setMinimumSize(new Dimension(500, 250)); + mainPanel.setPreferredSize(new Dimension(500, 300)); + + /* The message area */ + JScrollPane mssgPanel = new JScrollPane(); + mssgPanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + mssgPanel.setAutoscrolls(true); + mssgArea = new JTextArea(); + mssgArea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 20)); + mainPanel.add(mssgPanel, BorderLayout.CENTER); + mssgPanel.getViewport().add(mssgArea, null); + + /* The button area */ + BagPanel buttonPanel = new BagPanel(); + GridBagConstraints c = buttonPanel.c; + + c.fill = GridBagConstraints.HORIZONTAL; + c.gridwidth = GridBagConstraints.REMAINDER; + + buttonPanel.makeLabel("Detection", JLabel.CENTER); + c.gridwidth = GridBagConstraints.RELATIVE; + detDarkCb = buttonPanel.makeCheckBox("Dark", true); + c.gridwidth = GridBagConstraints.REMAINDER; + detAccelCb = buttonPanel.makeCheckBox("Movement", false); + buttonPanel.makeSeparator(SwingConstants.HORIZONTAL); + + buttonPanel.makeLabel("Theft Reports", JLabel.CENTER); + c.gridwidth = GridBagConstraints.RELATIVE; + repLedCb = buttonPanel.makeCheckBox("LED", true); + c.gridwidth = GridBagConstraints.REMAINDER; + repSirenCb = buttonPanel.makeCheckBox("Siren", false); + c.gridwidth = GridBagConstraints.RELATIVE; + repServerCb = buttonPanel.makeCheckBox("Server", false); + c.gridwidth = GridBagConstraints.REMAINDER; + repNeighboursCb = buttonPanel.makeCheckBox("Neighbours", false); + buttonPanel.makeSeparator(SwingConstants.HORIZONTAL); + + buttonPanel.makeLabel("Interval", JLabel.CENTER); + fieldInterval = buttonPanel.makeTextField(10, null); + fieldInterval.setText(Integer.toString(Constants.DEFAULT_CHECK_INTERVAL)); + + ActionListener settingsAction = new ActionListener() { + public void actionPerformed(ActionEvent e) { + updateSettings(); + } + }; + buttonPanel.makeButton("Update", settingsAction); + + mainPanel.add(buttonPanel, BorderLayout.EAST); + + /* The frame part */ + frame = new JFrame("AntiTheft"); + frame.setSize(mainPanel.getPreferredSize()); + frame.getContentPane().add(mainPanel); + frame.setVisible(true); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + } + + /* Add a message to the message area, auto-scroll to end */ + public synchronized void message(String s) { + SwingUtilities.invokeLater(() -> { + mssgArea.append(s + "\n"); + mssgArea.setCaretPosition(mssgArea.getDocument().getLength()); + }); + } + + /* Popup an error message */ + void error(String msg) { + JOptionPane.showMessageDialog(frame, msg, "Error", + JOptionPane.ERROR_MESSAGE); + } + + /* User pressed the "Update" button. Read the GUI fields and + send a SettingsMsg with the requested values. */ + public void updateSettings() { + SettingsMsg smsg = new SettingsMsg(); + short alert = 0; + short detect = 0; + int checkInterval = Constants.DEFAULT_CHECK_INTERVAL; + + /* Extract current interval value, fixing bad values */ + String intervalS = fieldInterval.getText().trim(); + try { + int newInterval = Integer.parseInt(intervalS); + if (newInterval < Constants.MIN_CHECK_INTERVAL) throw new NumberFormatException(); + checkInterval = newInterval; + } catch (NumberFormatException e) { + /* Reset field when value is bad */ + fieldInterval.setText("" + checkInterval); + } + + /* Extract alert settings */ + if (repLedCb.isSelected()) + alert |= Constants.ALERT_LEDS; + if (repSirenCb.isSelected()) + alert |= Constants.ALERT_SOUND; + if (repNeighboursCb.isSelected()) + alert |= Constants.ALERT_RADIO; + if (repServerCb.isSelected()) + alert |= Constants.ALERT_ROOT; + if (alert == 0) { + /* If nothing selected, force-select LEDs */ + alert = Constants.ALERT_LEDS; + repLedCb.setSelected(true); + } + + /* Extract detection settings */ + if (detDarkCb.isSelected()) + detect |= Constants.DETECT_DARK; + if (detAccelCb.isSelected()) + detect |= Constants.DETECT_ACCEL; + if (detect == 0) { + /* If no detection selected, force-select dark */ + detect = Constants.DETECT_DARK; + detDarkCb.setSelected(true); + } + + /* Build and send settings message */ + smsg.set_alert(alert); + smsg.set_detect(detect); + smsg.set_checkInterval(checkInterval); + try { + mote.send(MoteIF.TOS_BCAST_ADDR, smsg); + message("Settings updated successfully."); + } catch (IOException e) { + error("Cannot send message to mote"); + } + } + + /* Message received from mote network. Update message area if it's + a theft message. */ + public void messageReceived(int dest_addr, Message msg) { + if (msg instanceof AlertMsg) { + AlertMsg alertMsg = (AlertMsg) msg; + message("Theft of " + alertMsg.get_stolenId()); + } + } + + /* Just start the app... */ + public static void main(String[] args) { + SwingUtilities.invokeLater(AntiTheftGui::new); + } + } + diff --git a/apps/AntiTheft/java/BagPanel.java b/apps/AntiTheft/java/BagPanel.java index 9e9bf0b39f..f995765292 100644 --- a/apps/AntiTheft/java/BagPanel.java +++ b/apps/AntiTheft/java/BagPanel.java @@ -1,16 +1,3 @@ -// $Id: BagPanel.java,v 1.2 2007-04-04 22:29:29 idgay Exp $ - -/* tab:4 - * Copyright (c) 2007 Intel Corporation - * All rights reserved. - * - * This file is distributed under the terms in the attached INTEL-LICENSE - * file. If you do not find these files, copies can be found by writing to - * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, - * 94704. Attention: Intel License Inquiry. - */ - - import javax.swing.*; import java.awt.*; import java.awt.event.*; @@ -29,60 +16,66 @@ public class BagPanel extends JPanel { GridBagLayout bag; GridBagConstraints c; - /* Create a panel with a bag layout. Create some constraints are + /* Create a panel with a bag layout. Create some constraints that users can modify prior to creating widgets - the current constraints will be applied to all widgets created with makeXXX */ public BagPanel() { - bag = new GridBagLayout(); - setLayout(bag); - c = new GridBagConstraints(); + bag = new GridBagLayout(); + setLayout(bag); + c = new GridBagConstraints(); + // Default constraints settings (can be modified as needed) + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(5, 5, 5, 5); // Padding around components } /* The makeXXX methods create XXX widgets, apply the current constraints to them, and add them to this panel. The widget is returned in case - the creator needs to hang on to it. */ + the creator needs to keep a reference. */ public JButton makeButton(String label, ActionListener action) { - JButton button = new JButton(); - button.setText(label); + JButton button = new JButton(label); button.setFont(boldFont); - button.addActionListener(action); - bag.setConstraints(button, c); - add(button); - return button; + button.addActionListener(action); + GridBagConstraints tempC = (GridBagConstraints) c.clone(); // Clone the constraints + bag.setConstraints(button, tempC); + add(button); + return button; } public JCheckBox makeCheckBox(String label, boolean selected) { - JCheckBox box = new JCheckBox(label, selected); - box.setFont(normalFont); - bag.setConstraints(box, c); - add(box); - return box; + JCheckBox box = new JCheckBox(label, selected); + box.setFont(normalFont); + GridBagConstraints tempC = (GridBagConstraints) c.clone(); // Clone the constraints + bag.setConstraints(box, tempC); + add(box); + return box; } public JLabel makeLabel(String txt, int alignment) { - JLabel label = new JLabel(txt, alignment); - label.setFont(boldFont); - bag.setConstraints(label, c); - add(label); - return label; + JLabel label = new JLabel(txt, alignment); + label.setFont(boldFont); + GridBagConstraints tempC = (GridBagConstraints) c.clone(); // Clone the constraints + bag.setConstraints(label, tempC); + add(label); + return label; } public JTextField makeTextField(int columns, ActionListener action) { - JTextField tf = new JTextField(columns); - tf.setFont(normalFont); - tf.setMaximumSize(tf.getPreferredSize()); - tf.addActionListener(action); - bag.setConstraints(tf, c); - add(tf); - return tf; + JTextField tf = new JTextField(columns); + tf.setFont(normalFont); + tf.setMaximumSize(tf.getPreferredSize()); + tf.addActionListener(action); + GridBagConstraints tempC = (GridBagConstraints) c.clone(); // Clone the constraints + bag.setConstraints(tf, tempC); + add(tf); + return tf; } public JSeparator makeSeparator(int axis) { - JSeparator sep = new JSeparator(axis); - bag.setConstraints(sep, c); - add(sep); - return sep; + JSeparator sep = new JSeparator(axis); + GridBagConstraints tempC = (GridBagConstraints) c.clone(); // Clone the constraints + bag.setConstraints(sep, tempC); + add(sep); + return sep; } - }