Initial code check in continued

This commit is contained in:
dennis.sheirer
2014-04-26 19:48:24 +00:00
parent 960a6f9952
commit 3dfedcf8d1
474 changed files with 76613 additions and 0 deletions

126
src/alias/Alias.java Normal file
View File

@@ -0,0 +1,126 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.Color;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
import audio.AudioType;
public class Alias
{
private String mName;
private int mColor;
private String mIconName;
private ArrayList<AliasID> mAliasIDs = new ArrayList<AliasID>();
public Alias()
{
}
public String toString()
{
return "Alias: " + mName;
}
@XmlAttribute
public String getName()
{
return mName;
}
public void setName( String name )
{
mName = name;
}
@XmlAttribute
public int getColor()
{
return mColor;
}
public void setColor( int color )
{
mColor = color;
}
public Color getMapColor()
{
return new Color( mColor );
}
@XmlAttribute
public String getIconName()
{
return mIconName;
}
public void setIconName( String iconName )
{
mIconName = iconName;
}
public ArrayList<AliasID> getId()
{
return mAliasIDs;
}
public void setId( ArrayList<AliasID> id )
{
mAliasIDs = id;
}
public void addAliasID( AliasID id )
{
mAliasIDs.add( id );
}
public void removeAliasID( AliasID id )
{
mAliasIDs.remove( id );
}
public boolean hasAudioType()
{
for( AliasID id: mAliasIDs )
{
if( id.hasAudioType() )
{
return true;
}
}
return false;
}
public AudioType getAudioType()
{
for( AliasID id: mAliasIDs )
{
if( id.hasAudioType() )
{
return id.getAudioType();
}
}
return AudioType.NORMAL;
}
}

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlSeeAlso( { AliasList.class} )
@XmlRootElement( name = "alias_directory" )
public class AliasDirectory
{
private ArrayList<AliasList> mAliasList = new ArrayList<AliasList>();
public AliasDirectory()
{
}
public void refresh()
{
for( AliasList list: mAliasList )
{
list.update();
}
}
@XmlElement( name = "alias_list" )
public ArrayList<AliasList> getAliasList()
{
return mAliasList;
}
public void setAliasList( ArrayList<AliasList> lists )
{
mAliasList = lists;
}
public void addAliasList( AliasList list )
{
mAliasList.add( list );
}
public void removeAliasList( AliasList list )
{
mAliasList.remove( list );
}
/**
* Gets the named alias list, or returns an empty alias list
*/
public AliasList getAliasList( String name )
{
AliasList retVal = new AliasList();
for( AliasList list: mAliasList )
{
if( list.getName().equalsIgnoreCase( name ) )
{
return list;
}
}
return retVal;
}
}

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import controller.ConfigurableNode;
public class AliasDirectoryNode extends ConfigurableNode
{
private static final long serialVersionUID = 1L;
public AliasDirectoryNode( AliasDirectory directory )
{
super( directory );
}
public AliasDirectory getAliasDirectory()
{
return (AliasDirectory)getUserObject();
}
public void init()
{
for( AliasList list: getAliasDirectory().getAliasList() )
{
AliasListNode node = new AliasListNode( list );
getModel().addNode( node, AliasDirectoryNode.this, getChildCount() );
node.init();
}
sort();
}
public String toString()
{
return "Alias Lists [" + this.getChildCount() + "]";
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addItem = new JMenuItem( "Add Alias List" );
addItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
AliasList list = new AliasList();
getAliasDirectory().addAliasList( list );
AliasListNode node = new AliasListNode( list );
getModel().addNode( node,
AliasDirectoryNode.this,
AliasDirectoryNode.this.getChildCount() );
sort();
getModel().showNode( node );
}
} );
retVal.add( addItem );
return retVal;
}
}

205
src/alias/AliasEditor.java Normal file
View File

@@ -0,0 +1,205 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.tree.TreePath;
import map.MapIcon;
import map.MapIconListCellRenderer;
import net.miginfocom.swing.MigLayout;
import settings.SettingsManager;
import controller.ConfigurableNode;
import controller.ResourceManager;
public class AliasEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private AliasNode mAliasNode;
private ResourceManager mResourceManager;
private JLabel mLabelName;
private JTextField mTextAlias;
private JLabel mLabelMapColor;
private JButton mButtonColor;
private JComboBox<MapIcon> mComboMapIcon;
private JButton mBtnIconManager;
public AliasEditor( AliasNode aliasNode, ResourceManager resourceManager )
{
mAliasNode = aliasNode;
mResourceManager = resourceManager;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Alias" ) );
mLabelName = new JLabel( "Name:" );
add( mLabelName, "align right" );
mTextAlias = new JTextField( mAliasNode.getAlias().getName() );
add( mTextAlias, "grow, wrap" );
mLabelMapColor = new JLabel( "Map Color:" );
add( mLabelMapColor, "align right" );
mButtonColor = new JButton( "Map Color" );
mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() );
mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() );
mButtonColor.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Color newColor = JColorChooser.showDialog(
AliasEditor.this,
"Choose color for map labels and routes",
mAliasNode.getAlias().getMapColor() );
mButtonColor.setForeground( newColor );
mButtonColor.setBackground( newColor );
}
} );
add( mButtonColor, "wrap" );
add( new JLabel( "Map Icon:" ), "align right" );
mComboMapIcon = new JComboBox<MapIcon>(
mResourceManager.getSettingsManager().getMapIcons() );
MapIconListCellRenderer renderer = new MapIconListCellRenderer();
renderer.setPreferredSize( new Dimension( 200, 30 ) );
mComboMapIcon.setRenderer( renderer );
String iconName = mAliasNode.getAlias().getIconName();
if( iconName == null )
{
iconName = SettingsManager.DEFAULT_ICON;
}
MapIcon savedIcon = mResourceManager.getSettingsManager()
.getMapIcon( iconName );
if( savedIcon != null )
{
mComboMapIcon.setSelectedItem( savedIcon );
}
add( mComboMapIcon, "wrap" );
//Dummy place holder
add( new JLabel() );
mBtnIconManager = new JButton( "Icon Manager" );
mBtnIconManager.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent arg0 )
{
mResourceManager.getController().showIconManager();
}
} );
add( mBtnIconManager, "span 2,wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( AliasEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( AliasEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String alias = mTextAlias.getText();
if( alias != null )
{
boolean expanded = mAliasNode.getModel().getTree()
.isExpanded( new TreePath( mAliasNode ) );
mAliasNode.getAlias().setName( alias );
((ConfigurableNode)mAliasNode.getParent()).sort();
mAliasNode.getAlias().setColor(
mButtonColor.getBackground().getRGB() );
MapIcon selectedIcon = (MapIcon)mComboMapIcon.getSelectedItem();
if( selectedIcon != null )
{
mAliasNode.getAlias().setIconName( selectedIcon.getName() );
}
mAliasNode.save();
mAliasNode.show();
if( expanded )
{
mAliasNode.getModel().getTree()
.expandPath( new TreePath( mAliasNode ) );
}
}
else
{
JOptionPane.showMessageDialog( AliasEditor.this, "Please enter an alias name" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextAlias.setText( mAliasNode.getAlias().getName() );
mButtonColor.setBackground( mAliasNode.getAlias().getMapColor() );
mButtonColor.setForeground( mAliasNode.getAlias().getMapColor() );
MapIcon savedIcon = mResourceManager.getSettingsManager()
.getMapIcon( mAliasNode.getAlias().getIconName() );
mComboMapIcon.setSelectedItem( savedIcon );
}
mAliasNode.refresh();
}
}

41
src/alias/AliasID.java Normal file
View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import audio.AudioType;
public abstract class AliasID
{
public AliasID()
{
}
public abstract AliasIDType getType();
public boolean hasAudioType()
{
return false;
}
public AudioType getAudioType()
{
return AudioType.NORMAL;
}
public abstract boolean matches( AliasID id );
}

View File

@@ -0,0 +1,35 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import controller.ConfigurableNode;
public class AliasIDNode extends ConfigurableNode
{
private static final long serialVersionUID = 1L;
public AliasIDNode( AliasID id )
{
super( id );
}
public void save()
{
getModel().getResourceManager().getPlaylistManager().save();
}
}

View File

@@ -0,0 +1,31 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
public enum AliasIDType
{
ESN,
Fleetsync,
LTRNetUID,
MDC1200,
MIN,
MPT1327,
Site,
Status,
Talkgroup;
}

409
src/alias/AliasList.java Normal file
View File

@@ -0,0 +1,409 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import alias.esn.Esn;
import alias.fleetsync.FleetsyncID;
import alias.fleetsync.StatusID;
import alias.mdc.MDC1200ID;
import alias.mobileID.Min;
import alias.mpt1327.MPT1327ID;
import alias.siteID.SiteID;
import alias.talkgroup.TalkgroupID;
import alias.uniqueID.UniqueID;
@XmlSeeAlso( { Alias.class,
AliasID.class,
FleetsyncID.class,
Esn.class,
Group.class,
MDC1200ID.class,
Min.class,
MPT1327ID.class,
UniqueID.class,
SiteID.class,
StatusID.class,
TalkgroupID.class } )
@XmlRootElement( name = "alias_list" )
public class AliasList implements Comparable<AliasList>
{
private String mName;
private ArrayList<Group> mGroups = new ArrayList<Group>();
private HashMap<String,Alias> mESN = new HashMap<String,Alias>();
private HashMap<String,Alias> mFleetsync = new HashMap<String,Alias>();
private HashMap<String,Alias> mMDC1200 = new HashMap<String,Alias>();
private HashMap<String,Alias> mMobileID = new HashMap<String,Alias>();
private HashMap<String,Alias> mMPT1327 = new HashMap<String,Alias>();
private HashMap<Integer, Alias> mSiteID = new HashMap<Integer,Alias>();
private HashMap<Integer, Alias> mStatus = new HashMap<Integer,Alias>();
private HashMap<String,Alias> mTalkgroup = new HashMap<String,Alias>();
private HashMap<Integer,Alias> mUniqueID = new HashMap<Integer,Alias>();
private boolean mESNWildcard = false;
private boolean mFleetsyncWildcard = false;
private boolean mMDC1200Wildcard = false;
private boolean mMPT1327Wildcard = false;
private boolean mTalkgroupWildcard = false;
public AliasList()
{
this( null );
}
public AliasList( String name )
{
mName = name;
update();
}
/**
* Load/Reload all lookup hashmaps
*/
public void update()
{
//Clear hashmaps
mESN.clear();
mFleetsync.clear();
mMDC1200.clear();
mMobileID.clear();
mMPT1327.clear();
mSiteID.clear();
mStatus.clear();
mTalkgroup.clear();
mUniqueID.clear();
for( Group group: mGroups )
{
for( Alias alias: group.getAlias() )
{
for( AliasID id: alias.getId() )
{
switch( id.getType() )
{
case ESN:
Esn esn = (Esn)id;
if( esn.getEsn().contains( "*" ) )
{
mESNWildcard = true;
//Replace (*) wildcard with regex wildcard (.)
mESN.put( esn.getEsn().replace( "*", "." ), alias );
}
else
{
mESN.put( esn.getEsn(), alias );
}
break;
case Fleetsync:
FleetsyncID fs = (FleetsyncID)id;
if( fs.getIdent().contains( "*" ) )
{
mFleetsyncWildcard = true;
//Replace (*) wildcard with regex wildcard (.)
mFleetsync.put( fs.getIdent().replace( "*", "." ), alias );
}
else
{
mFleetsync.put( fs.getIdent(), alias );
}
break;
case MDC1200:
MDC1200ID mdc = (MDC1200ID)id;
if( mdc.getIdent().contains( "*" ) )
{
mMDC1200Wildcard = true;
//Replace (*) wildcard with regex wildcard (.)
mMDC1200.put( mdc.getIdent().replace( "*", "." ), alias );
}
else
{
mMDC1200.put( mdc.getIdent(), alias );
}
break;
case MPT1327:
MPT1327ID mpt = (MPT1327ID)id;
String ident = mpt.getIdent();
if( ident != null )
{
if( ident.contains( "*" ) )
{
mMPT1327Wildcard = true;
//Replace (*) wildcard with regex wildcard (.)
mMPT1327.put( ident.replace( "*", "." ), alias );
}
else
{
mMPT1327.put( ident, alias );
}
}
break;
case MIN:
Min min = (Min)id;
mMobileID.put( min.getMin(), alias );
break;
case LTRNetUID:
UniqueID uid = (UniqueID)id;
mUniqueID.put( uid.getUid(), alias );
break;
case Site:
mSiteID.put( ((SiteID)id).getSite(), alias );
break;
case Status:
mStatus.put( ((StatusID)id).getStatus(), alias );
break;
case Talkgroup:
TalkgroupID tgid = (TalkgroupID)id;
if( tgid.getTalkgroup().contains( "*" ) )
{
mTalkgroupWildcard = true;
//Replace (*) wildcard with regex wildcard (.)
mTalkgroup.put( tgid.getTalkgroup()
.replace( "*", "." ), alias );
}
else
{
mTalkgroup.put( tgid.getTalkgroup(), alias );
}
break;
}
}
}
}
}
public Alias getSiteID( int siteID )
{
return mSiteID.get( siteID );
}
public Alias getStatus( int status )
{
return mStatus.get( status );
}
public Alias getUniqueID( int uniqueID )
{
return mUniqueID.get( uniqueID );
}
public Alias getESNAlias( String esn )
{
if( esn != null )
{
Alias retVal = null;
if( mESNWildcard )
{
for( String key: mESN.keySet() )
{
if( esn.matches( key ) )
{
return mESN.get( key );
}
}
}
else
{
return mESN.get( esn );
}
}
return null;
}
public Alias getFleetsyncAlias( String ident )
{
if( ident != null )
{
Alias retVal = null;
if( mFleetsyncWildcard )
{
for( String key: mFleetsync.keySet() )
{
if( ident.matches( key ) )
{
return mFleetsync.get( key );
}
}
}
else
{
return mFleetsync.get( ident );
}
}
return null;
}
public Alias getMDC1200Alias( String ident )
{
if( ident != null )
{
Alias retVal = null;
if( mMDC1200Wildcard )
{
for( String key: mMDC1200.keySet() )
{
if( ident.matches( key ) )
{
return mMDC1200.get( key );
}
}
}
else
{
return mMDC1200.get( ident );
}
}
return null;
}
public Alias getMPT1327Alias( String ident )
{
if( ident != null )
{
Alias retVal = null;
if( mMPT1327Wildcard )
{
for( String key: mMPT1327.keySet() )
{
if( ident.matches( key ) )
{
return mMPT1327.get( key );
}
}
}
else
{
return mMPT1327.get( ident );
}
}
return null;
}
public Group getGroup( Alias alias )
{
if( alias != null )
{
for( Group group: mGroups )
{
if( group.contians( alias ) )
{
return group;
}
}
}
return null;
}
public Alias getMobileIDNumberAlias( String ident )
{
return mMobileID.get( ident );
}
public Alias getTalkgroupAlias( String tgid )
{
if( tgid != null )
{
Alias retVal = null;
if( mTalkgroupWildcard )
{
for( String key: mTalkgroup.keySet() )
{
if( tgid.matches( key ) )
{
return mTalkgroup.get( key );
}
}
}
else
{
return mTalkgroup.get( tgid );
}
}
return null;
}
public String toString()
{
return mName;
}
@XmlAttribute
public String getName()
{
return mName;
}
public void setName( String name )
{
mName = name;
}
public ArrayList<Group> getGroup()
{
return mGroups;
}
public void setGroup( ArrayList<Group> groups )
{
mGroups = groups;
}
public void addGroup( Group group )
{
mGroups.add( group );
}
public void removeGroup( Group group )
{
mGroups.remove( group );
}
@Override
public int compareTo( AliasList otherAliasList )
{
return getName().compareTo( otherAliasList.getName() );
}
}

View File

