Amateur Radio

Morse-it BLE Hardware CW Key

This project utilizes (at minimum):

  1. An iOS device with Bluetooth LE capabilities
  2. Morse-it
  3. Adafruit Feather 32u4 Bluefruit LE
  4. And a physical CW key of your choice.
  5. Various bits of wire and a micro USB cable
  6. Soldering iron and solder, wire strippers and other basic electronics tools.


  1. Update the firmware on Feather
    1. Easiest way is to download BlueFruit Connect
    2. Open the app, find the “Adafruit Bluefruit LE” device and click the “Connect” button
    3. Scroll down the list, find the “Update” menu option and install the latest firmware
    4. Download and install the Arduino IDE
      Firmware Update
  2. Follow the Adafruit Arduino setup guide to add the Adafruit boards to the IDE.
  3. Connect the board to the computer with a micro USB cable
  4. Create new project in the Arduino IDE
  5. Copy the 3 files from the project into your new project.
  6. Compile the project
  7. Upload the project to the board
    Arduino IDE
  8. Wire the CW key to the board. In my case I used an old mobile 3.5 mm headphones adapter so I could quickly move the key between the Bluetooth module and the radio. I used a 4 pin Dupont connector for quick connection to the breadboard. If you want you can mount the feather on a breadboard. You can order the board with headers already installed, I chose to solder the header pins myself.
    1. GND – Common on the CW key
    2. PIN A0 – Dit( . ) for iambic keys or for straight keys
    3. PIN A1 – Dah( _ ) for iambic keys
      Feather Wiring
  9. On your iOS device, go to “Settings” -> “Bluetooth” and discover “MorseKey”
  10. Open Morse-it, go the “Tap” tab and test sending.

I’ve programmed the Feather so that it sends only the default key mappings. I haven’t bothered to measure latency as it is imperceptible. If you do experience timing issues, toggle the “Reduce delays” option in the Settings>Global>KeyType, depending on how you send, this can improve the decode. 

Other uses include using it a logging devices and checking the quality of your sending while on the air.

To use a Straight Key:

In Morse-It, open “Settings” -> “Key Type” and select “Straight Key”.  This sets up Morse-It to work with a straight key.  Then go back one menu level and select “Hardware Interface” -> “Straight Key” under the “Keyboard” option at the bottom ensure that the “Enabled” toggle switch is green and then select “- Key” and set it to “Left Arrow”.  This is the standard configuration, if that doesn’t work, change “- Key” to “Right Arrow”. 

M7BVC tests out the finished project.

A huge thanks to the work done by Chris Young on his tutorials and GitHub page. This project is adapted and modified from his original work and is licensed under Creative Commons ShareALike.


Homemade White Bread

If you have been friends with me for a while then most likely, you’ve had some of my bread. This is the classic that I’ve traditionally made for the last 20 years or so. Enjoy.

White Bread
Makes two large loaves
2 packages of active dry yeast (1 tablespoon + 1/2 teaspoon)
3/4 cup warm water (105 – 115 F)
2 2/3 cups warm water (105 – 115 F)
1/4 cup sugar
1 tablespoon sea salt
3 tablespoons shortening (UK – Stork, Trex, Flora White US – Butter Flavoured Crisco)
8-9 cups unbleached bread flour
6 – tablespoons salted butter – melted
Sesame or poppy seeds (optional)

Sponge Process (2-6 hours)
Dissolve yeast in 3/4 cup warm water for 5 minutes.  Stir in remaining water and ensure that all the yeast is dissolved.  Add in 4 cups of flour and mix well.  Place mixture in very large nonmetallic bowl (it will grow dramatically). Cover bowl with plastic wrap and let rest for at least 2 hours but no more than 6 hours (longer times give better flavor and texture).

Mix and Knead
Add sugar, sea salt, shortening and mix well.  Add remaining flour, one cup at a time until dough is easy to handle.  Place dough on the a lightly floured surface and knead for 10 minutes, add flour as necessary to keep from sticking.  Place dough in a greased, nonmetallic bowl; cover and let rise until double in size (about 45-60 minutes).

Punch down dough (push all the air out of it and make it flat).  Divide dough in half.  Divide each half into 3 equal parts.  Braid the 3 parts together.  Lightly dust a baking stone with corn meal. Place the two loaves on baking stone, brush with melted butter (sprinkle optional seeds on top), cover with towel and let rise for 30-45 minutes.

Pre-heat oven to 425 F (215C or 200C Fan), position racks so that the bottom of the stone is just below the middle of the oven.  On a rack below that, place a baking dish full of water to add moisture to the air in the oven.

Bake for 28 minutes.

Remove from oven, brush with butter again, and serve immediately. I suggest tearing the bread rather than slicing it.

Amateur Radio

Icom IC-7300 and EasyPal PTT

First setup your Icom IC-7300 as described here.

Find the COM Port for the Radio in Device Manager (that’s in control panel):


Then in EasyPal, open the PTT Settings:

Set your settings to look like below, make sure to change the COM port to what your system is using. Also, make sure to Save the Profile.

To automatically enable DATA mode on the radio and then back to regular mode, set:

PTT ON String: FEFE94E01A060101FDFEFE94E01C0001FD

PTT OFF String: FEFE94E01C0000FDFEFE94E01A060000FD

For more information on the strings, review the full manual for the ICOM IC-7300 available here.

Amateur Radio

Icom IC-7300 Connector Settings

I’ve had a few people ask about the data settings that I use for the ICOM IC-7300. I’ve decided it’s just easier to post them here.

ACC/USB Output SelectAF
ACC/USB AF Output Level42%
ACC/USB AF SquelchOFF(Open)
ACC/USB AF Beep/Speech OutputOFF
ACC/USB IF Output Level80%
ACC MOD Level50%
USB MOD Level60%
External Keypad
CI-VSee Below
USB Serial FunctionCI-V
CI-V SettingsSetting
CI-V Baud RateAuto
CI-V Address94h
CI-V TranscieveON
CI-V USB->Remote Transceive Address00h
CI-V Output (for ANT)OFF
CI-V USB PortUnlink from [REMOTE]
CI-V USB Baud Rate115200


As most of us in the world are currently in some form of isolation or quarantine and we all have far too much time on our hands, I figured I would finally get around to posting some of the food fun that we’ve been having here at the Marvel house.

Sunny Weather Barbecue

With unseasonably warm and sunny weather we’ve been experiencing here on the Welsh borders, I decided that we should fire up the smoker and cook some burgers. Of course, in the current “self-isolating” phase of life, there is no such thing as just a “quick” pop out to the shop to grab some burgers or buns. This was going to require a bit of planning.


I’ve recently met Hal over at The Little Hill Farm through amateur radio. He wanted to borrow some radio gear and I wanted some meat, and he offers delivery. Hal provided me with high quality half-chuck/half-silverside quarter-pound burgers from his locally raised Hereford stock, pre-seasoned lightly and with no additives, along with some additional ground beef and lamb.


Bread availability has been hit-or-miss at the moment and with such nice burgers on the line, I couldn’t take the chance of them not being in stock, so I decided to make my own. Flour, as well, has been hard to come by, but my wife, Emma, found some very nice wholemeal strong flour at the local organic shop. I did a bit of research, followed my gut from all my previous bread-making experience, and made up some wholemeal burger buns. I think they turned out alright.


What’s a burger without chips (fries, for all my American friends)? Better than chips are homemade wedges. We live in a part of the country that produces absolutely hands-down the best potatoes I have ever had, no questions asked. We buy them in a 20kg sack and they are fantastic, I don’t know the variety, all I know is they are perfect when oiled, seasoned and baked for 30 minutes. Unfortunately, earlier in the week we had eaten up all the nice lettuce that we have delivered, but we did cut some nice fresh red onion, red pepper, cucumber, and carrots for sides and toppings.

Putting it all together

I heated up the smoker with restaurant grade charcoal, seared the outside of the burgers for about 4 minutes sealing them nicely and only flipping them once. Then took them off the heat, and added some damp hickory on the charcoal and closed all the vents on the smoker. I added some cheddar (I didn’t have an really nice cheese, so sad) to the burgers and smoked them off heat for another 5 minutes whilst the cheese melted. Checked the burgers; just right with a slightly pink center. Inside, Emma was hard at work, finishing up the wedges, slicing buns, and cutting up the veg.


I added a bit of mayo, barbecue sauce, red onion and red pepper to the burger and dug in. And lets just say, I haven’t had a better burger in Britain and like all burgers, it down to the meat (maybe the buns, just a little bit).