@@ -0,0 +1,126 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import controller.ConfigurableNode;
public class AliasListNode extends ConfigurableNode
{
private static final long serialVersionUID = 1L;
public AliasListNode( AliasList list )
{
super( list );
}
@Override
public JPanel getEditor()
{
return new ListEditor( this );
}
public AliasList getList()
{
return (AliasList)getUserObject();
}
public void init()
{
for( Group group: getList().getGroup() )
{
GroupNode node = new GroupNode( group );
getModel().addNode( node, AliasListNode.this, getChildCount() );
node.init();
}
sort();
}
public String toString()
{
return getList().getName() + " [" + this.getChildCount() + "]";
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addItem = new JMenuItem( "Add Group" );
addItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Group group = new Group();
getList().addGroup( group );
GroupNode node = new GroupNode( group );
getModel().addNode( node,
AliasListNode.this,
AliasListNode.this.getChildCount() );
sort();
getModel().showNode( node );
}
} );
retVal.add( addItem );
retVal.add( new JSeparator() );
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasDirectoryNode parent = (AliasDirectoryNode)getParent();
parent.getAliasDirectory().removeAliasList( getList() );
save();
getModel().removeNodeFromParent( AliasListNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

373
src/alias/AliasNode.java Normal file
View File

@@ -0,0 +1,373 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import map.MapIcon;
import alias.esn.ESNNode;
import alias.esn.Esn;
import alias.fleetsync.FleetsyncID;
import alias.fleetsync.FleetsyncIDNode;
import alias.fleetsync.StatusID;
import alias.fleetsync.StatusIDNode;
import alias.mdc.MDC1200ID;
import alias.mdc.MDC1200IDNode;
import alias.mobileID.MINNode;
import alias.mobileID.Min;
import alias.mpt1327.MPT1327ID;
import alias.mpt1327.MPT1327IDNode;
import alias.siteID.SiteID;
import alias.siteID.SiteIDNode;
import alias.talkgroup.TalkgroupID;
import alias.talkgroup.TalkgroupIDNode;
import alias.uniqueID.UniqueID;
import alias.uniqueID.UniqueIDNode;
import controller.ConfigurableNode;
public class AliasNode extends ConfigurableNode
{
private static final long serialVersionUID = 1L;
public AliasNode( Alias alias )
{
super( alias );
}
@Override
public JPanel getEditor()
{
return new AliasEditor( this, getModel().getResourceManager() );
}
public Alias getAlias()
{
return (Alias)getUserObject();
}
public String getIconPath()
{
String icon = getAlias().getIconName();
MapIcon mapIcon = getModel().getResourceManager()
.getSettingsManager().getMapIcon( icon );
if( mapIcon != null )
{
return mapIcon.getPath();
}
else
{
return null;
}
}
public void init()
{
for( AliasID aliasID: getAlias().getId() )
{
if( aliasID instanceof Esn )
{
getModel().addNode( new ESNNode( (Esn)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof FleetsyncID )
{
getModel().addNode( new FleetsyncIDNode( (FleetsyncID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof MDC1200ID )
{
getModel().addNode( new MDC1200IDNode( (MDC1200ID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof Min )
{
getModel().addNode( new MINNode( (Min)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof MPT1327ID )
{
getModel().addNode( new MPT1327IDNode( (MPT1327ID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof SiteID )
{
getModel().addNode( new SiteIDNode( (SiteID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof StatusID )
{
getModel().addNode( new StatusIDNode( (StatusID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof TalkgroupID )
{
getModel().addNode( new TalkgroupIDNode( (TalkgroupID)aliasID ),
AliasNode.this, getChildCount() );
}
else if( aliasID instanceof UniqueID )
{
getModel().addNode( new UniqueIDNode( (UniqueID)aliasID ),
AliasNode.this, getChildCount() );
}
}
sort();
}
public String toString()
{
return getAlias().getName() + " [" + this.getChildCount() + "]";
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenu addIDMenu = new JMenu( "Add ID" );
JMenuItem addESNItem = new JMenuItem( "ESN" );
addESNItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Esn esn = new Esn();
getAlias().addAliasID( esn );
ESNNode node = new ESNNode( esn );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addESNItem );
JMenuItem addFleetsyncItem = new JMenuItem( "Fleetsync" );
addFleetsyncItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
FleetsyncID fs = new FleetsyncID();
getAlias().addAliasID( fs );
FleetsyncIDNode node = new FleetsyncIDNode( fs );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addFleetsyncItem );
JMenuItem addMDCItem = new JMenuItem( "MDC-1200" );
addMDCItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
MDC1200ID mdc = new MDC1200ID();
getAlias().addAliasID( mdc );
MDC1200IDNode node = new MDC1200IDNode( mdc );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addMDCItem );
JMenuItem addMINItem = new JMenuItem( "MIN" );
addMINItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Min min = new Min();
getAlias().addAliasID( min );
MINNode node = new MINNode( min );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addMINItem );
JMenuItem addMPTItem = new JMenuItem( "MPT-1327" );
addMPTItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
MPT1327ID mpt = new MPT1327ID();
getAlias().addAliasID( mpt );
MPT1327IDNode node = new MPT1327IDNode( mpt );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addMPTItem );
JMenuItem addSiteItem = new JMenuItem( "Site" );
addSiteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
SiteID siteID = new SiteID();
getAlias().addAliasID( siteID );
SiteIDNode node = new SiteIDNode( siteID );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addSiteItem );
JMenuItem addStatusItem = new JMenuItem( "Status" );
addStatusItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
StatusID statusID = new StatusID();
getAlias().addAliasID( statusID );
StatusIDNode node = new StatusIDNode( statusID );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addStatusItem );
JMenuItem addTalkgroupItem = new JMenuItem( "Talkgroup" );
addTalkgroupItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
TalkgroupID tg = new TalkgroupID();
getAlias().addAliasID( tg );
TalkgroupIDNode node = new TalkgroupIDNode( tg );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addTalkgroupItem );
JMenuItem addUniqueIDItem = new JMenuItem( "Unique ID" );
addUniqueIDItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
UniqueID uid = new UniqueID();
getAlias().addAliasID( uid );
UniqueIDNode node = new UniqueIDNode( uid );
getModel().addNode( node,
AliasNode.this,
AliasNode.this.getChildCount() );
node.show();
}
} );
addIDMenu.add( addUniqueIDItem );
retVal.add( addIDMenu );
retVal.add( new JSeparator() );
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
GroupNode parent = (GroupNode)getParent();
parent.getGroup().removeAlias( getAlias() );
save();
getModel().removeNodeFromParent( AliasNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

73
src/alias/Group.java Normal file
View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlAttribute;
public class Group
{
private String mName;
private ArrayList<Alias> mAliases = new ArrayList<Alias>();
public Group()
{
}
public String toString()
{
return "Group: " + mName;
}
@XmlAttribute
public String getName()
{
return mName;
}
public void setName( String name )
{
mName = name;
}
public ArrayList<Alias> getAlias()
{
return mAliases;
}
public void setAlias( ArrayList<Alias> aliases )
{
mAliases = aliases;
}
public void addAlias( Alias alias )
{
mAliases.add( alias );
}
public void removeAlias( Alias alias )
{
mAliases.remove( alias );
}
public boolean contians( Alias alias )
{
return mAliases.contains( alias );
}
}

110
src/alias/GroupEditor.java Normal file
View File

@@ -0,0 +1,110 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.tree.TreePath;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class GroupEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private GroupNode mGroupNode;
private JLabel mLabelName;
private JTextField mTextGroup;
public GroupEditor( GroupNode groupNode )
{
mGroupNode = groupNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Group" ) );
mLabelName = new JLabel( "Name:" );
add( mLabelName, "align right" );
mTextGroup = new JTextField( mGroupNode.getGroup().getName() );
add( mTextGroup, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( GroupEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( GroupEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String group = mTextGroup.getText();
if( group != null )
{
boolean expanded = mGroupNode.getModel().getTree()
.isExpanded( new TreePath( mGroupNode ) );
mGroupNode.getGroup().setName( group );
((ConfigurableNode)mGroupNode.getParent()).sort();
mGroupNode.save();
mGroupNode.show();
if( expanded )
{
mGroupNode.getModel().getTree()
.expandPath( new TreePath( mGroupNode ) );
}
}
else
{
JOptionPane.showMessageDialog( GroupEditor.this, "Please enter a group name" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextGroup.setText( mGroupNode.getGroup().getName() );
}
mGroupNode.refresh();
}
}

126
src/alias/GroupNode.java Normal file
View File

@@ -0,0 +1,126 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import controller.ConfigurableNode;
public class GroupNode extends ConfigurableNode
{
private static final long serialVersionUID = 1L;
public GroupNode( Group group )
{
super( group );
}
@Override
public JPanel getEditor()
{
return new GroupEditor( this );
}
public Group getGroup()
{
return (Group)getUserObject();
}
public void init()
{
for( Alias alias: getGroup().getAlias() )
{
AliasNode node = new AliasNode( alias );
getModel().addNode( node, GroupNode.this, getChildCount() );
node.init();
}
sort();
}
public String toString()
{
return getGroup().getName() + " [" + this.getChildCount() + "]";
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addItem = new JMenuItem( "Add Alias" );
addItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
Alias alias = new Alias();
getGroup().addAlias( alias );
AliasNode node = new AliasNode( alias );
getModel().addNode( node,
GroupNode.this,
GroupNode.this.getChildCount() );
sort();
getModel().showNode( node );
}
} );
retVal.add( addItem );
retVal.add( new JSeparator() );
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasListNode parent = (AliasListNode)getParent();
parent.getList().removeGroup( getGroup() );
save();
getModel().removeNodeFromParent( GroupNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

107
src/alias/ListEditor.java Normal file
View File

@@ -0,0 +1,107 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.tree.TreePath;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class ListEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private AliasListNode mListNode;
private JLabel mLabelName;
private JTextField mTextGroup;
public ListEditor( AliasListNode listNode )
{
mListNode = listNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "List" ) );
mLabelName = new JLabel( "Name:" );
add( mLabelName, "align right" );
mTextGroup = new JTextField( mListNode.getList().getName() );
add( mTextGroup, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( ListEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( ListEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String group = mTextGroup.getText();
if( group != null )
{
boolean expanded = mListNode.getModel().getTree()
.isExpanded( new TreePath( mListNode ) );
mListNode.getList().setName( group );
((ConfigurableNode)mListNode.getParent()).sort();
mListNode.save();
mListNode.show();
if( expanded )
{
mListNode.getModel().getTree().expandPath( new TreePath( mListNode ) );
}
}
else
{
JOptionPane.showMessageDialog( ListEditor.this, "Please enter a list name" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextGroup.setText( mListNode.getList().getName() );
}
mListNode.refresh();
}
}

View File

@@ -0,0 +1,100 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.esn;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class ESNEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private ESNNode mESNNode;
private JLabel mLabelName;
private JTextField mTextESN;
public ESNEditor( ESNNode esnNode )
{
mESNNode = esnNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "ESN" ) );
mLabelName = new JLabel( "ESN:" );
add( mLabelName, "align right" );
mTextESN = new JTextField( mESNNode.getESN().getEsn() );
add( mTextESN, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( ESNEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( ESNEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String esn = mTextESN.getText();
if( esn != null )
{
mESNNode.getESN().setEsn( esn );
((ConfigurableNode)mESNNode.getParent()).sort();
mESNNode.save();
mESNNode.show();
}
else
{
JOptionPane.showMessageDialog( ESNEditor.this, "Please enter an ESN" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextESN.setText( mESNNode.getESN().getEsn() );
}
mESNNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.esn;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class ESNNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public ESNNode( Esn esn )
{
super( esn );
}
@Override
public JPanel getEditor()
{
return new ESNEditor( this );
}
public Esn getESN()
{
return (Esn)getUserObject();
}
public String toString()
{
return "ESN " + getESN().getEsn();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getESN() );
save();
getModel().removeNodeFromParent( ESNNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

72
src/alias/esn/Esn.java Normal file
View File

@@ -0,0 +1,72 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.esn;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class Esn extends AliasID
{
private String mEsn;
public Esn()
{
}
@XmlAttribute
public String getEsn()
{
return mEsn;
}
public void setEsn( String esn )
{
mEsn = esn;
}
public String toString()
{
return "ESN: " + mEsn;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( mEsn != null && id instanceof Esn )
{
Esn esn = (Esn)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mEsn.replace( "*", ".?" );
retVal = esn.getEsn().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.ESN;
}
}

View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class FleetsyncID extends AliasID
{
private String mID;
public FleetsyncID()
{
}
@XmlAttribute
public String getIdent()
{
return mID;
}
public void setIdent( String ident )
{
mID = ident;
}
public String toString()
{
return "Fleetsync: " + mID;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( mID != null && id instanceof FleetsyncID )
{
FleetsyncID tgid = (FleetsyncID)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mID.replace( "*", ".?" );
retVal = tgid.getIdent().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.Fleetsync;
}
}

View File

@@ -0,0 +1,109 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class FleetsyncIDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private FleetsyncIDNode mFleetsyncIDNode;
private JLabel mLabelName;
private JTextField mTextIdent;
private String mHelpText = "Enter a formatted fleetsync identifier.\n\n"
+ "Format: PPP-IIII (P=Prefix, I=Identifier)\n\n"
+ "Wildcard: use one or more asterisks (*) for any talkgroup "
+ "digits.\n\n";
public FleetsyncIDEditor( FleetsyncIDNode fsNode )
{
mFleetsyncIDNode = fsNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Fleetsync" ) );
mLabelName = new JLabel( "Ident:" );
add( mLabelName, "align right" );
mTextIdent = new JTextField( mFleetsyncIDNode.getFleetsyncID().getIdent() );
add( mTextIdent, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( FleetsyncIDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( FleetsyncIDEditor.this );
add( btnReset, "wrap" );
JTextArea helpText = new JTextArea( mHelpText );
helpText.setLineWrap( true );
add( helpText, "span,grow" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String ident = mTextIdent.getText();
if( ident != null )
{
mFleetsyncIDNode.getFleetsyncID().setIdent( ident );
((ConfigurableNode)mFleetsyncIDNode.getParent()).sort();
mFleetsyncIDNode.save();
mFleetsyncIDNode.show();
}
else
{
JOptionPane.showMessageDialog( FleetsyncIDEditor.this, "Please enter an ident" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextIdent.setText( mFleetsyncIDNode.getFleetsyncID().getIdent() );
}
mFleetsyncIDNode.refresh();
}
}

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class FleetsyncIDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public FleetsyncIDNode( FleetsyncID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new FleetsyncIDEditor( this );
}
public FleetsyncID getFleetsyncID()
{
return (FleetsyncID)getUserObject();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "Fleetsync " );
String ident = getFleetsyncID().getIdent();
if( ident != null )
{
sb.append( ident );
}
return sb.toString();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getFleetsyncID() );
save();
getModel().removeNodeFromParent( FleetsyncIDNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class StatusID extends AliasID
{
private int mStatus;
public StatusID()
{
}
@XmlAttribute
public int getStatus()
{
return mStatus;
}
public void setStatus( int status )
{
this.mStatus = status;
}
public String toString()
{
return "Status: " + mStatus;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( id instanceof StatusID )
{
StatusID statusId = (StatusID)id;
retVal = ( mStatus == statusId.getStatus() );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.Status;
}
}

View File

@@ -0,0 +1,114 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import log.Log;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class StatusIDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private StatusIDNode mStatusIDNode;
private JLabel mLabelName;
private JTextField mTextStatusID;
public StatusIDEditor( StatusIDNode statusIDNode )
{
mStatusIDNode = statusIDNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Status Code" ) );
mLabelName = new JLabel( "Status Code:" );
add( mLabelName, "align right" );
mTextStatusID = new JTextField(
String.valueOf( mStatusIDNode.getStatusID().getStatus() ) );
add( mTextStatusID, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( StatusIDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( StatusIDEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String statusIDString = mTextStatusID.getText();
if( statusIDString != null )
{
try
{
int id = Integer.parseInt( statusIDString );
mStatusIDNode.getStatusID().setStatus( id );
((ConfigurableNode)mStatusIDNode.getParent()).sort();
mStatusIDNode.save();
mStatusIDNode.show();
}
catch( Exception ex )
{
Log.error( "StatusIDEditor - error parsing int status " +
"id from [" + statusIDString + "]" );
}
}
else
{
JOptionPane.showMessageDialog( StatusIDEditor.this,
"Please enter a status ID code" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextStatusID.setText(
String.valueOf( mStatusIDNode.getStatusID().getStatus() ) );
}
mStatusIDNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.fleetsync;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class StatusIDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public StatusIDNode( StatusID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new StatusIDEditor( this );
}
public StatusID getStatusID()
{
return (StatusID)getUserObject();
}
public String toString()
{
return "Status Code " + getStatusID().getStatus();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getStatusID() );
save();
getModel().removeNodeFromParent( StatusIDNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mdc;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class MDC1200ID extends AliasID
{
private String mID;
public MDC1200ID()
{
}
@XmlAttribute
public String getIdent()
{
return mID;
}
public void setIdent( String ident )
{
mID = ident;
}
public String toString()
{
return "MDC-1200: " + mID;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( mID != null && id instanceof MDC1200ID )
{
MDC1200ID tgid = (MDC1200ID)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mID.replace( "*", ".?" );
retVal = tgid.getIdent().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.MDC1200;
}
}

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mdc;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class MDC1200IDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private MDC1200IDNode mMDC1200IDNode;
private JLabel mLabelName;
private JTextField mTextIdent;
public MDC1200IDEditor( MDC1200IDNode fsNode )
{
mMDC1200IDNode = fsNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "MDC-1200" ) );
mLabelName = new JLabel( "Unit ID:" );
add( mLabelName, "align right" );
mTextIdent = new JTextField( mMDC1200IDNode.getMDC1200ID().getIdent() );
add( mTextIdent, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( MDC1200IDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( MDC1200IDEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String ident = mTextIdent.getText();
if( ident != null )
{
mMDC1200IDNode.getMDC1200ID().setIdent( ident );
((ConfigurableNode)mMDC1200IDNode.getParent()).sort();
mMDC1200IDNode.save();
mMDC1200IDNode.show();
}
else
{
JOptionPane.showMessageDialog( MDC1200IDEditor.this, "Please enter a unit ID" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextIdent.setText( mMDC1200IDNode.getMDC1200ID().getIdent() );
}
mMDC1200IDNode.refresh();
}
}

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mdc;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class MDC1200IDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public MDC1200IDNode( MDC1200ID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new MDC1200IDEditor( this );
}
public MDC1200ID getMDC1200ID()
{
return (MDC1200ID)getUserObject();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "MDC-1200 " );
sb.append( getMDC1200ID().getIdent() );
return sb.toString();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getMDC1200ID() );
save();
getModel().removeNodeFromParent( MDC1200IDNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

View File

@@ -0,0 +1,100 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mobileID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class MINEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private MINNode mMINNode;
private JLabel mLabelName;
private JTextField mTextMIN;
public MINEditor( MINNode minNode )
{
mMINNode = minNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Mobile ID Number (MIN)" ) );
mLabelName = new JLabel( "MIN:" );
add( mLabelName, "align right" );
mTextMIN = new JTextField( mMINNode.getMIN().getMin() );
add( mTextMIN, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( MINEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( MINEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String esn = mTextMIN.getText();
if( esn != null )
{
mMINNode.getMIN().setMin( esn );
((ConfigurableNode)mMINNode.getParent()).sort();
mMINNode.save();
mMINNode.show();
}
else
{
JOptionPane.showMessageDialog( MINEditor.this, "Please enter an ESN" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextMIN.setText( mMINNode.getMIN().getMin() );
}
mMINNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mobileID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class MINNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public MINNode( Min min )
{
super( min );
}
@Override
public JPanel getEditor()
{
return new MINEditor( this );
}
public Min getMIN()
{
return (Min)getUserObject();
}
public String toString()
{
return "MIN " + getMIN().getMin();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getMIN() );
save();
getModel().removeNodeFromParent( MINNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

View File

@@ -0,0 +1,75 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mobileID;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
/**
* Mobile ID Number
*/
public class Min extends AliasID
{
private String mMin;
public Min()
{
}
@XmlAttribute
public String getMin()
{
return mMin;
}
public void setMin( String min )
{
mMin = min;
}
public String toString()
{
return "MIN: " + mMin;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( mMin != null && id instanceof Min )
{
Min min = (Min)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mMin.replace( "*", ".?" );
retVal = min.getMin().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.MIN;
}
}

View File

@@ -0,0 +1,72 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mpt1327;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class MPT1327ID extends AliasID
{
private String mID;
public MPT1327ID()
{
}
@XmlAttribute
public String getIdent()
{
return mID;
}
public void setIdent( String ident )
{
mID = ident;
}
public String toString()
{
return "MPT-1327: " + mID;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( mID != null && id instanceof MPT1327ID )
{
MPT1327ID tgid = (MPT1327ID)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mID.replace( "*", ".?" );
retVal = tgid.getIdent().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.MPT1327;
}
}

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mpt1327;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class MPT1327IDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private MPT1327IDNode mMPT1327IDNode;
private JLabel mLabelName;
private JTextField mTextIdent;
public MPT1327IDEditor( MPT1327IDNode fsNode )
{
mMPT1327IDNode = fsNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "MPT-1327" ) );
mLabelName = new JLabel( "Unit ID:" );
add( mLabelName, "align right" );
mTextIdent = new JTextField( mMPT1327IDNode.getMPT1327ID().getIdent() );
add( mTextIdent, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( MPT1327IDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( MPT1327IDEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String ident = mTextIdent.getText();
if( ident != null )
{
mMPT1327IDNode.getMPT1327ID().setIdent( ident );
((ConfigurableNode)mMPT1327IDNode.getParent()).sort();
mMPT1327IDNode.save();
mMPT1327IDNode.show();
}
else
{
JOptionPane.showMessageDialog( MPT1327IDEditor.this, "Please enter a MPT1327 unit ID" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextIdent.setText( mMPT1327IDNode.getMPT1327ID().getIdent() );
}
mMPT1327IDNode.refresh();
}
}

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.mpt1327;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class MPT1327IDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public MPT1327IDNode( MPT1327ID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new MPT1327IDEditor( this );
}
public MPT1327ID getMPT1327ID()
{
return (MPT1327ID)getUserObject();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "MPT-1327 " );
sb.append( getMPT1327ID().getIdent() );
return sb.toString();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem deleteItem = new JMenuItem( "Delete" );
deleteItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getMPT1327ID() );
save();
getModel().removeNodeFromParent( MPT1327IDNode.this );
}
}
} );
retVal.add( deleteItem );
return retVal;
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.siteID;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class SiteID extends AliasID
{
private int mSite;
public SiteID()
{
}
@XmlAttribute
public int getSite()
{
return mSite;
}
public void setSite( int site )
{
this.mSite = site;
}
public String toString()
{
return "Site: " + mSite;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( id instanceof SiteID )
{
SiteID uid = (SiteID)id;
retVal = ( mSite == uid.getSite() );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.Site;
}
}

View File

@@ -0,0 +1,114 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.siteID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import log.Log;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class SiteIDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private SiteIDNode mSiteIDNode;
private JLabel mLabelName;
private JTextField mTextSiteID;
public SiteIDEditor( SiteIDNode siteIDNode )
{
mSiteIDNode = siteIDNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Site ID" ) );
mLabelName = new JLabel( "Site ID:" );
add( mLabelName, "align right" );
mTextSiteID = new JTextField(
String.valueOf( mSiteIDNode.getSiteID().getSite() ) );
add( mTextSiteID, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( SiteIDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( SiteIDEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String siteIDString = mTextSiteID.getText();
if( siteIDString != null )
{
try
{
int id = Integer.parseInt( siteIDString );
mSiteIDNode.getSiteID().setSite( id );
((ConfigurableNode)mSiteIDNode.getParent()).sort();
mSiteIDNode.save();
mSiteIDNode.show();
}
catch( Exception ex )
{
Log.error( "SiteIDEditor - error parsing int site " +
"id from [" + siteIDString + "]" );
}
}
else
{
JOptionPane.showMessageDialog( SiteIDEditor.this,
"Please enter a site ID" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextSiteID.setText(
String.valueOf( mSiteIDNode.getSiteID().getSite() ) );
}
mSiteIDNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.siteID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class SiteIDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public SiteIDNode( SiteID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new SiteIDEditor( this );
}
public SiteID getSiteID()
{
return (SiteID)getUserObject();
}
public String toString()
{
return "Site " + getSiteID().getSite();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getSiteID() );
save();
getModel().removeNodeFromParent( SiteIDNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

View File

@@ -0,0 +1,102 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.talkgroup;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
import audio.AudioType;
public class TalkgroupID extends AliasID
{
private String mTalkgroup;
private AudioType mAudioType;
public TalkgroupID()
{
}
@XmlAttribute
public String getTalkgroup()
{
return mTalkgroup;
}
public void setTalkgroup( String talkgroup )
{
mTalkgroup = talkgroup;
}
@XmlAttribute
public AudioType getAudioType()
{
return mAudioType;
}
public void setAudioType( AudioType type )
{
mAudioType = type;
}
public boolean hasAudioType()
{
return mAudioType != null;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append( "Talkgroup: " + mTalkgroup );
if( mAudioType != null )
{
sb.append( " [Audio " );
sb.append( mAudioType.getShortDisplayString() );
sb.append( "]" );
}
return sb.toString();
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( id instanceof TalkgroupID )
{
TalkgroupID tgid = (TalkgroupID)id;
//Create a pattern - replace * wildcards with regex single-char wildcard
String pattern = mTalkgroup.replace( "*", ".?" );
retVal = tgid.getTalkgroup().matches( pattern );
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.Talkgroup;
}
}

View File

@@ -0,0 +1,151 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.talkgroup;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import audio.AudioType;
import controller.ConfigurableNode;
public class TalkgroupIDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private TalkgroupIDNode mTalkgroupIDNode;
private JLabel mLabelName;
private JTextField mTextTalkgroupID;
private JLabel mLabelAudio;
private JComboBox<AudioType> mComboAudioTypes;
private String mHelpText = "Enter a formatted talkgroup identifier.\n\n"
+ "LTR Talkgroup Format: A-HH-TTT (A=Area, H=Home Repeater, "
+ "T=Talkgroup)\n\n"
+ "Passport Talkgroup Format: xxxxx (up to 5-digit number)\n\n"
+ "Wildcard: use one or more asterisks (*) for any talkgroup digits.\n\n"
+ "Audio: if the talkgroup uses simple frequency inversion, specify"
+ " the inversion frequency from the dropdown list to automatically"
+ " un-invert audio for this specific talkgroup";
public TalkgroupIDEditor( TalkgroupIDNode talkgroupIDNode )
{
mTalkgroupIDNode = talkgroupIDNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Talkgroup ID" ) );
mLabelName = new JLabel( "TGID:" );
add( mLabelName, "align right" );
mTextTalkgroupID = new JTextField();
mTextTalkgroupID.setText( mTalkgroupIDNode.getTalkgroupID().getTalkgroup() );
add( mTextTalkgroupID, "grow, wrap" );
mLabelAudio = new JLabel( "Audio:" );
add( mLabelAudio, "align right" );
mComboAudioTypes = new JComboBox<AudioType>();
mComboAudioTypes.setModel(
new DefaultComboBoxModel<AudioType>( AudioType.values() ) );
AudioType audioType = mTalkgroupIDNode.getTalkgroupID().getAudioType();
if( audioType != null )
{
mComboAudioTypes.setSelectedItem( audioType );
}
add( mComboAudioTypes, "wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( TalkgroupIDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( TalkgroupIDEditor.this );
add( btnReset, "wrap" );
JTextArea helpText = new JTextArea( mHelpText );
helpText.setLineWrap( true );
add( helpText, "span,grow" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String tgid = mTextTalkgroupID.getText();
if( tgid != null )
{
mTalkgroupIDNode.getTalkgroupID().setTalkgroup( tgid );
((ConfigurableNode)mTalkgroupIDNode.getParent()).sort();
AudioType selected = mComboAudioTypes
.getItemAt( mComboAudioTypes.getSelectedIndex() );
if( selected != null )
{
mTalkgroupIDNode.getTalkgroupID().setAudioType( selected );
}
mTalkgroupIDNode.save();
mTalkgroupIDNode.show();
}
else
{
JOptionPane.showMessageDialog( TalkgroupIDEditor.this,
"Please enter a talkgroup ID" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextTalkgroupID.setText(
mTalkgroupIDNode.getTalkgroupID().getTalkgroup() );
mComboAudioTypes.setSelectedItem(
mTalkgroupIDNode.getTalkgroupID().getAudioType() );
}
mTalkgroupIDNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.talkgroup;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class TalkgroupIDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public TalkgroupIDNode( TalkgroupID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new TalkgroupIDEditor( this );
}
public TalkgroupID getTalkgroupID()
{
return (TalkgroupID)getUserObject();
}
public String toString()
{
return "Talkgroup " + getTalkgroupID().getTalkgroup();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getTalkgroupID() );
save();
getModel().removeNodeFromParent( TalkgroupIDNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.uniqueID;
import javax.xml.bind.annotation.XmlAttribute;
import alias.AliasID;
import alias.AliasIDType;
public class UniqueID extends AliasID
{
private int mUid;
public UniqueID()
{
}
@XmlAttribute
public int getUid()
{
return mUid;
}
public void setUid( int uid )
{
this.mUid = uid;
}
public String toString()
{
return "UniqueID: " + mUid;
}
@Override
public boolean matches( AliasID id )
{
boolean retVal = false;
if( id instanceof UniqueID )
{
UniqueID uid = (UniqueID)id;
retVal = mUid == uid.getUid();
}
return retVal;
}
@Override
public AliasIDType getType()
{
return AliasIDType.LTRNetUID;
}
}

View File

@@ -0,0 +1,114 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.uniqueID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import log.Log;
import net.miginfocom.swing.MigLayout;
import controller.ConfigurableNode;
public class UniqueIDEditor extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private UniqueIDNode mUniqueIDNode;
private JLabel mLabelUniqueID;
private JTextField mTextUniqueID;
public UniqueIDEditor( UniqueIDNode uniqueIDNode )
{
mUniqueIDNode = uniqueIDNode;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout() );
setBorder( BorderFactory.createTitledBorder( "Unique ID" ) );
mLabelUniqueID = new JLabel( "Unique ID:" );
add( mLabelUniqueID, "align right" );
mTextUniqueID = new JTextField(
String.valueOf( mUniqueIDNode.getUniqueID().getUid() ) );
add( mTextUniqueID, "grow, wrap" );
JButton btnSave = new JButton( "Save" );
btnSave.addActionListener( UniqueIDEditor.this );
add( btnSave );
JButton btnReset = new JButton( "Reset" );
btnReset.addActionListener( UniqueIDEditor.this );
add( btnReset, "wrap" );
}
@Override
public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();
if( command.contentEquals( "Save" ) )
{
String uid = mTextUniqueID.getText();
if( uid != null )
{
try
{
int uidInt = Integer.parseInt( uid );
mUniqueIDNode.getUniqueID().setUid( uidInt );
((ConfigurableNode)mUniqueIDNode.getParent()).sort();
mUniqueIDNode.save();
mUniqueIDNode.show();
}
catch( Exception ex )
{
Log.error( "UniqueIDEditor - exception trying to parse " +
"int from uid [" + uid + "]" );
}
}
else
{
JOptionPane.showMessageDialog( UniqueIDEditor.this,
"Please enter a site number and unique ID" );
}
}
else if( command.contentEquals( "Reset" ) )
{
mTextUniqueID.setText(
String.valueOf( mUniqueIDNode.getUniqueID().getUid() ) );
}
mUniqueIDNode.refresh();
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package alias.uniqueID;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import alias.AliasIDNode;
import alias.AliasNode;
public class UniqueIDNode extends AliasIDNode
{
private static final long serialVersionUID = 1L;
public UniqueIDNode( UniqueID id )
{
super( id );
}
@Override
public JPanel getEditor()
{
return new UniqueIDEditor( this );
}
public UniqueID getUniqueID()
{
return (UniqueID)getUserObject();
}
public String toString()
{
return "Unique ID " + getUniqueID().getUid();
}
public JPopupMenu getContextMenu()
{
JPopupMenu retVal = new JPopupMenu();
JMenuItem addSystemItem = new JMenuItem( "Delete" );
addSystemItem.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
int n = JOptionPane.showConfirmDialog( getModel().getTree(),
"Are you sure you want to permanently delete this node?" );
if( n == JOptionPane.YES_OPTION )
{
AliasNode parent = (AliasNode)getParent();
parent.getAlias().removeAliasID( getUniqueID() );
save();
getModel().removeNodeFromParent( UniqueIDNode.this );
}
}
} );
retVal.add( addSystemItem );
return retVal;
}
}

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
import util.Oscillator;
import dsp.filter.FilterFactory;
import dsp.filter.FloatFIRFilter;
import dsp.filter.Window.WindowType;
/**
* Based on the AudioType applied, produces normal, muted, or audio inverted
* audio output.
*/
public class AudioAdapter
{
private static int mGain = 5;
private Oscillator mSineWaveGenerator;
private FloatFIRFilter mPostInversionFilter;
private FloatFIRFilter mAudioHighPassFilter;
private AudioType mAudioType = AudioType.NORMAL;
private int mSampleRate;
public AudioAdapter( int sampleRate )
{
mSampleRate = sampleRate;
mSineWaveGenerator = new Oscillator( 3000, mSampleRate );
mAudioHighPassFilter = new FloatFIRFilter(
FilterFactory.getHighPass( mSampleRate, 200, 1600, 48,
WindowType.HAMMING, true ), mGain );
mPostInversionFilter = new FloatFIRFilter(
FilterFactory.getLowPass( mSampleRate, 3000, 5000, 48,
WindowType.HAMMING, true ), mGain );
}
public void setAudioType( AudioType type )
{
if( type != null && type != mAudioType )
{
mAudioType = type;
int inversionFrequency = type.getAudioInversionFrequency();
if( inversionFrequency != 0 )
{
mSineWaveGenerator.setFrequency( inversionFrequency );;
}
}
}
public float get( float sample )
{
float retVal;
switch( mAudioType )
{
case NORMAL:
retVal = mAudioHighPassFilter.get( sample );
break;
case MUTE:
retVal = 0.0f;
break;
case INV2632:
case INV2718:
case INV2868:
case INV3023:
case INV3107:
case INV3196:
case INV3333:
case INV3339:
case INV3496:
case INV3729:
case INV4096:
default:
retVal = (float)( mPostInversionFilter.get(
mAudioHighPassFilter.get( sample ) *
mSineWaveGenerator.nextFloat() ) );
break;
}
return retVal;
}
}

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
import sample.Listener;
import util.Oscillator;
import dsp.filter.Filters;
import dsp.filter.FloatFIRFilter;
/**
* Applies audio inversion (or un-inversion) to a stream of float audio samples
* by multiplying each successive sample by either a 1 or a -1 value.
*/
public class AudioInverter implements Listener<Float>
{
private Oscillator mSineWaveGenerator;
private FloatFIRFilter mPostInversionLowPassFilter;
private Listener<Float> mListener;
public AudioInverter( int inversionFrequency, int sampleRate )
{
mSineWaveGenerator = new Oscillator( inversionFrequency, sampleRate );
mPostInversionLowPassFilter = new FloatFIRFilter(
Filters.FIRLP_55TAP_48000FS_3000FC.getCoefficients(), 1.04 );
mPostInversionLowPassFilter.setListener( new FilteredSampleProcessor() );
}
public AudioInverter( InversionFrequency frequency, int sampleRate )
{
this( frequency.getFrequency(), sampleRate );
}
public void setListener( Listener<Float> listener )
{
mListener = listener;
}
@Override
public void receive( Float sample )
{
//Multiply the sample by the folding frequency and then send it to
//the low pass filter
if( mPostInversionLowPassFilter != null )
{
mPostInversionLowPassFilter.receive(
sample * mSineWaveGenerator.nextFloat() );
}
}
/**
* Simple class to receive the output of the FIR low pass filter and then
* send it to the registered listener(s)
*/
class FilteredSampleProcessor implements Listener<Float>
{
@Override
public void receive( Float sample )
{
if( mListener != null )
{
mListener.receive( sample );
}
}
}
}

116
src/audio/AudioOutput.java Normal file
View File

@@ -0,0 +1,116 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
import java.nio.ByteBuffer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import log.Log;
import sample.Listener;
import buffer.FloatSampleBufferAssembler;
public class AudioOutput implements Listener<Float>,
SquelchListener,
AudioTypeListener
{
private static final int sAUDIO_BLOCK_SIZE = 24000;
private static final AudioFormat sAUDIO_FORMAT =
new AudioFormat( 48000, //SampleRate
16, //Sample Size
1, //Channels
true, //Signed
false ); //Little Endian
private AudioAdapter mAdapter = new AudioAdapter( 48000 );
private FloatSampleBufferAssembler mBuffer =
new FloatSampleBufferAssembler( sAUDIO_BLOCK_SIZE );
private SourceDataLine mOutput;
private boolean mEnabled = false;
private SquelchState mSquelchState = SquelchState.SQUELCH;
public AudioOutput( String channelName )
{
try
{
mOutput = AudioSystem.getSourceDataLine( sAUDIO_FORMAT );
mOutput.open( sAUDIO_FORMAT, (int)( sAUDIO_FORMAT.getSampleRate() ) );
mOutput.start();
}
catch ( LineUnavailableException e )
{
Log.warning( "AudioOutput - couldn't open audio speakers "
+ "for playback:" + e.getLocalizedMessage() );
}
}
@Override
public void setSquelch( SquelchState state )
{
mSquelchState = state;
}
public void setAudioPlaybackEnabled( boolean enabled )
{
mEnabled = enabled;
}
public void dispose()
{
mOutput.stop();
mOutput.close();
mOutput = null;
}
@Override
public void receive( Float sample )
{
float outputSample = mAdapter.get( sample );
if( mEnabled && mSquelchState == SquelchState.UNSQUELCH )
{
mBuffer.put( outputSample );
}
else
{
/* Use 0-valued samples when we're disabled or squelched */
mBuffer.put( 0.0f );
}
if( !mBuffer.hasRemaining() )
{
ByteBuffer buffer = mBuffer.get();
mOutput.write( buffer.array(), 0, buffer.array().length );
mBuffer.reset();
}
}
@Override
public void setAudioType( AudioType type )
{
mAdapter.setAudioType( type );
}
}

87
src/audio/AudioType.java Normal file
View File

@@ -0,0 +1,87 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
public enum AudioType
{
NORMAL( "Normal Audio", "Clear", 0 ),
MUTE( "Muted Audio", "Muted", 0 ),
INV2500( "Inverted Audio 2500Hz", "Inverted", 2500 ),
INV2550( "Inverted Audio 2550Hz", "Inverted", 2550 ),
INV2600( "Inverted Audio 2600Hz", "Inverted", 2600 ),
INV2632( "Inverted Audio 2632Hz", "Inverted", 2632 ),
INV2675( "Inverted Audio 2675Hz", "Inverted", 2675 ),
INV2718( "Inverted Audio 2718Hz", "Inverted", 2718 ),
INV2725( "Inverted Audio 2725Hz", "Inverted", 2725 ),
INV2750( "Inverted Audio 2750Hz", "Inverted", 2750 ),
INV2760( "Inverted Audio 2760Hz", "Inverted", 2760 ),
INV2775( "Inverted Audio 2775Hz", "Inverted", 2775 ),
INV2800( "Inverted Audio 2800Hz", "Inverted", 2800 ),
INV2825( "Inverted Audio 2825Hz", "Inverted", 2825 ),
INV2868( "Inverted Audio 2868Hz", "Inverted", 2868 ),
INV3023( "Inverted Audio 3023Hz", "Inverted", 3023 ),
INV3107( "Inverted Audio 3107Hz", "Inverted", 3107 ),
INV3196( "Inverted Audio 3196Hz", "Inverted", 3196 ),
INV3333( "Inverted Audio 3333Hz", "Inverted", 3333 ),
INV3339( "Inverted Audio 3339Hz", "Inverted", 3339 ),
INV3360( "Inverted Audio 3360Hz", "Inverted", 3360 ),
INV3375( "Inverted Audio 3375Hz", "Inverted", 3375 ),
INV3400( "Inverted Audio 3400Hz", "Inverted", 3400 ),
INV3450( "Inverted Audio 3450Hz", "Inverted", 3450 ),
INV3496( "Inverted Audio 3496Hz", "Inverted", 3496 ),
INV3729( "Inverted Audio 3729Hz", "Inverted", 3729 ),
INV4096( "Inverted Audio 4096Hz", "Inverted", 4096 ),
INV4300( "Inverted Audio 4300Hz", "Inverted", 4300 ),
INV4500( "Inverted Audio 4500Hz", "Inverted", 4500 ),
INV4700( "Inverted Audio 4700Hz", "Inverted", 4700 ),
INV4900( "Inverted Audio 4900Hz", "Inverted", 4900 );
private String mDisplayString;
private String mShortDisplayString;
private int mAudioInversionFrequency;
AudioType( String displayString,
String shortDisplayString,
int inversionFrequency )
{
mDisplayString = displayString;
mShortDisplayString = shortDisplayString;
mAudioInversionFrequency = inversionFrequency;
}
public String getDisplayString()
{
return mDisplayString;
}
public String getShortDisplayString()
{
return mShortDisplayString;
}
public int getAudioInversionFrequency()
{
return mAudioInversionFrequency;
}
@Override
public String toString()
{
return mDisplayString;
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
public interface AudioTypeListener
{
public void setAudioType( AudioType type );
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
/**
* Standard voice inversion foldover frequencies
*
* Reference: http://en.wikipedia.org/wiki/Voice_inversion
*/
public enum InversionFrequency
{
HZ_2500( 2500 ),
HZ_2550( 2550 ),
HZ_2600( 2600 ),
HZ_2632( 2632 ),
HZ_2675( 2675 ),
HZ_2718( 2718 ),
HZ_2800( 2800 ),
HZ_2868( 2868 ),
HZ_2950( 2950 ),
HZ_3023( 3023 ),
HZ_3075( 3075 ),
HZ_3107( 3107 ),
HZ_3150( 3150 ),
HZ_3196( 3196 ),
HZ_3333( 3333 ),
HZ_3339( 3339 ),
HZ_3400( 3400 ),
HZ_3496( 3496 ),
HZ_3729( 3729 ),
HZ_4096( 4096 );
private int mFrequency;
private InversionFrequency( int frequency )
{
mFrequency = frequency;
}
public int getFrequency()
{
return mFrequency;
}
}

View File

@@ -0,0 +1,31 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package audio;
public interface SquelchListener
{
/**
* Squelch Control:
*/
public void setSquelch( SquelchState state );
public enum SquelchState
{
UNSQUELCH, SQUELCH;
}
}

322
src/bits/BitSetBuffer.java Normal file
View File

@@ -0,0 +1,322 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package bits;
import java.util.BitSet;
public class BitSetBuffer extends BitSet
{
private static final long serialVersionUID = 1L;
/**
* Logical (ie constructed) size of this bitset, despite the actual size of
* the super bitset that this class is based on
*/
private int mSize = 0;
/**
* Pointer to the next fill index location, when adding bits to this bitset
* one at a time.
*/
private int mPointer = 0;
/**
* Bitset that buffers bits added one at a time, up to the size of the this
* bitset.
*
* Note: the super class bitset behind this class may have a size larger
* that the size parameter specified.
* @param size
*/
public BitSetBuffer( int size )
{
super( size );
mSize = size;
}
/**
* Constructs a bitset buffer and preloads it with the bits contained in
* the bitsToPreload parameter. If the bitsToPreload are longer than the
* size of the bitset, only those bits that fit will be preloaded
*
* @param size
* @param bitsToPreload
*/
public BitSetBuffer( int size, boolean[] bitsToPreload )
{
this( size );
int pointer = 0;
while( !this.isFull() && pointer < bitsToPreload.length )
{
try
{
this.add( bitsToPreload[ pointer ] );
}
catch( BitSetFullException e )
{
e.printStackTrace();
}
pointer++;
}
}
/**
* Constructs a new BitSetBuffer from an existing one
*/
private BitSetBuffer( BitSetBuffer toCopyFrom )
{
this( toCopyFrom.size() );
this.or( toCopyFrom );
this.mPointer = toCopyFrom.pointer();
}
/**
* Current pointer index
*/
public int pointer()
{
return mPointer;
}
/**
* Static method to construct a new BitSetBuffer, preloaded with the bits
* from the preload parameter, and then filled with the bits from the
* second bitsetbuffer parameter.
*
* @param preloadBits - boolean array of bits to be prepended to the new
* bitset
* @param bitsetToAppend - full bitset to be appended to the residual bits array
* @return - new Bitset preloaded with residual bits and new bitset
*/
public static BitSetBuffer merge( boolean[] preloadBits, BitSetBuffer bitsetToAppend )
{
BitSetBuffer returnValue = new BitSetBuffer( preloadBits.length + bitsetToAppend.size(), preloadBits );
int pointer = 0;
while( pointer < bitsetToAppend.size() && !returnValue.isFull() )
{
try
{
returnValue.add( bitsetToAppend.get( pointer ) );
}
catch( BitSetFullException e )
{
e.printStackTrace();
}
pointer++;
}
return returnValue;
}
/**
* Returns a (new) copy of this bitsetbuffer
* @return
*/
public BitSetBuffer copy()
{
return new BitSetBuffer( this );
}
public boolean isFull()
{
return mPointer >= mSize;
}
/**
* Overrides the in-build size() method of the bitset and returns the value
* specified at instantiation. The actual bitset size may be larger than
* this value, and that size is managed by the super class.
*/
@Override
public int size()
{
return mSize;
}
/**
* Clears (sets to false or 0) the bits in this bitset and resets the
* pointer to zero.
*/
@Override
public void clear()
{
this.clear( 0, mSize );
mPointer = 0;
}
/**
* Adds a the bit parameters to this bitset, placing it in the index
* specified by mPointer, and incrementing mPointer to prepare for the next
* call to this method
* @param value
* @throws BitSetFullException - if the size specified at construction is
* exceeded. Invoke full() to determine if the bitset is full either before
* adding a new bit, or after adding a bit.
*/
public void add( boolean value ) throws BitSetFullException
{
if( !isFull() )
{
this.set( mPointer++, value );
}
else
{
throw new BitSetFullException( "bitset is full -- contains " + ( mPointer + 1 ) + " bits" );
}
}
public String toString()
{
StringBuilder sb = new StringBuilder();
for( int x = 0; x < mSize; x++ )
{
sb.append( ( this.get( x ) ? "1" : "0" ) );
}
return sb.toString();
}
/**
* Returns a boolean array from startIndex to end of the bitset
*/
public boolean[] getBits( int startIndex )
{
return getBits( startIndex, mSize - 1 );
}
/**
* Returns a boolean array of the right-most bitCount number of bits
*/
public boolean[] right( int bitCount )
{
return getBits( mSize - bitCount - 1 );
}
/**
* Returns a boolean array representing the bits located from startIndex
* through endIndex
*/
public boolean[] getBits( int startIndex, int endIndex )
{
boolean[] returnValue = null;
if( startIndex >= 0 &&
startIndex < endIndex &&
endIndex < mSize )
{
returnValue = new boolean[ endIndex - startIndex + 1 ];
int bitsetPointer = startIndex;
int returnPointer = 0;
while( bitsetPointer <= endIndex )
{
returnValue[ returnPointer ] = this.get( bitsetPointer );
bitsetPointer++;
returnPointer++;
}
}
return returnValue;
}
/**
* Returns the integer value represented by the bit array
* @param bits - an array of bit positions that will be treated as if they
* were contiguous bits, with index 0 being the MSB and index
* length - 1 being the LSB
* @return - integer value of the bit array
*/
public int getInt( int[] bits )
{
int retVal = 0;
for( int x = 0; x < bits.length; x++ )
{
if( get( bits[ x ] ) )
{
retVal += 1<<( bits.length - 1 - x );
}
}
return retVal;
}
public String getHex( int[] bits, int digitDisplayCount )
{
int value = getInt( bits );
return String.format( "%0" + digitDisplayCount + "X", value );
}
/**
* Returns the integer value represented by the bit range
* @param start - MSB of the integer
* @param end - LSB of the integer
* @return - integer value of the bit range
*/
public int getInt( int start, int end )
{
if( end - start > 32 )
{
throw new IllegalArgumentException( "BitSetBuffer - requested bit "
+ "length [" + ( end - start ) + "] is larger than an "
+ "integer (32 bits)" );
}
int retVal = 0;
for( int x = start; x <= end; x++ )
{
if( get( x ) )
{
retVal += 1<<( end - x );
}
}
return retVal;
}
/**
* Returns the long value represented by the bit range
* @param start - MSB of the long
* @param end - LSB of the long
* @return - long value of the bit range
*/
public long getLong( int start, int end )
{
long retVal = 0;
for( int x = start; x <= end; x++ )
{
if( get( x ) )
{
retVal += 1<<( end - x );
}
}
return retVal;
}
}

View File

@@ -0,0 +1,28 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package bits;
public class BitSetFullException extends Exception
{
private static final long serialVersionUID = 1L;
public BitSetFullException( String text )
{
super( text );
}
}

232
src/bits/MessageFramer.java Normal file
View File

@@ -0,0 +1,232 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package bits;
import java.util.ArrayList;
import java.util.Iterator;
import sample.Broadcaster;
import sample.Listener;
import dsp.SyncDetectListener;
import dsp.SyncDetectProvider;
/**
* MessageFramer - processes bitsets looking for a sync pattern within
* the bits, and then extracts the message, including the sync
* pattern, for a total bit length of messageLength.
*
* Will extract multiple messages simultaneously, for each sync pattern that is
* encountered within the bitset bit stream.
*/
public class MessageFramer implements Listener<Boolean>,
SyncDetectProvider
{
private boolean[] mSyncPattern;
private int mMessageLength;
private SyncDetectListener mSyncDetectListener;
private Broadcaster<BitSetBuffer> mBroadcaster =
new Broadcaster<BitSetBuffer>();
private ArrayList<MessageAssembler> mMessageAssemblers =
new ArrayList<MessageAssembler>();
private ArrayList<MessageAssembler> mCompletedMessageAssemblers =
new ArrayList<MessageAssembler>();
private BitSetBuffer mPreviousBuffer = null;
private SyncPatternMatcher mMatcher;
public MessageFramer( boolean[] syncPattern, int messageLength )
{
mSyncPattern = syncPattern;
mMatcher = new SyncPatternMatcher( syncPattern );
mMessageLength = messageLength;
}
public void dispose()
{
mBroadcaster.dispose();
mCompletedMessageAssemblers.clear();
mMessageAssemblers.clear();
}
@Override
public void receive( Boolean bit )
{
mMatcher.receive( bit );
Iterator<MessageAssembler> it = mMessageAssemblers.iterator();
MessageAssembler assembler;
while( it.hasNext() )
{
assembler = it.next();
/* Dispose and remove any completed assemblers */
if( assembler.complete() )
{
assembler.dispose();
it.remove();
}
/* Otherwise, send them the bit */
else
{
assembler.receive( bit );
}
}
/* Check for sync match and add new message assembler */
if( mMatcher.matches() )
{
addMessageAssembler( new MessageAssembler( mMessageLength, mSyncPattern ) );
/* Notify any sync detect listener(s) */
if( mSyncDetectListener != null )
{
mSyncDetectListener.syncDetected();
}
}
}
/**
* Causes all messages currently under assembly to be forcibly
* sent (ie flushed) to all registered message listeners, and
* subsequently, all assemblers to be deleted
*/
public void flush()
{
for( MessageAssembler assembler: mMessageAssemblers )
{
assembler.flush();
}
}
@Override
public void setSyncDetectListener( SyncDetectListener listener )
{
mSyncDetectListener = listener;
}
/**
* Allow a message listener to register with this framer to receive
* all framed messages
*/
public void addMessageListener( Listener<BitSetBuffer> listener )
{
mBroadcaster.addListener( listener );
}
public void removeMessageListener( Listener<BitSetBuffer> listener )
{
mBroadcaster.removeListener( listener );
}
/*
* Adds a message assembler to receive bits from the bit stream
*/
private void addMessageAssembler( MessageAssembler assembler )
{
mMessageAssemblers.add( assembler );
}
private void removeMessageAssembler( MessageAssembler assembler )
{
mMessageAssemblers.remove( assembler );
}
/**
* Assembles a binary message, starting with the initial fill of the
* identified sync pattern, and every bit thereafter. Once the accumulated
* bits equal the message length, the message is sent and the assembler
* flags itself as complete.
*
* By design, multiple message assemblers can exist at the same time, each
* assembling different, overlapping potential messages
*/
private class MessageAssembler implements Listener<Boolean>
{
BitSetBuffer mMessage;
boolean mComplete = false;
MessageAssembler( int messageLength )
{
mMessage = new BitSetBuffer( messageLength );
}
MessageAssembler( int messageLength, boolean[] initialFill )
{
this( messageLength );
/* Pre-load the message with the sync pattern */
for( int x = 0; x < initialFill.length; x++ )
{
receive( initialFill[ x ] );
}
}
public void dispose()
{
mMessage = null;
}
@Override
/**
* Receives one bit at a time, and assembles them into a message
*/
public void receive( Boolean bit )
{
try
{
mMessage.add( bit );
}
catch( BitSetFullException e )
{
e.printStackTrace();
}
/* Once our message is complete (ie full), send it to all registered
* message listeners, and set complete flag so for auto-removal */
if( mMessage.isFull() )
{
mComplete = true;
flush();
}
}
/**
* Flushes/Sends the current message, or partial message, and sets
* complete flag to true, so that we can be auto-removed
*/
public void flush()
{
mBroadcaster.receive( mMessage );
mComplete = true;
}
/**
* Flag to indicate when this assembler has received all of the bits it
* is looking for (ie message length), and should then be removed from
* receiving any more bits
*/
public boolean complete()
{
return mComplete;
}
}
}

118
src/bits/SyncPattern.java Normal file
View File

@@ -0,0 +1,118 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package bits;
public enum SyncPattern
{
/* Revs (0xAA) and Sync (0x7650) = 01010 0111011001010000 */
FLEETSYNC1( new boolean[]
{
false, true, false, true, false, //end of revs
false, true, true, true, //0111 0x7
false, true, true, false, //0110 0x6
false, true, false, true, //0101 0x5
false, false, false, false //0000 0x0
} ),
/* Revs (0x0A) and Sync (0x23EB) = 10101 0010001111101011 */
FLEETSYNC2( new boolean[]
{
false, true, false, true, false, //End of bit revs
false, false, true, false, //0010 0x2
false, false, true, true, //0011 0x3
true, true, true, false, //1110 0xE
true, false, true, true //1011 0xB
} ),
/**
* Note: we use a truncated portion of the NRZ-I encoded sync pattern.
* The truncated version seems to work well enough for detecting the burst,
* while limiting falsing.
*
* Sync: .... .... 0000 0111 0000 1001 0010 1010 0100 0100 0110 1111
* Rev & Sync: ...1 0101 0000 0111 0000 1001 0010 1010 0100 0100 0110 1111
* NRZ-I: .... 1111 1000 0100 1000 1101 1011 1111 0110 0110 0101 1000
* This: .... .... 1000 0100 1000 1101 1011 1111 .... .... .... ....
*/
/* Sync (0x07092A446F) = 0000011100001001001010100100010001101111 */
MDC1200( new boolean[]
{
false, false, false, false,//0000 0x0
false, true, true, true, //0111 0x7
false, false, false, false,//0000 0x0
true, false, false, true, //1001 0x9
false, false, true, false, //0010 0x2
true, false, true, false, //1010 0xA
false, true, false, false, //0100 0x4
false, true, false, false, //0100 0x4
false, true, true, false, //0110 0x6
true, true, true, true //1111 0xF
} ),
/* Revs (0xA) and Sync(0xA4D7) = 1010 1100010011010111 */
MPT1327_CONTROL( new boolean[]
{
true, false, true, false, //Includes 4 of 16 rev bits
// false, true, false, true, //Includes 4 of 16 rev bits
true, true, false, false, //1100 0xA
false, true, false, false, //0100 0x4
true, true, false, true, //1101 0xD
false, true, true, true //0111 0x7
}),
/* Revs (0xA) and Sync(0x3B28) = 1010 0011101100101000 */
MPT1327_TRAFFIC( new boolean[]
{
true, false, true, false, //1010 Includes 4 of 16 rev bits
// false, true, false, true, //1010 Includes 4 of 16 rev bits
false, false, true, true, //0011 0x3
true, false, true, true, //1011 0xB
false, false, true, false, //0010 0x2
true, false, false, false //1000 0x8
}),
/* Sync (0x158) = 1101011000 */
PASSPORT( new boolean[]
{
true, //0001 0x1
false, true, false, true, //0101 0x5
true, false, false, false //1000 0x8
} ),
LTR_STANDARD_OSW( new boolean[]
{
true,false,true,false,true,true,false,false,false
} ),
LTR_STANDARD_ISW( new boolean[]
{
false, true, false, true,false, false, true, true, true
} );
boolean[] mBits;
private SyncPattern( boolean[] bits )
{
mBits = bits;
}
public boolean[] getPattern()
{
return mBits;
}
}

View File

@@ -0,0 +1,74 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package bits;
/**
* Sync pattern matcher.
*
* Note: works for sync patterns up to 63 bits (integer size - 1 ) long.
* If a 64 bit or larger sync pattern is applied, then the wrapping feature
* of the Integer.rotate methods will wrap the MSB around to the LSB and
* corrupt the matching value.
*
*/
public class SyncPatternMatcher
{
private long mBits = 0;
private long mMask = 0;
private long mSync = 0;
public SyncPatternMatcher( boolean[] syncPattern )
{
//Setup a bit mask of all ones the length of the sync pattern
mMask = (long)( ( Math.pow( 2, syncPattern.length ) ) - 1 );
//Convert the sync bits into a long value for comparison
for( int x = 0; x < syncPattern.length; x++ )
{
if( syncPattern[ x ] )
{
mSync += 1l << ( syncPattern.length - 1 - x );
}
}
}
public void receive( boolean bit )
{
//Left shift the previous value
mBits = Long.rotateLeft( mBits, 1 );
//Apply the mask to erase the previous MSB
mBits &= mMask;
//Add in the new bit
if( bit )
{
mBits += 1;
}
}
/**
* Indicates if the most recently received bit sequence matches the
* sync pattern
*/
public boolean matches()
{
return ( mBits == mSync );
}
}

View File

@@ -0,0 +1,107 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular Buffer - implements a circular buffer with a method to get the
* current head of the buffer, and put a new value in its place at the same
* time
*
* Also provides averaging over the elements in the buffer
*/
public class AveragingCircularBooleanBuffer {
private boolean[] mBuffer;
private int mBufferPointer;
public AveragingCircularBooleanBuffer( int length )
{
mBuffer = new boolean[ length ];
//Preload the array with false values
Arrays.fill( mBuffer, false );
}
public boolean get( boolean newValue )
{
//Fetch current boolean value
boolean retVal = mBuffer[ mBufferPointer ];
//Load the new value into the buffer
put( newValue );
return retVal;
}
/**
* Loads the newValue into this buffer and adjusts the buffer pointer
* to prepare for the next get/put cycle
*/
private void put( boolean newValue )
{
//Store the new value to the buffer
mBuffer[ mBufferPointer ] = newValue;
//Increment the buffer pointer
mBufferPointer++;
//Wrap the buffer pointer around to 0 when necessary
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
}
/**
* Loads the newValue into the buffer, calculates the average
* and returns that average from this method
*
* This effectively performs low-pass filtering
*/
public boolean getAverage( boolean newValue )
{
//Load the new value into the buffer
put( newValue );
int trueCount = 0;
for( int x = 0; x < mBuffer.length; x++ )
{
if( mBuffer[ x ] )
{
trueCount++;
}
}
/**
* If the number of true values in the buffer is
* more than half, return true, otherwise, false
*/
if( trueCount > (int)( mBuffer.length / 2 ) )
{
return true;
}
else
{
return false;
}
}
}

View File

@@ -0,0 +1,33 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public class BufferOverflowException extends Exception
{
private static final long serialVersionUID = 1L;
public BufferOverflowException( String text )
{
super( text );
}
public BufferOverflowException( String text, Throwable exc )
{
super( text, exc );
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface BufferOverflowListener
{
public void overflow( Object source, String message );
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public class ByteArrayDelayBuffer
{
private int mBufferSize;
private byte[][] mBuffer = null;
private int mBufferPointer = 0;
/**
* Implements a delay buffer for byte arrays. As a new byte[] is placed
* into the buffer, the oldest byte[] is returned
* @param bufferSize - number of byte arrays to buffer
*/
public ByteArrayDelayBuffer( int bufferSize )
{
mBufferSize = bufferSize;
}
/**
* Inserts new bytes into the buffer
*
* @return - oldest byte[] from the buffer, or null if the buffer is not
* yet full
*/
public byte[] get( byte[] bytes )
{
if( mBuffer == null )
{
mBuffer = new byte[ mBufferSize ][ bytes.length ];
}
byte[] returnBytes = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer++ ] = bytes;
if( mBufferPointer >= mBufferSize )
{
mBufferPointer = 0;
}
return returnBytes;
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface ByteArrayListener
{
public void receive( byte[] data );
}

View File

@@ -0,0 +1,25 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
public interface ByteBufferListener
{
public void receive( ByteBuffer buffer );
}

View File

@@ -0,0 +1,33 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface ByteBufferProvider
{
/**
* Adds a sample listener to receive samples
*/
public void addByteBufferListener( ByteBufferListener listener );
/**
* Removes the sample listener, if it is currently registered as a listener
*/
public void removeByteBufferListener( ByteBufferListener listener );
}

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.util.Enumeration;
import sample.complex.ComplexSample;
/**
* Provides a complex sample enumeration wrapper around a byte array containing
* interleaved byte-length I & Q sample values in the range of 0 - 255, converting
* those samples into complex samples with value range of -128 to 0 to 127.
*/
public class ComplexByteBuffer implements Enumeration<ComplexSample>
{
private static float[] mValues;
/**
* Creates a lookup table that converts the 8-bit valued range from 0 - 255
* into scaled float values of -128 to 0 to 127
*/
static
{
mValues = new float[ 256 ];
float scale = (float)( 1.0f / 127.0f );
for( int x = 0; x < 256; x++ )
{
mValues[ x ] = (float)( x - 128 ) * scale;
}
}
private ByteBuffer mBytes;
// private byte[] mBytes;
// private int mPointer;
public ComplexByteBuffer( byte[] bytes )
{
mBytes = ByteBuffer.wrap( bytes );
// mBytes = bytes;
// mPointer = 0;
}
public byte[] toArray()
{
// return mBytes;
return mBytes.array();
}
/**
* Indicates if there are more complex samples remaining.
*/
@Override
public boolean hasMoreElements()
{
// return mPointer < mBytes.length;
return mBytes.hasRemaining();
}
/**
* Returns the next complex sample.
*
* Note: does not check for buffer overrun. Use the hasMoreElements()
* method to ensure you do not read past the end of the buffer.
*/
@Override
public ComplexSample nextElement()
{
// return new ComplexSample( mValues[ ( mBytes[ mPointer++ ] & 0xFF ) ],
// mValues[ ( mBytes[ mPointer++ ] & 0xFF ) ] );
return new ComplexSample( mValues[ ( mBytes.get() & 0xFF ) ],
mValues[ ( mBytes.get() & 0xFF ) ] );
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface ComplexByteBufferListener
{
public void receive( ComplexByteBuffer buffer );
}

View File

@@ -0,0 +1,90 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
import sample.complex.ComplexSample;
/**
* Circular sample buffer - allocates a buffer and stores samples in a circular
* fashion, overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
*/
public class ComplexCircularBuffer
{
ComplexSample[] mBuffer;
int mBufferPointer = 0;
public ComplexCircularBuffer( int size )
{
mBuffer = new ComplexSample[ size ];
Arrays.fill( mBuffer, new ComplexSample( 1.0f, 1.0f ) );
}
/**
* Returns the sample currently pointed to in the buffer and stores the
* new sample in its place
* @param sample
* @return
*/
public ComplexSample get( ComplexSample sample )
{
ComplexSample retVal = mBuffer[ mBufferPointer ];
put( sample );
return retVal;
}
public void put( ComplexSample sample )
{
mBuffer[ mBufferPointer ] = sample;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
}
public ComplexSample[] get( int count )
{
ComplexSample[] samples = new ComplexSample[ count ];
int tempCounter = mBufferPointer;
for( int x = 0; x < count; x++ )
{
samples[ x ] = mBuffer[ tempCounter ];
tempCounter++;
if( tempCounter > mBuffer.length - 1 )
{
tempCounter = 0;
}
}
return samples;
}
}

View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import sample.complex.ComplexSample;
public class ComplexSampleBufferAssembler
{
private ByteBuffer mByteBuffer;
private int mSizeInBytes;
public ComplexSampleBufferAssembler( int size )
{
mSizeInBytes = size * 4;
//Allocate a byte buffer with 4 bytes per sample (ie 2 x 16-bit samples)
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
/**
* Load the sample's bytes, left then right, little endian, into the
* backing byte array
*/
public void put( ComplexSample sample )
{
mByteBuffer.putShort( (short)sample.left() );
mByteBuffer.putShort( (short)sample.right() );
}
/**
* Indicates if there is room for more samples in the buffer, or if it is full
*/
public boolean hasRemaining()
{
return mByteBuffer.hasRemaining();
}
/**
* Returns a copy of the byte array backing this buffer
*/
public ByteBuffer get()
{
return ByteBuffer.wrap( Arrays.copyOf( mByteBuffer.array(), mSizeInBytes ) );
}
/**
* Clear the bytes from the underlying buffer and reset the pointer to 0.
*/
public void clear()
{
mByteBuffer.clear();
}
}

View File

@@ -0,0 +1,87 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import sample.complex.ComplexSample;
/**
* Implements a FIFO circular buffer for complex samples that provides access
* to each complex sample by index number, where index 0 is the newest/latest
* complex sample and index (length - 1) is the oldest sample in the buffer.
*/
public class ComplexTappedCircularBuffer
{
private ComplexSample[] mBuffer;
private int mBufferPointer = 0;
public ComplexTappedCircularBuffer( int length )
{
mBuffer = new ComplexSample[ length ];
//Pre-load the buffer with 0-valued samples
for( int x = 0; x < length; x++ )
{
mBuffer[ x ] = new ComplexSample( 0, 0 );
}
}
/**
* Adds the sample to the buffer and removes the oldest sample
* @param sample
*/
public void add( ComplexSample sample )
{
mBuffer[ mBufferPointer++ ] = sample;
//Reset the buffer pointer once it points past the end of the buffer
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
}
/**
* Retrieves a sample currently in the buffer by index position.
*
* Index 0 is the newest/latest sample in the buffer and index (length - 1)
* is the oldest.
*
* Note: the buffer is preloaded with complex samples of 0,0 value.
*
* @param index where 0 is the newest/latest sample and length-1 is the oldest
* @return complex sample from the buffer.
* @throws ArrayIndexOutOfBoundsException if you attempt to access a sample
* outside of the buffer size
*/
public ComplexSample get( int index )
{
/* Since the samples are stored in a forward fashion, we have to access
* the samples in reverse to comply with the access contract, where
* index 0 is the newest and index (length -1) is the oldest, all
* relative to the current buffer pointer */
int pointer = mBuffer.length - 1 + mBufferPointer - index;
if( pointer >= mBuffer.length )
{
pointer -= mBuffer.length;
}
return mBuffer[ pointer ];
}
}

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.ArrayList;
import java.util.Arrays;
public class FloatArrayCircularAveragingBuffer
{
private ArrayList<float[]> mBuffer;
private int mBufferPointer;
private int mBufferSize;
private float[] mAverage;
public FloatArrayCircularAveragingBuffer( int bufferSize )
{
mBufferSize = bufferSize;
mBuffer = new ArrayList<float[]>();
}
/**
* Replaces the oldest float array element in the buffer with this new
* float array element, and then returns the average of the buffer contents
* with the newElement values included in the average array
*/
public float[] get( float[] newElement )
{
/**
* If we've never setup the average array, or the newElements length is
* different than what we've been processing, reset the buffer & averages
*/
if( mAverage == null || mAverage.length != newElement.length )
{
reset( newElement.length );
}
float[] oldElement = mBuffer.get( mBufferPointer );
for( int x = 0; x < newElement.length; x++ )
{
/**
* Change the current average value in each array element by the
* difference of the new element minus the old element, divided
* by the buffer size ... average it
*/
mAverage[ x ] +=
( ( newElement[ x ] - oldElement[ x ] ) / mBufferSize );
}
mBuffer.set( mBufferPointer, newElement );
mBufferPointer++;
if( mBufferPointer >= mBufferSize )
{
mBufferPointer = 0;
}
return mAverage;
}
/**
* Clears buffer and average and fills buffer with zero-valued float arrays
*/
private void reset( int arrayLength )
{
mAverage = new float[ arrayLength ];
Arrays.fill( mAverage, 0.0f );
mBuffer.clear();
mBufferPointer = 0;
float[] emptyArray = new float[ arrayLength ];
Arrays.fill( emptyArray, 0.0f );
for( int x = 0; x < mBufferSize; x++ )
{
mBuffer.add( emptyArray );
}
}
}

View File

@@ -0,0 +1,57 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public class FloatAveragingBuffer
{
private float[] mBuffer;
private float mAverage = 0.0f;
private int mBufferSize;
private int mBufferPointer;
public FloatAveragingBuffer( int size )
{
mBufferSize = size;
mBuffer = new float[ size ];
}
public float get( float newValue )
{
float oldValue = mBuffer[ mBufferPointer ];
if( Float.isInfinite( newValue ) || Float.isNaN( newValue ) )
{
mAverage = mAverage - ( oldValue / mBufferSize );
mBuffer[ mBufferPointer++ ] = 0.0f;
}
else
{
mAverage = mAverage - ( oldValue / mBufferSize ) + ( newValue / mBufferSize );
mBuffer[ mBufferPointer++ ] = newValue;
}
if( mBufferPointer >= mBufferSize )
{
mBufferPointer = 0;
}
return mAverage;
}
}

View File

@@ -0,0 +1,70 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
import sample.Listener;
/**
* Assembles single samples into sample blocks (ie arrays) for broadcast to
* registered SampleBlockListeners
*/
public class FloatBufferAssembler implements Listener<Float>
{
private Float[] mFloatBuffer;
private int mBufferSize;
private int mBufferPointer = 0;
private Listener<Float[]> mListener;
public FloatBufferAssembler( int bufferSize )
{
mBufferSize = bufferSize;
mFloatBuffer = new Float[ mBufferSize ];
}
/**
* Stores received samples in the sample block and manages the storage
* pointer. Sends sample blocks when full.
*/
@Override
public void receive( Float sample )
{
mFloatBuffer[ mBufferPointer++ ] = sample;
if( mBufferPointer == mBufferSize )
{
if( mListener != null )
{
mListener.receive( Arrays.copyOf( mFloatBuffer, mBufferSize ) );
}
mBufferPointer = 0;
}
}
/**
* Adds a new sampleblock listener to receive sample blocks as they are
* assembled from the sample stream
*/
public void setListener( Listener<Float[]> listener )
{
mListener = listener;
}
}

View File

@@ -0,0 +1,110 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular sample buffer - allocates a buffer and stores samples in a circular
* fashion, overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Produces no output. Obtain the average buffer value on-demand via the
* getAverage() method
*/
public class FloatCircularAveragingBuffer
{
private float[] mBuffer;
private int mBufferPointer = 0;
private int mSampleCountForAveraging;
private int mCurrentSampleCount = 0;
private float mAverage = 0.0f;
public FloatCircularAveragingBuffer( int size, int sampleCountForAveraging )
{
mBuffer = new float[ size ];
mSampleCountForAveraging = sampleCountForAveraging;
Arrays.fill( mBuffer, 0.0f );
}
/**
* Convenience wrapper to throw away to put the new sample and throwaway
* the oldest sample
*/
public void put( float newestSample )
{
get( newestSample );
}
/**
* Loads the newest sample into the buffer and returns the oldest sample
*/
public float get( float newestSample )
{
float oldestSample = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = newestSample;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
mCurrentSampleCount++;
if( mCurrentSampleCount >= mSampleCountForAveraging )
{
calculateAverage();
mCurrentSampleCount = 0;
}
return oldestSample;
}
/**
* Calculates the average of the maximum and minimum values present in
* the buffer
*/
private void calculateAverage()
{
float min = mBuffer[ 0 ];
float max = mBuffer[ 0 ];
for( int x = 0; x < mBuffer.length; x++ )
{
if( mBuffer[ x ] < min )
{
min = mBuffer[ x ];
}
if( mBuffer[ x ] > max )
{
max = mBuffer[ x ];
}
}
mAverage = (float)( ( min + max ) / 2.0f );
}
public float getAverage()
{
return mAverage;
}
}

View File

@@ -0,0 +1,68 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular sample buffer - stores samples in a circular buffer
* overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Continuously calculates the average of the samples in the buffer, with the
* average available from the average() method.
*/
public class FloatCircularAveragingBuffer2
{
private float[] mBuffer;
private int mBufferPointer = 0;
private float mAverage = 0.0f;
public FloatCircularAveragingBuffer2( int size )
{
mBuffer = new float[ size ];
Arrays.fill( mBuffer, 0.0f );
}
/**
* Loads the newest sample into the buffer and returns the oldest sample
*/
public float get( float newestSample )
{
float oldestSample = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = newestSample;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
mAverage = mAverage - ( oldestSample / mBuffer.length ) +
( newestSample / mBuffer.length );
return oldestSample;
}
public float average()
{
return mAverage;
}
}

View File

@@ -0,0 +1,108 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.util.Arrays;
/**
* Circular sample buffer - allocates a buffer and stores samples in a circular
* fashion, overwriting older samples with newly arrived samples. Initially
* fills buffer with 0-valued samples
*
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
* @author denny
*
*/
public class FloatCircularBuffer
{
float[] mBuffer;
int mBufferPointer = 0;
public FloatCircularBuffer( int size )
{
mBuffer = new float[ size ];
Arrays.fill( mBuffer, (float)0.0 );
}
/**
* Puts the new value into the buffer and returns the oldest buffer value
* that it replaced
* @param newValue
* @return
*/
public float get( float newValue )
{
float oldestSample = mBuffer[ mBufferPointer ];
mBuffer[ mBufferPointer ] = newValue;
mBufferPointer++;
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
return oldestSample;
}
/**
* Convenience method to put a new value in the buffer, while discarding
* the old value
*/
public void put( float newValue )
{
get( newValue );
}
/**
* Returns an array of arraySize, loaded with sampleCount of the
* oldest samples, loaded into the array starting at index 0.
*
* This is useful for fetching an array filled half way with samples to
* use in FFT processing.
* @param arraySize - size of the array (must be larger than sampleCount)
* @param sampleCount - number of the oldest samples in the buffer to load
* @return
*/
public float[] get( int arraySize, int sampleCount )
{
float[] samples = new float[ arraySize ];
if( arraySize > sampleCount )
{
int tempCounter = mBufferPointer;
for( int x = 0; x < sampleCount; x++ )
{
samples[ x ] = mBuffer[ tempCounter ];
tempCounter++;
if( tempCounter > mBuffer.length )
{
tempCounter = 0;
}
}
}
return samples;
}
}

View File

@@ -0,0 +1,66 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
public class FloatSampleBuffer
{
private static final long serialVersionUID = 1L;
private int mSize;
private float[] mBuffer;
private int mBufferPointer = 0;
public FloatSampleBuffer( int size )
{
super();
mBuffer = new float[ size ];
}
public void put( float sample )
{
if( !isFull() )
{
mBuffer[ mBufferPointer++ ] = sample;
}
}
public void reset()
{
mBufferPointer = 0;
}
public boolean isFull()
{
return mBufferPointer >= mBuffer.length;
}
public byte[] getBytes()
{
ByteBuffer bb = ByteBuffer.allocate( mBuffer.length * 2 );
for( int x = 0; x < mBuffer.length; x++ )
{
bb.putShort( ((Float)mBuffer[ x ]).shortValue() );
}
return bb.array();
}
}

View File

@@ -0,0 +1,72 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class FloatSampleBufferAssembler
{
private ByteBuffer mByteBuffer;
private int mSizeInBytes;
public FloatSampleBufferAssembler( int size )
{
mSizeInBytes = size * 2;
//Allocate a byte buffer with 2 bytes per sample (ie 1 x 16-bit sample)
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
/**
* Load the sample's bytes, left then right, little endian, into the
* backing byte array
*/
public void put( float sample )
{
mByteBuffer.putShort( Float.valueOf( sample ).shortValue() );
}
/**
* Indicates if there is room for more samples in the buffer, or if it is full
*/
public boolean hasRemaining()
{
return mByteBuffer.hasRemaining();
}
/**
* Returns a copy of the byte array backing this buffer
*/
public ByteBuffer get()
{
return mByteBuffer;
// return ByteBuffer.wrap( Arrays.copyOf( mByteBuffer.array(), mSizeInBytes ) );
}
/**
* Clear the bytes from the underlying buffer and reset the pointer to 0.
*/
public void reset()
{
// mByteBuffer.clear();
mByteBuffer = ByteBuffer.allocate( mSizeInBytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
/**
* Implements a FIFO circular buffer for floats that provides access
* to each sample by index number, where index 0 is the newest/latest
* complex sample and index (length - 1) is the oldest sample in the buffer.
*/
public class FloatTappedCircularBuffer
{
private Float[] mBuffer;
private int mBufferPointer = 0;
public FloatTappedCircularBuffer( int length )
{
mBuffer = new Float[ length ];
//Pre-load the buffer with 0-valued samples
for( int x = 0; x < length; x++ )
{
mBuffer[ x ] = Float.valueOf( 0.0f );
}
}
/**
* Adds the sample to the buffer and removes the oldest sample
* @param sample
*/
public void add( Float sample )
{
mBuffer[ mBufferPointer++ ] = sample;
//Reset the buffer pointer once it points past the end of the buffer
if( mBufferPointer >= mBuffer.length )
{
mBufferPointer = 0;
}
}
/**
* Retrieves a sample currently in the buffer by index position.
*
* Index 0 is the newest/latest sample in the buffer and index (length - 1)
* is the oldest.
*
* Note: the buffer is preloaded with complex samples of 0,0 value.
*
* @param index where 0 is the newest/latest sample and length-1 is the oldest
* @return complex sample from the buffer.
* @throws ArrayIndexOutOfBoundsException if you attempt to access a sample
* outside of the buffer size
*/
public Float get( int index )
{
/* Since the samples are stored in a forward fashion, we have to access
* the samples in reverse to comply with the access contract, where
* index 0 is the newest and index (length -1) is the oldest, all
* relative to the current buffer pointer */
int pointer = mBuffer.length - 1 + mBufferPointer - index;
if( pointer >= mBuffer.length )
{
pointer -= mBuffer.length;
}
return mBuffer[ pointer ];
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import sample.Broadcaster;
import sample.Listener;
public class FloatToByteBufferAssembler implements Listener<Float>
{
private Broadcaster<ByteBuffer> mBroadcaster = new Broadcaster<ByteBuffer>();
private int mBufferSize = 0;
private ByteBuffer mBuffer;
public FloatToByteBufferAssembler( int bufferSize )
{
mBufferSize = bufferSize;
resetBuffer();
}
public void addByteBufferListener( Listener<ByteBuffer> listener )
{
mBroadcaster.addListener( listener );
}
public void removeByteBufferListener( Listener<ByteBuffer> listener )
{
mBroadcaster.removeListener( listener );
}
private void resetBuffer()
{
mBuffer = ByteBuffer.allocate( mBufferSize );
mBuffer.order( ByteOrder.BIG_ENDIAN );
}
@Override
public void receive( Float sample )
{
mBuffer.putShort( Float.valueOf( sample ).shortValue() );
if( mBuffer.position() >= mBufferSize )
{
//Buffer is full ... send it
mBroadcaster.receive( mBuffer );
//Reset the buffer
resetBuffer();
}
}
}

View File

@@ -0,0 +1,53 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Enumeration;
import sample.complex.ComplexSample;
public class ShortComplexByteBuffer implements Enumeration<ComplexSample>
{
private ByteBuffer mByteBuffer;
public ShortComplexByteBuffer( byte[] bytes, ByteOrder endianness )
{
mByteBuffer = ByteBuffer.wrap( bytes );
mByteBuffer.order( endianness );
}
public byte[] array()
{
return mByteBuffer.array();
}
@Override
public boolean hasMoreElements()
{
return mByteBuffer.hasRemaining();
}
@Override
public ComplexSample nextElement()
{
return new ComplexSample( (float)mByteBuffer.getShort(),
(float)mByteBuffer.getShort() );
}
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Enumeration;
import sample.complex.ComplexSample;
import source.mixer.MixerChannel;
public class StereoByteBuffer implements Enumeration<ComplexSample>
{
private ByteBuffer mByteBuffer;
public StereoByteBuffer( byte[] bytes, int frames )
{
mByteBuffer = ByteBuffer.wrap( bytes );
mByteBuffer.order( ByteOrder.LITTLE_ENDIAN );
}
public byte[] array()
{
return mByteBuffer.array();
}
public ByteBuffer getChannel( MixerChannel channel )
{
return StereoToMonoByteBufferConverter.getChannel( mByteBuffer, channel );
}
@Override
public boolean hasMoreElements()
{
return mByteBuffer.hasRemaining();
}
@Override
public ComplexSample nextElement()
{
return new ComplexSample( (float)mByteBuffer.getShort(),
(float)mByteBuffer.getShort() );
}
}

View File

@@ -0,0 +1,24 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface StereoByteBufferListener
{
public void receive( StereoByteBuffer buffer );
}

View File

@@ -0,0 +1,32 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
public interface StereoByteBufferProvider
{
/**
* Adds a sample listener to receive samples
*/
public void addStereoByteBufferListener( StereoByteBufferListener listener );
/**
* Removes the sample listener, if it is currently registered as a listener
*/
public void removeStereoByteBufferListener( StereoByteBufferListener listener );
}

View File

@@ -0,0 +1,58 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import source.mixer.MixerChannel;
public class StereoToMonoByteBufferConverter
{
public static ByteBuffer getChannel( ByteBuffer buffer, MixerChannel channel )
{
byte[] channelBuffer = new byte[ buffer.capacity() / 2 ];
int channelBufferPointer = 0;
if( channel == MixerChannel.RIGHT )
{
//throw away the first two bytes
buffer.get();
buffer.get();
}
while( channelBufferPointer < channelBuffer.length )
{
if( buffer.hasRemaining() )
{
channelBuffer[ channelBufferPointer++ ] = buffer.get();
channelBuffer[ channelBufferPointer++ ] = buffer.get();
}
if( buffer.hasRemaining() )
{
buffer.get();
buffer.get();
}
}
return ByteBuffer.wrap( channelBuffer ).order( ByteOrder.LITTLE_ENDIAN );
}
}

View File

@@ -0,0 +1,177 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.tree.DefaultMutableTreeNode;
public class BaseNode extends DefaultMutableTreeNode
implements Comparable<BaseNode>
{
private static final long serialVersionUID = 1L;
/**
* Model backing the JTree and nodes. Since we're primarily interacting
* with the model via JTree tree nodes via context menus, injecting a
* reference to the model facilitates nodal access to the model's methods
*/
protected ConfigurationControllerModel mModel = null;
/**
* Implements a base node that has a reference to the underlying
* tree data model to facilitate tree node operations from nodal context
* menus.
*/
public BaseNode( Object object )
{
super( object );
}
/**
* Override this method to return a custom icon for the node
* @return
*/
public String getIconPath()
{
return null;
}
public String toString()
{
if( getUserObject() != null )
{
return (String)getUserObject();
}
else
{
return "SDRTrunk";
}
}
public JPanel getEditor()
{
return new EmptyEditor();
}
/**
* Comparator to support nodal sorting/ordering
*/
@Override
public int compareTo( BaseNode node )
{
return toString().compareTo( node.toString() );
}
/**
* This method only needs to be called once on the root node and all nodes
* in the tree will then have a reference to the model via getModel()
*/
public void setModel( ConfigurationControllerModel model )
{
mModel = model;
}
/**
* Returns reference to the SystemTreeModel. Only ConfigurableNode types
* or children are allowed in this tree, so this method assumes that the
* node or parent is of ConfigurableNode class or subclass.
*
* Reference to the model is required to enable node context operations
* like adding/deleting/stopping/starting.
*/
public ConfigurationControllerModel getModel()
{
if( mModel == null )
{
return ((BaseNode)getParent()).getModel();
}
else
{
return mModel;
}
}
/**
* Supports a context menu for any children of the BaseNode. Override the
* method in the child node to provide a custom context menu for that node.
*/
public JPopupMenu getContextMenu()
{
return null;
}
/**
* Invokes a recursive delete() on all children to perform any cleanup
* operations prior to deleting. Override this method to perform cleanup
* operations specific to the node. Remember to also either invoke
* super.delete(), or specifically call .delete() on any children of the
* node with the custom delete method.
*/
public void delete()
{
for( int x = 0; x < getChildCount(); x++ )
{
BaseNode node = (BaseNode)getChildAt( x );
//Tell the node to delete its children
node.delete();
//Delete the child node
getModel().deleteNode( node );
}
}
public void show()
{
getModel().showNode( this );
}
public void refresh()
{
getModel().nodeChanged( this );
}
public void sort()
{
List<BaseNode> nodesToSort = new ArrayList<BaseNode>();
while( children().hasMoreElements() )
{
BaseNode child = (BaseNode)children().nextElement();
nodesToSort.add( child );
getModel().removeNodeFromParent( child );
}
if( !nodesToSort.isEmpty() )
{
Collections.sort( nodesToSort );
for( BaseNode node: nodesToSort )
{
getModel().insertNodeInto( node, this, getChildCount() );
}
}
}
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
public abstract class ConfigurableNode extends BaseNode
{
private static final long serialVersionUID = 1L;
public ConfigurableNode( Object object )
{
super( object );
}
/**
* Saves changes to the node
*/
public void save()
{
getModel().getResourceManager().getPlaylistManager().save();
BaseNode parent = (BaseNode)getParent();
if( parent instanceof ConfigurableNode )
{
((ConfigurableNode)parent).sort();
}
}
}

View File

@@ -0,0 +1,280 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import map.IconManager;
import playlist.PlaylistNode;
import source.config.SourceConfigTuner;
import source.tuner.Tuner;
import source.tuner.TunerGroupNode;
import source.tuner.TunerNode;
import source.tuner.TunerSelectionListener;
import controller.channel.Channel;
import controller.channel.ChannelListener;
import controller.channel.ChannelNode;
import controller.site.Site;
import controller.system.System;
import controller.system.SystemListNode;
import controller.system.SystemNode;
import decode.DecoderType;
import decode.config.DecodeConfigFactory;
public class ConfigurationControllerModel extends DefaultTreeModel
{
private static final long serialVersionUID = 1L;
private JTree mTree;
private ResourceManager mResourceManager;
private ArrayList<ChannelListener> mChannelConfigChangeListeners =
new ArrayList<ChannelListener>();
private ArrayList<TunerSelectionListener> mTunerSelectionListeners =
new ArrayList<TunerSelectionListener>();
private PlaylistNode mPlaylistNode;
private TunerGroupNode mTunerGroupNode;
private IconManager mIconManagerFrame;
/**
* Implements a merged system controller and (tree) model. The user will
* primarily interact with the system nodes via the tree view, so from a
* design perspective, the model and the control are necessarily merged to
* work well with the JTree as the system view.
*/
public ConfigurationControllerModel( ResourceManager resourceManager )
{
super( new BaseNode( null ) );
mResourceManager = resourceManager;
/**
* Give the root node a reference to this model, so that all nodes can
* invoke add/delete operations on the tree via context menu
*/
((BaseNode)getRoot()).setModel( this );
}
public JTree getTree()
{
return mTree;
}
public void showIconManager()
{
if( mIconManagerFrame == null )
{
mIconManagerFrame = new IconManager( mResourceManager, mTree );
mResourceManager.getSettingsManager().addListener( mIconManagerFrame );
}
if( !mIconManagerFrame.isVisible() )
{
mIconManagerFrame.setVisible( true );
}
mIconManagerFrame.toFront();
}
/**
* init() gets invoked manually/externally, after all of the references
* are established in the constructor
*/
public void init()
{
/**
* Add the root tuner group node
*/
mTunerGroupNode = new TunerGroupNode();
insertNodeInto( mTunerGroupNode, (MutableTreeNode)root, 0 );
addTuners( mTunerGroupNode );
/**
* Add the playlist node
*/
mPlaylistNode = new PlaylistNode();
insertNodeInto( mPlaylistNode, (MutableTreeNode)root, 1 );
mPlaylistNode.loadPlaylist();
}
public void showNode( DefaultMutableTreeNode node )
{
if( mTree != null && node != null )
{
mTree.setSelectionPath( new TreePath( node.getPath() ) );
}
}
public ResourceManager getResourceManager()
{
return mResourceManager;
}
public void setTree( JTree tree )
{
mTree = tree;
}
private void addTuners( TunerGroupNode parent )
{
List<Tuner> tuners = mResourceManager.getTunerManager().getTuners();
for( Tuner tuner: tuners )
{
TunerNode child = new TunerNode( tuner );
insertNodeInto( child, parent, parent.getChildCount() );
parent.sort();
show( child );
}
}
/**
* Convenience method to add a new default system, site and channel to
* the tree
*/
public void createChannel( int frequency, DecoderType decoder )
{
System system = new System();
Site site = new Site();
system.addSite( site );
Channel channel = new Channel();
channel.setDecodeConfiguration(
DecodeConfigFactory.getDecodeConfiguration( decoder ) );
SourceConfigTuner sourceConfig = new SourceConfigTuner();
sourceConfig.setFrequency( frequency );
channel.setSourceConfiguration( sourceConfig );
channel.setEnabled( true, true );
site.addChannel( channel );
mPlaylistNode.getPlaylist().getSystemList().addSystem( system );
SystemNode systemNode = new SystemNode( system );
SystemListNode systemListNode = mPlaylistNode.getSystemListNode();
addNode( systemNode, systemListNode, systemListNode.getChildCount() );
systemNode.init();
systemNode.save();
}
public void addNode( BaseNode child, BaseNode parent, int index )
{
insertNodeInto( child, parent, index );
show( child );
}
public void deleteNode( BaseNode node )
{
node.delete();
}
private void show( BaseNode node )
{
if( mTree != null )
{
mTree.scrollPathToVisible( new TreePath( node.getPath() ) );
}
}
public void addListener( TunerSelectionListener listener )
{
mTunerSelectionListeners.add( listener );
}
public void removeListener( TunerSelectionListener listener )
{
mTunerSelectionListeners.remove( listener );
}
/**
* Notifies registered listeners that the tuner has been selected
*/
public void fireTunerSelectedEvent( Tuner tuner )
{
Iterator<TunerSelectionListener> it =
mTunerSelectionListeners.iterator();
while( it.hasNext() )
{
it.next().tunerSelected( tuner );
}
}
/**
* Fires a tuner selection event for the first tuner listed in the tree.
* This is mainly used on application startup to show the spectral display
* of the first tuner in the spectrum panel.
*/
public void fireFirstTunerSelected()
{
if( mTunerGroupNode.getChildCount() > 0 )
{
TunerNode node = (TunerNode)mTunerGroupNode.getChildAt( 0 );
fireTunerSelectedEvent( node.getTuner() );
}
}
public ArrayList<Channel> getCurrentChannelConfigs()
{
return getChannelConfigs( mPlaylistNode );
}
private ArrayList<Channel> getChannelConfigs( DefaultMutableTreeNode parent )
{
ArrayList<Channel> configs = new ArrayList<Channel>();
Enumeration<DefaultMutableTreeNode> nodes = parent.children();
while( nodes.hasMoreElements() )
{
DefaultMutableTreeNode node = nodes.nextElement();
if( node instanceof ChannelNode )
{
configs.add( ((ChannelNode)node).getChannel() );
}
//Recursive call
configs.addAll( getChannelConfigs( node ) );
}
return configs;
}
}

View File

@@ -0,0 +1,75 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
public class ConfigurationEditor extends JPanel
implements TreeSelectionListener
{
private static final long serialVersionUID = 1L;
/**
* Host for configuration editor display panels
*/
public ConfigurationEditor()
{
init();
}
public void init()
{
setPanel( new EmptyEditor() );
}
public void setPanel( JPanel display )
{
removeAll();
setLayout( new BorderLayout() );
JScrollPane scroll = new JScrollPane( display );
add( scroll, BorderLayout.CENTER );
revalidate();
repaint();
}
@Override
public void valueChanged( TreeSelectionEvent e )
{
JTree tree = (JTree)e.getSource();
BaseNode node =
(BaseNode)tree.getLastSelectedPathComponent();
if( node != null )
{
setPanel( node.getEditor() );
}
}
}

View File

@@ -0,0 +1,117 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeSelectionModel;
import net.miginfocom.swing.MigLayout;
public class ConfigurationTreePanel extends JPanel
{
private static final long serialVersionUID = 1L;
protected JTree mSystemTree;
protected ConfigurationControllerModel mTreeModel;
public ConfigurationTreePanel( ConfigurationControllerModel model )
{
mTreeModel = model;
initGUI();
}
private void initGUI()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill][]") );
mSystemTree = new JTree( mTreeModel );
mSystemTree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION );
mSystemTree.setShowsRootHandles( true );
mSystemTree.addMouseListener( new Handler() );
mSystemTree.setCellRenderer( new ControllerTreeCellRenderer() );
//Give the model a reference to the tree, so that it can force newly
//added nodes to be displayed
mTreeModel.setTree( mSystemTree );
JScrollPane treeScroll = new JScrollPane( mSystemTree );
add( treeScroll, "cell 0 0,span,grow" );
}
public void addTreeSelectionListener( TreeSelectionListener listener )
{
mSystemTree.addTreeSelectionListener( listener );
}
public class Handler implements MouseListener
{
public Handler()
{
}
@Override
public void mouseClicked( MouseEvent event )
{
if( SwingUtilities.isRightMouseButton( event ) )
{
int row = mSystemTree.getRowForLocation( event.getX(),
event.getY() );
if( row != -1 )
{
mSystemTree.setSelectionRow( row );
Object selectedNode =
mSystemTree.getLastSelectedPathComponent();
if( selectedNode instanceof BaseNode )
{
JPopupMenu contextMenu =
((BaseNode)selectedNode).getContextMenu();
if( contextMenu != null )
{
contextMenu.show( mSystemTree,
event.getX(),
event.getY() );
}
}
}
}
}
@Override
public void mousePressed( MouseEvent e ){}
@Override
public void mouseReleased( MouseEvent e ){}
@Override
public void mouseEntered( MouseEvent e ){}
@Override
public void mouseExited( MouseEvent e ){}
}
}

View File

@@ -0,0 +1,134 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import map.MapPanel;
import message.Message;
import net.miginfocom.swing.MigLayout;
import sample.Listener;
import com.jidesoft.swing.JideSplitPane;
import com.jidesoft.swing.JideTabbedPane;
import controller.activity.CallEventPanel;
import controller.activity.MessageActivityPanel;
import controller.state.ChannelStateList;
public class ControllerPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private ChannelStateList mChannelStateList;
private CallEventPanel mCallEventPanel = new CallEventPanel();
private MessageActivityPanel mMessageActivityPanel =
new MessageActivityPanel();
private JideTabbedPane mTabbedPane;
protected ConfigurationTreePanel mSystemControlViewPanel;
protected ConfigurationEditor mConfigurationEditor;
protected JideSplitPane mSystemControlSplitPane;
protected JTable mChannelActivityTable = new JTable();
protected ResourceManager mResourceManager;
public ControllerPanel( ResourceManager resourceManager )
{
mResourceManager = resourceManager;
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0 ",
"[grow,fill]",
"[grow,fill]") );
//System Configuration View and Editor
mConfigurationEditor = new ConfigurationEditor();
mSystemControlViewPanel =
new ConfigurationTreePanel( mResourceManager.getController() );
mSystemControlViewPanel.addTreeSelectionListener( mConfigurationEditor );
mSystemControlSplitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT );
mSystemControlSplitPane.setDividerSize( 5 );
mSystemControlSplitPane.add( mSystemControlViewPanel );
mSystemControlSplitPane.add( mConfigurationEditor );
//Tabbed View - configuration, calls, messages, map
mTabbedPane = new JideTabbedPane();
mTabbedPane.setFont( this.getFont() );
mTabbedPane.setForeground( Color.BLACK );
mTabbedPane.addTab( "Configuration", mSystemControlSplitPane );
mTabbedPane.addTab( "Calls", mCallEventPanel );
mTabbedPane.addTab( "Messages", mMessageActivityPanel );
/**
* Add mapping services and map panel to a new tab
*/
/* Add Map Service as message listener to receive all messages */
mResourceManager.getChannelManager().addListener(
(Listener<Message>)mResourceManager.getMapService() );
MapPanel mapPanel = new MapPanel( mResourceManager );
mTabbedPane.addTab( "Map", mapPanel );
/* Channel state list */
mChannelStateList = new ChannelStateList( mResourceManager.getSettingsManager() );
/* Add message activity panel to receive channel selection events so
* that we can display the correct message listings */
mResourceManager.getChannelManager().addListener( mMessageActivityPanel );
/* Add call event panel to receive channel selection events so
* that we can display the correct call event listings */
mResourceManager.getChannelManager().addListener( mCallEventPanel );
/* Register ChannelStateList as a listener on the channel manager to
* receive channel starts and stops and deletes */
mResourceManager.getChannelManager().addListener( mChannelStateList );
JScrollPane channelStateListScroll = new JScrollPane();
channelStateListScroll.getViewport().setView( mChannelStateList );
channelStateListScroll.setPreferredSize( new Dimension( 150,
(int)channelStateListScroll.getPreferredSize().getHeight() ) );
JideSplitPane channelSplit = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT );
channelSplit.setDividerSize( 5 );
channelSplit.add( channelStateListScroll );
channelSplit.add( mTabbedPane );
add( channelSplit );
}
public ConfigurationControllerModel getController()
{
return mResourceManager.getController();
}
}

View File

@@ -0,0 +1,106 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.awt.Component;
import java.awt.Image;
import java.util.HashMap;
import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
public class ControllerTreeCellRenderer extends DefaultTreeCellRenderer
{
private static final long serialVersionUID = 1L;
public static final int MAX_ICON_HEIGHT = 16;
private HashMap<String,ImageIcon> mIcons = new HashMap<String,ImageIcon>();
public ControllerTreeCellRenderer()
{
}
@Override
public Component getTreeCellRendererComponent( JTree tree,
Object value, boolean selected, boolean expanded, boolean isLeaf,
int row, boolean focused )
{
Component c = super.getTreeCellRendererComponent( tree, value, selected,
expanded, isLeaf, row, focused );
if( value instanceof BaseNode )
{
ImageIcon icon = getIcon( (BaseNode)value );
if( icon != null )
{
if( icon.getIconHeight() > 16 )
{
}
else
{
setIcon( icon );
}
}
}
return c;
}
private ImageIcon getIcon( BaseNode node )
{
ImageIcon icon = null;
String filepath = node.getIconPath();
if( filepath != null )
{
if( mIcons.containsKey( filepath ) )
{
icon = mIcons.get( filepath );
}
else
{
icon = new ImageIcon( filepath );
if( icon.getIconHeight() > MAX_ICON_HEIGHT )
{
Image image = icon.getImage();
double scale = (double)icon.getIconHeight() / (double)MAX_ICON_HEIGHT;
int scaledWidth = (int)( (double)icon.getIconWidth() / scale );
Image scaledImage = image.getScaledInstance( scaledWidth,
MAX_ICON_HEIGHT, java.awt.Image.SCALE_SMOOTH );
mIcons.put( filepath, new ImageIcon( scaledImage ) );
}
else
{
mIcons.put( filepath, icon );
}
}
}
return icon;
}
}

View File

@@ -0,0 +1,36 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public abstract class Editor extends JPanel
{
private static final long serialVersionUID = 1L;
public Editor()
{
setLayout( new MigLayout() );
}
public abstract void save();
public abstract void reset();
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class EmptyEditor extends JPanel
{
private static final long serialVersionUID = 1L;
public EmptyEditor()
{
setLayout( new BorderLayout() );
setPreferredSize( new Dimension( 200, (int)getPreferredSize().getHeight() ) );
String text = "<html>"
+ "<p>SDR Trunk</p>"
+ "<br>"
+ "<p>Use the tree structure to the left to configure SDRTrunk"
+ " to use multiple SDR tuners and sound card sources to"
+ " decode multiple trunked and digital radio channels.</p>"
+ "<br>"
+ "<p>Each tree branch can be accessed by clicking on the branch"
+ " and a configuration editor will appear here.</p>"
+ "<br>"
+ "<p>Many of the branches contain context sensitive menus that "
+ " you can access by right-clicking on the node.</p>"
+ "<br>"
+ "<p>To begin, right-click on the 'Systems' branch under 'Playlist'"
+ "and create a new 'System'. Right-click the 'System' node to create "
+ "a new 'Site'. Right-click on the 'Site' node to create a new Channel.</p>"
+ "<br>"
+ "<p>In the new channel, select a channel source and decoder "
+ "and select event logging and recording options. Check 'Enabled'"
+ " and hit the 'Save' button to begin decoding.</p>"
+ "</html>";
add( new JLabel( text ), BorderLayout.NORTH );
}
}

View File

@@ -0,0 +1,159 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import map.MapService;
import playlist.PlaylistManager;
import record.RecorderManager;
import settings.SettingsManager;
import source.SourceManager;
import source.tuner.TunerManager;
import controller.channel.ChannelManager;
import eventlog.EventLogManager;
/**
* Manager for system wide resources
*/
public class ResourceManager
{
private ChannelManager mChannelManager;
private EventLogManager mEventLogManager;
private PlaylistManager mPlaylistManager;
private RecorderManager mRecorderManager;
private SettingsManager mSettingsManager;
private SourceManager mSourceManager;
private TunerManager mTunerManager;
private ConfigurationControllerModel mController;
private MapService mMapService;
private ThreadPoolManager mThreadPoolManager;
public ResourceManager()
{
this( new SettingsManager(),
new PlaylistManager(),
new EventLogManager(),
new RecorderManager() );
}
public ResourceManager( SettingsManager settingsManager,
PlaylistManager playlistManager,
EventLogManager eventLogManager,
RecorderManager recorderManager )
{
mSettingsManager = settingsManager;
mPlaylistManager = playlistManager;
mEventLogManager = eventLogManager;
mRecorderManager = recorderManager;
/**
* ChannelManager requires a reference to the ResourceManager so that
* channel processing chains can access system wide resources
*/
mChannelManager = new ChannelManager( this );
mSourceManager = new SourceManager( this );
mTunerManager = new TunerManager( this );
mController = new ConfigurationControllerModel( this );
mMapService = new MapService( this );
mThreadPoolManager = new ThreadPoolManager();
}
public ConfigurationControllerModel getController()
{
return mController;
}
public ThreadPoolManager getThreadPoolManager()
{
return mThreadPoolManager;
}
public void setController( ConfigurationControllerModel controller )
{
mController = controller;
}
public TunerManager getTunerManager()
{
return mTunerManager;
}
public MapService getMapService()
{
return mMapService;
}
public SettingsManager getSettingsManager()
{
return mSettingsManager;
}
public void setSettingsManager( SettingsManager manager )
{
mSettingsManager = manager;
}
public PlaylistManager getPlaylistManager()
{
return mPlaylistManager;
}
public void setPlaylistManager( PlaylistManager aliasManager )
{
mPlaylistManager = aliasManager;
}
public EventLogManager getEventLogManager()
{
return mEventLogManager;
}
public void setEventLogManager( EventLogManager eventLogManager )
{
mEventLogManager = eventLogManager;
}
public RecorderManager getRecorderManager()
{
return mRecorderManager;
}
public void setRecorderManager( RecorderManager recorderManager )
{
mRecorderManager = recorderManager;
}
public SourceManager getSourceManager()
{
return mSourceManager;
}
public void setSourceManager( SourceManager sourceManager )
{
mSourceManager = sourceManager;
}
public ChannelManager getChannelManager()
{
return mChannelManager;
}
public void setChannelManager( ChannelManager channelManager )
{
mChannelManager = channelManager;
}
}

View File

@@ -0,0 +1,97 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller;
import java.util.HashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ThreadPoolManager
{
private int THREAD_POOL_SIZE = 10;
private int MAX_TASK_COUNT = 24;
private HashMap<ScheduledFuture<?>,ThreadType> mTasks =
new HashMap<ScheduledFuture<?>,ThreadType>();
private ScheduledExecutorService mExecutor;
public ThreadPoolManager()
{
}
public ScheduledFuture<?> schedule( ThreadType type,
Runnable command,
long period,
TimeUnit unit )
throws RejectedExecutionException
{
if( mExecutor == null )
{
mExecutor = Executors.newScheduledThreadPool( THREAD_POOL_SIZE );
}
if( mTasks.size() <= MAX_TASK_COUNT )
{
ScheduledFuture<?> task =
mExecutor.scheduleAtFixedRate( command, 0, period, unit );
mTasks.put( task, type );
return task;
}
else
{
throw new RejectedExecutionException( "Cannot schedule task - at "
+ "max task count [" + mTasks.size() + "]" );
}
}
public void cancel( ScheduledFuture<?> task )
{
task.cancel( true );
ThreadType type = mTasks.remove( task );
}
public int getTaskCount( ThreadType type )
{
int count = 0;
for( ThreadType current: mTasks.values() )
{
if( current == type )
{
count++;
}
}
return count;
}
public enum ThreadType
{
SOURCE_SAMPLE_PROCESSING,
DECIMATION,
DECODER;
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout;
public class ActivitySummaryFrame extends JFrame
{
private static final long serialVersionUID = 1L;
public ActivitySummaryFrame( String summary )
{
this( summary, null );
}
public ActivitySummaryFrame( String summary, Component displayOver )
{
setTitle( "Activity Summary" );
setLocationRelativeTo( displayOver );
setSize( 400, 400 );
setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill][]" ) );
JTextArea summaryText = new JTextArea( summary );
JScrollPane scroller = new JScrollPane( summaryText );
scroller.setViewportView( summaryText );
add( scroller, "wrap" );
JButton close = new JButton( "Close" );
close.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
dispose();
}
} );
add( close );
setVisible( true );
}
}

View File

@@ -0,0 +1,26 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import message.Message;
import sample.Listener;
public interface ActivitySummaryProvider extends Listener<Message>
{
public String getSummary();
}

View File

@@ -0,0 +1,226 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import java.text.SimpleDateFormat;
import java.util.Date;
import alias.Alias;
import alias.AliasList;
import decode.DecoderType;
public abstract class CallEvent
{
protected long mEventTime = System.currentTimeMillis();
private SimpleDateFormat mSDF = new SimpleDateFormat( "yyyyMMdd','HHmmss" );
protected DecoderType mDecoderType;
protected CallEventType mCallEventType;
protected AliasList mAliasList;
protected String mFromID;
protected String mToID;
protected String mDetails;
public CallEvent( DecoderType decoder,
CallEventType callEventType,
AliasList aliasList,
String fromID,
String toID,
String details )
{
mDecoderType = decoder;
mCallEventType = callEventType;
mAliasList = aliasList;
mFromID = fromID;
mToID = toID;
mDetails = details;
}
public DecoderType getDecoderType()
{
return mDecoderType;
}
public CallEventType getCallEventType()
{
return mCallEventType;
}
public AliasList getAliasList()
{
return mAliasList;
}
public void setAliasList( AliasList aliasList )
{
mAliasList = aliasList;
}
public boolean hasAliasList()
{
return mAliasList != null;
}
public long getEventTime()
{
return mEventTime;
}
public String getFromID()
{
return mFromID;
}
public void setFromID( String id )
{
mFromID = id;
}
public String getToID()
{
return mToID;
}
public void setToID( String id )
{
mToID = id;
}
public String getDetails()
{
return mDetails;
}
public void setDetails( String details )
{
mDetails = details;
}
public abstract Alias getFromIDAlias();
public abstract Alias getToIDAlias();
public abstract int getChannel();
public abstract int getFrequency();
public static String getCSVHeader()
{
return "DATE,TIME,DECODER,EVENT,FROM,FROM_ALIAS,TO,TO_ALIAS,"
+ "CHANNEL,FREQUENCY,DETAILS";
}
public String toCSV()
{
StringBuilder sb = new StringBuilder();
sb.append( "'" );
sb.append( mSDF.format( new Date( getEventTime() ) ) );
sb.append( "','" );
sb.append( getDecoderType().toString() );
sb.append( "','" );
sb.append( getCallEventType().toString() );
sb.append( "'," );
if( getFromID() != null )
{
sb.append( "'" );
sb.append( getFromID() );
sb.append( "'" );
}
sb.append( "," );
Alias fromAlias = getFromIDAlias();
if( fromAlias != null )
{
sb.append( "'" );
sb.append( fromAlias.getName() );
sb.append( "'" );
}
sb.append( "," );
if( getToID() != null )
{
sb.append( "'" );
sb.append( getToID() );
sb.append( "'" );
}
sb.append( "," );
Alias toAlias = getToIDAlias();
if( toAlias != null )
{
sb.append( "'" );
sb.append( toAlias.getName() );
sb.append( "'" );
}
sb.append( ",'" );
sb.append( getChannel() );
sb.append( "','" );
sb.append( getFrequency() );
sb.append( "'," );
if( getDetails() != null )
{
sb.append( "'" );
sb.append( getDetails() );
sb.append( "'" );
}
return sb.toString();
}
public enum CallEventType
{
ACKNOWLEDGE( "Acknowledge" ),
CALL_DETECT( "Call Detect" ),
CALL_START( "Call Start" ),
CALL_START_UNIQUE_ID( "Call Start" ),
CALL_START_NO_TUNER( "Call - No Tuner" ),
CALL_END( "Call End" ),
CALL_TIMEOUT( "Call Timeout" ),
EMERGENCY( "EMERGENCY" ),
GPS( "GPS" ),
ID_ANI( "ANI" ),
ID_UNIQUE( "Unique ID" ),
PAGE( "Page" ),
REGISTER( "Register" ),
REGISTER_ESN( "ESN" ),
SDM( "SDM" ),
STATUS( "Status" ),
UNKNOWN( "Unknown" );
private String mLabel;
private CallEventType( String label )
{
mLabel = label;
}
public String getLabel()
{
return mLabel;
}
public String toString()
{
return mLabel;
}
}
}

View File

@@ -0,0 +1,72 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import javax.swing.ImageIcon;
import javax.swing.table.DefaultTableCellRenderer;
import settings.SettingsManager;
import alias.Alias;
/**
* Custom renderer for JTable cells that contain Alias objects. Renders the
* alias name, and if there is an icon name, attempts to get that icon from
* the settings manager and render it.
*/
public class CallEventAliasCellRenderer extends DefaultTableCellRenderer
{
private SettingsManager mSettingsManager;
public CallEventAliasCellRenderer( SettingsManager settingsManager )
{
super();
mSettingsManager = settingsManager;
}
public void setValue( Object obj )
{
if( obj != null && obj instanceof Alias )
{
Alias alias = (Alias)obj;
setText( alias.getName() );
ImageIcon icon = getIcon( alias, 12 );
if( icon != null )
{
setIcon( icon );
}
}
else
{
setText( " " );
setIcon( null );
}
}
private ImageIcon getIcon( Alias alias, int height )
{
if( mSettingsManager != null && alias != null )
{
return mSettingsManager.getImageIcon( alias.getIconName(), height );
}
return null;
}
}

View File

@@ -0,0 +1,176 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import javax.swing.table.AbstractTableModel;
import log.Log;
import sample.Broadcaster;
import sample.Listener;
public class CallEventModel extends AbstractTableModel
{
private static final long serialVersionUID = 1L;
private static final int DEFAULT_ICON_HEIGHT = 14;
private static final int sTIME = 0;
private static final int sEVENT = 1;
private static final int sFROM_ID = 2;
private static final int sFROM_ALIAS = 3;
private static final int sTO_ID = 4;
private static final int sTO_ALIAS =5;
private static final int sCHANNEL = 6;
private static final int sFREQUENCY = 7;
private static final int sDETAILS = 8;
protected int mMaxMessages = 500;
protected LinkedList<CallEvent> mEvents = new LinkedList<CallEvent>();
protected String[] mHeaders = new String[] { "Time",
"Event",
"From",
"From Alias",
"To",
"To Alias",
"Channel",
"Frequency",
"Details" };
private SimpleDateFormat mSDFTime = new SimpleDateFormat( "HH:mm:ss" );
private Broadcaster<CallEvent> mBroadcaster = new Broadcaster<CallEvent>();
private boolean mNewMessagesFirst = true;
public CallEventModel()
{
}
public void dispose()
{
mEvents.clear();
mBroadcaster.dispose();
}
public void flush()
{
/* Flush all events to listeners ( normally the call event logger ) */
for( CallEvent event: mEvents )
{
mBroadcaster.receive( event );
}
}
public int getMaxMessageCount()
{
return mMaxMessages;
}
public void setMaxMessageCount( int count )
{
mMaxMessages = count;
}
public void add( final CallEvent event )
{
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
mEvents.addFirst( event );
CallEventModel.this.fireTableRowsInserted( 0, 0 );
prune();
}
} );
}
private void prune()
{
while( mEvents.size() > mMaxMessages )
{
CallEvent event = mEvents.removeLast();
mBroadcaster.receive( event );
super.fireTableRowsDeleted( mEvents.size(), mEvents.size() );
}
}
@Override
public int getRowCount()
{
return mEvents.size();
}
@Override
public int getColumnCount()
{
return mHeaders.length;
}
public String getColumnName( int column )
{
return mHeaders[ column ];
}
@Override
public Object getValueAt( int rowIndex, int columnIndex )
{
switch( columnIndex )
{
case sTIME:
return mSDFTime.format( mEvents.get( rowIndex ).getEventTime() );
case sEVENT:
return mEvents.get( rowIndex ).getCallEventType();
case sFROM_ID:
return mEvents.get( rowIndex ).getFromID();
case sFROM_ALIAS:
return mEvents.get( rowIndex ).getFromIDAlias();
case sTO_ID:
return mEvents.get( rowIndex ).getToID();
case sTO_ALIAS:
return mEvents.get( rowIndex ).getToIDAlias();
case sCHANNEL:
return mEvents.get( rowIndex ).getChannel();
case sFREQUENCY:
return mEvents.get( rowIndex ).getFrequency();
case sDETAILS:
return mEvents.get( rowIndex ).getDetails();
}
return null;
}
public void addListener( Listener<CallEvent> listener )
{
mBroadcaster.addListener( listener );
}
public void removeListener( Listener<CallEvent> listener )
{
mBroadcaster.removeListener( listener );
}
}

View File

@@ -0,0 +1,84 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import net.miginfocom.swing.MigLayout;
import controller.channel.Channel;
import controller.channel.Channel.ChannelEvent;
import controller.channel.ChannelListener;
public class CallEventPanel extends JPanel implements ChannelListener
{
private static final long serialVersionUID = 1L;
private JScrollPane mEmptyScroller;
private Channel mDisplayedChannel;
public CallEventPanel()
{
setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") );
JTable table = new JTable( new CallEventModel() );
table.setAutoCreateRowSorter( true );
table.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
mEmptyScroller = new JScrollPane( table );
add( mEmptyScroller );
}
@Override
public void occurred( Channel channel, ChannelEvent event )
{
if( event == ChannelEvent.CHANGE_SELECTED && channel.getSelected() )
{
if( mDisplayedChannel == null ||
( mDisplayedChannel != null && mDisplayedChannel != channel ) )
{
removeAll();
JScrollPane scroller = new JScrollPane(
channel.getProcessingChain().getChannelState()
.getCallEventTable() );
add( scroller );
mDisplayedChannel = channel;
revalidate();
repaint();
}
}
else if( event == ChannelEvent.PROCESSING_STOPPED ||
event == ChannelEvent.CHANNEL_DELETED )
{
if( mDisplayedChannel != null && mDisplayedChannel == channel )
{
mDisplayedChannel = null;
removeAll();
add( mEmptyScroller );
revalidate();
repaint();
}
}
}
}

View File

@@ -0,0 +1,155 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import javax.swing.table.AbstractTableModel;
import message.Message;
import sample.Listener;
public class MessageActivityModel extends AbstractTableModel
implements Listener<Message>
{
private static final long serialVersionUID = 1L;
private static final int sTIME = 0;
private static final int sPROTOCOL = 1;
private static final int sERROR_STATUS = 2;
private static final int sMESSAGE = 3;
private static final int sMESSAGE_BITS = 4;
protected int mMaxMessages = 500;
protected LinkedList<Message> mMessages = new LinkedList<Message>();
protected int[] mColumnWidths = { 110, 110, 110, -1, -1 };
protected String[] mHeaders = new String[] { "Time",
"Protocol",
"Error Check",
"Message",
"Binary" };
private SimpleDateFormat mSDFTime = new SimpleDateFormat( "HH:mm:ss" );
private boolean mNewMessagesFirst = true;
public MessageActivityModel()
{
}
public void dispose()
{
mMessages.clear();
}
public int[] getColumnWidths()
{
return mColumnWidths;
}
public void setColumnWidths( int[] widths )
{
if( widths.length != 5 )
{
throw new IllegalArgumentException( "MessageActivityModel - "
+ "column widths array should have 5 elements" );
}
else
{
mColumnWidths = widths;
}
}
public int getMaxMessageCount()
{
return mMaxMessages;
}
public void setMaxMessageCount( int count )
{
mMaxMessages = count;
}
public void receive( final Message message )
{
EventQueue.invokeLater( new Runnable()
{
@Override
public void run()
{
mMessages.addFirst( message );
MessageActivityModel.this.fireTableRowsInserted( 0, 0 );
prune();
}
} );
}
private void prune()
{
while( mMessages.size() > mMaxMessages )
{
mMessages.removeLast();
super.fireTableRowsDeleted( mMessages.size() - 1, mMessages.size() - 1 );
}
}
@Override
public int getRowCount()
{
return mMessages.size();
}
@Override
public int getColumnCount()
{
return mHeaders.length;
}
public String getColumnName( int column )
{
return mHeaders[ column ];
}
@Override
public Object getValueAt( int rowIndex, int columnIndex )
{
Message message = mMessages.get( rowIndex );
switch( columnIndex )
{
case sTIME:
return mSDFTime.format( message.getDateReceived() );
case sPROTOCOL:
return message.getProtocol();
case sERROR_STATUS:
return message.getErrorStatus();
case sMESSAGE:
return message.getMessage();
case sMESSAGE_BITS:
return message.getBinaryMessage();
}
return null;
}
}

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import net.miginfocom.swing.MigLayout;
import controller.channel.Channel;
import controller.channel.Channel.ChannelEvent;
import controller.channel.ChannelListener;
public class MessageActivityPanel extends JPanel implements ChannelListener
{
private static final long serialVersionUID = 1L;
private JScrollPane mEmptyScrollPane;
private Channel mDisplayedChannel;
public MessageActivityPanel()
{
setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") );
mEmptyScrollPane =
new JScrollPane( new JTable( new MessageActivityModel() ) );
add( mEmptyScrollPane );
}
@Override
public void occurred( Channel channel, ChannelEvent event )
{
if( event == ChannelEvent.CHANGE_SELECTED && channel.getSelected() )
{
if( mDisplayedChannel == null ||
( mDisplayedChannel != null && mDisplayedChannel != channel ) )
{
removeAll();
JScrollPane scroll =
new JScrollPane( channel.getProcessingChain()
.getChannelState().getMessageActivityTable() );
add( scroll );
mDisplayedChannel = channel;
revalidate();
repaint();
}
}
else if( event == ChannelEvent.PROCESSING_STOPPED ||
event == ChannelEvent.CHANNEL_DELETED )
{
if( mDisplayedChannel != null && mDisplayedChannel == channel )
{
mDisplayedChannel = null;
removeAll();
add( mEmptyScrollPane );
revalidate();
repaint();
}
}
}
}

View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
******************************************************************************/
package controller.activity;
import alias.Alias;
/**
* Getter methods to support the Message Activity Table/Model
* @author denny
*
*/
public interface MessageDetailsProvider
{
/**
* Indicates if the message is valid and has passed crc/integrity checks
*/
public abstract boolean isValid();
/**
* Status of the CRC check of the message
*/
public abstract String getErrorStatus();
/**
* Parsed Message
* @return
*/
public abstract String getMessage();
/**
* Raw ( 0 & 1 ) message bits
*/
public abstract String getBinaryMessage();
/**
* Decoded protocol
*/
public abstract String getProtocol();
/**
* Event - call, data, idle, etc.
*/
public abstract String getEventType();
/**
* Formatted from identifier
*/
public abstract String getFromID();
/**
* From identifier alias (from AliasManager)
*/
public abstract Alias getFromIDAlias();
/**
* Formatted to identifier
*/
public abstract String getToID();
/**
* To identifier alias (from AliasManager)
* @return
*/
public abstract Alias getToIDAlias();
}

Some files were not shown because too many files have changed in this diff Show More