In a time where we could complain that we can’t go out and that things are bad, I was able to sit with a lovely pint of cider, a delicious burger and enjoy the company of my family. Truely, we ate like kings and it certainly lifted our moods and our spirits. Food is important, it joins us together around the table, and it is something to be thankful for.

A huge thanks to Hal for raising cattle and delivering meat right to the doorstep.

Networking Scripting

Procurve Secure Configuration Manager

This is a simple script that obtains the current running configuration of HP Procurve switches via SCP, compares it against previously stored versions, and stores any updated copy in the appropriate directory.  Once there are 10 copies the oldest copy is deleted automatically.  Again, I am using Pexpect for the SCP connection and authentication is handled via public key authentication.  To setup public key authentication on the switch, see my previous post.

### The Procurve Public Key Automator Script needs to be run prior to utilizing this script ###

# Import modules needed for script
import pexpect
import sys
import time
import datetime
import os
import filecmp
import glob

# Change this to an appropriate directory that has read and write permissions for the user/group that will be running the script
path = '/var/sw_confs/'

# Create a dictionary to store all the devices and attributes
devices = {}

# Set Switches Attributes: make changes as necessary 
devices[('NYCoreSW-01')] =  ''
devices[('ATLCoreSW-01')] = ''
devices[('CHICoreSW-01')] = ''
devices[('LACoreSW-01')] = ''
devices[('SEACoreSW-01')] = ''

# Create the base directory for storing the configs
if not os.path.exists(path):
# Creates the individual directory for each switch
def sw_dir(host):
  conf_dir = path + host
  if not os.path.exists(conf_dir):
  return conf_dir

# Builds the filename based on date and time for each switch config
def file_name():
  systime = time.time()
  timestamp = datetime.datetime.fromtimestamp(systime).strftime('%Y_%m_%d-%H_%M_%S')
  fn = ('%s.conf' % timestamp)
  return fn

# Loop through each switch	
for host in devices:
  conf_dir = sw_dir(host) + '/'
  rc = 'running-config.tmp'
  # Connect to the switch via scp and download the running config
  s = pexpect.spawn('scp %s:cfg/running-config %s' % (devices[host], rc))
  s.expect(pexpect.EOF, timeout=10)
  # Create a list of files ending in .conf and store them in order of creation date	
  conf_list = filter(os.path.isfile, glob.glob("*.conf"))
  conf_list.sort(key=lambda x: os.path.getmtime(x))
  # Check for existing conf files within the specific switch's directory and compare the last saved with the current running and if it's different save a new copy otherwise delete the copy (rc) just downloaded.
  if len(conf_list) >= 1:
    compare = filecmp.cmp(rc, conf_list[-1])
    if compare == False:
      fn = file_name()
      os.rename(rc, fn)
    elif compare == True:
  elif len(conf_list) < 1:
    fn = file_name()
    os.rename(rc, fn)
  # We are only interested in keeping the last 10 versions of config, so remove the oldest version.
  if len(conf_list) >= 9:

Once you have the script edited, modify permissions so that it is executable, and setup a cron job to run as often as you’d like to ensure all switches are backed up.  The example below backs up the configs every 30 minutes on the hour and half-hour mark.

crontab -e
0,30 * * * * /path/to/script/

Post mailbox migration Exchange 2013 ActiveSync failures

There is an issue with Exchange 2013 first reported around the CU2 release date and is still an issue as of CU8.  The issue presents itself to existing users with an ActiveSynced device after mailbox migration.


  • Users experience an outage on mobile device for up to 16 hours, but typically it resolves itself within 8 hours.
  • Not all mailboxes are affected.
  • Not all devices utilizing the same mailbox are affected.  For instance, I had an iPhone and an iPad on the same account; the iPhone experienced no issues, but the iPad failed to connect.
  • Email can be sent from a device but not received.
  • Connection attempts to the server are rejected initially with a 130 – Access Denied error when viewing MDM logs or when utilizing tools such as LemonJar’s iOS Console utility.  Errors will eventually turn to IIS 403 – Forbidden errors after approximately 30 minutes of attempted connections.
  • EAS logs indicate that a user device is still being proxied to the server they were migrated from.
  • Issues appears to be completely intermittent in nature.

This is a result of the IIS application pools on the 2013 CAS not being made aware that the mailbox has moved.  The issue itself is easy enough to resolve by recycling IIS application pools: MSExchangeAutodiscoverAppPool and MSExchangeSyncAppPool on the 2013 CAS.  It may take up to 15 minutes after recycling the application pools for mail to begin to flow normally.

While researching this issue I came across an article by Jeff Guillet who has additional information and a script available on

Networking Scripting

Automate HP Procurve Client Public-Key SSH Authentication Setup

This is a simple SSH public key management utility for HP Procurve switches that is a prerequisite to the automated backup script that is coming soon.  It first removes any existing keys, enables the TFTP client on the switch and then downloads and installs new public keys.  *Please be aware that there isn’t very much error handling built into this script.

On a Linux box, install and configure a TFTP server.  I using Debian in this scenario.

su root
apt-get update
apt-get install tftpd-hpa
vim /etc/default/tftpd-hpa

Make appropriate edits to the config file, restart the service and exit from root

service tftpd-hpa restart

Generate an RSA key pair and copy the public key only to the TFTP server directory

cp /home/{username}/.ssh/  /srv/tftp/

If Pip and Pexpect isn’t installed yet:

pip install pexpect

You can also create RSA key pairs in PuttyGen and add the public key ONLY to the TFTP server directory.

Edit the script below with TFTP server information, public key names, and devices.

# Import modules needed for script
import pexpect
import getpass
import sys

#TFTP server name, use either IP address or hostname if resolvable
tftphost = 'myTFTPserver.local'

#TFTP has no directory content listing function, so each public key's file name must be listed here.
managerkeys = ('', '')
operatorkeys = ('backupserver_pub.key', '')

# Create a dictionary to store all the devices and attributes
devices = {}

# Set Switches Attributes and place them in the devices dictionary.
devices[('NYCoreSW-01')] = 'NYCoreSW-01', 'manager', '', '.*\w+[\w\)]#'
devices[('ATLCoreSW-01')] = 'ATLCoreSW-01', 'manager', '', '.*\w+[\w\)]#'
devices[('CHICoreSW-01')] = 'CHICoreSW-01', 'manager', '', '.*\w+[\w\)]#'
devices[('LACoreSW-01')] = 'LACoreSW-01', 'manager', '', '.*\w+[\w\)]#'
devices[('SEACoreSW-01')] = 'SEACoreSW-01', 'manager', '', '.*\w+[\w\)]#'

### Definitions ###
# Open Switch connections
def switch_connect(d):
    #Setup the connection
    s = pexpect.spawn(('ssh %[email protected]%s' % (d[1], d[2])))
    #Expect 3 different results from the connection attempt
    login_result = s.expect(['.*Are you sure you want to continue connecting','.*assword: ','Press any key to continue'])
    #Add SSH Keys to known hosts file if this is the first time connecting. 
    if login_result == 0:
    #Send password  
    elif login_result == 1:
        p = getpass.getpass('\nPlease enter the password for %s: ' % (d[0]))
    #If we already have keys installed on the switch then send a return key to bypass the MOTD  
    elif login_result == 2:
    #Repeat passowrd entry until password is correct  
    login_result = s.expect(['Press any key to continue', '.*assword:', d[3]])
    while login_result == 1:
        p = getpass.getpass('\nPlease enter the correct password for %s: ' % (d[0]))
        login_result = s.expect(['Press any key to continue', '.*assword: '])						
    #Enable configuration mode
    return s;

# Close Switch connections
def switch_close(d,s):
    #Save the config
    s.sendline('wr mem')
    #Close the connection to the switch

### Add Keys by looping through devices###
for d in devices.values():
  s = switch_connect(d)
  #Revoke existing manager keys
  s.sendline('clear crypto client-public-key manager')
  s.expect('continue [y/n]?')
  #Revoke existing operator keys
  s.sendline('clear crypto client-public-key operator')
  s.expect('continue [y/n]?')
  #Keys can only be uploaded via TFTP, eliminate the next 2 lines if not using SCP for file transfers
  s.sendline('no ip ssh filetransfer')
  #Allow public key authentication for SSH  
  s.sendline('aaa authentication ssh login public-key none')
  #Enable TFTP client
  s.sendline('tftp client')
  #Download manager keys from the TFTP server and install them
  for managerkey in managerkeys:
    s.sendline('copy tftp pub-key-file %s %s manager append' % (tftphost, managerkey))
  #Download operator keys from the TFTP server and install them              
  for operatorkey in operatorkeys:
    s.sendline('copy tftp pub-key-file %s %s operator append' % (tftphost, operatorkey))
  s.sendline('ip ssh filetransfer')              
  #Let us know which switches have completed
  print ('%s complete.' % (d[0]))
print 'Script Complete'

To run the script:

Networking Scripting

Python Scripting for HP Procurve Switches

I’ve working for the last several months on setting up a disaster recovery site, part of which required scripting network changes to streamline the process of making the site hot when necessary.  I wanted to connect from the scripting server to my networking devices via SSH for security purposes and I didn’t want to necessarily rely on using SSH keys.  For this task I chose to use Python 2.7 and Pexpect 3.3.  Initially I was hoping to use Pxssh which is included in Pexpect, but I was unsuccessful in getting being able to get Pxssh to work around issues with initial log-in messages and setting the command prompt.

I will create additional posts to supplement  this basic tutorial in the near future.

First, let’s make sure that the prerequisites are satisfied.

  1. You have a Linux machine of some variety available.
  2. You have Python 2.x installed.
  3. You have installed Pip, Pexpect and Netaddr
    pip install pexpect
    pip install netaddr

Let’s build a simple test to verify connectivity

# Import modules needed for script
import pexpect
import getpass

# Setup Username, Hostname and Password
hostname = raw_input('hostname: ')
username = raw_input('username: ')
password = getpass.getpass('password: ')

# Spawn SSH session to the host
s = pexpect.spawn('ssh %[email protected]%s' % (username, hostname))

# Expect the switch to prompt for a password
s.expect('.*assword: ')

# Send the password

# Expect the MOTD to end with 
s.expect('Press any key to continue')

# Send the return key

# Interact with the shell

Let’s drop:

# Interact with the shell

And add:

# Show the running configuration or substitute other commands
s.expect('.*\w+#') #Find the prompt
s.sendline('show running-config')

# Once the terminal window fills, we need to press the spacebar to continue printing the config
nextpage = s.expect(['--.*\w+l-C', '.*\w+#']) 
while nextpage == 0:
  # print everything before came before the continue message
  print s.before
  s.send(' ')
  nextpage = s.expect(['--.*\w+l-C', '.*\w+#'])
# Now we are out of the while loop so we need to print everything after that.
print s.after

In my next post, we’ll look at how to take the data gathered above and perform useful tasks with it.

Asterisk Hacking

Hacking voicemail: Warning, it’s scary simple.

Disclaimer: I do not under any circumstance condone hacking/phreaking or any other illegal activities.  This is an extremely simple proof of concept attack that should raise your awareness about the lack of security in voicemail networks and why you should never leave confidential information on any voicemail system.

Stealing voicemail is much easier simpler than most people believe.  Many voicemail systems use the caller ID number as the username for authentication for voicemail.  When no PIN number is set, simply spoofing caller ID allows an attacker to access to listen and delete voicemail, listen to deleted voicemail messages, modify call forwarding, and other account options.  I discovered this accidentally during testing while working on setting up my own phone server’s outbound caller ID.

How hard is it to spoof caller ID?  It’s extremely easy, a simple Asterisk phone server setup and a SIP PSTN service provider is all you need (to be anonymous, simply sign up for a SIP account using an email address only ever accessed through a VPN tunnel/Tor).  Just set the outbound caller ID to the number to be attacked and then dial the number to be attacked.  If there is a PIN number set, a simple script to try the last 4 digits of the number being attacked and the most common sequences (1234, 1111, etc) is easy enough to write.  Ensure the phone server is connecting to the SIP provider through anonymizing services such as VPN/Tor when making calls.

I have tested this on numbers that I own or manage voicemail on across several major US service providers.  I have been able to successfully attack all of them.  Some providers will pass the call through to the attacked phone (leaving a missed call) but will eventually go to voicemail if unanswered.

So why am I giving instructions?  Really, it’s more of a warning.  If you don’t have a PIN set, get it set.  If you see missed calls from your own number, then there is a good chance that someone is trying to hack your voicemail.  Don’t ever leave confidential or sensitive information in a voicemail.