Author: admin

  • Garland  & Garmin Greetings

    Garland & Garmin Greetings

    My office at work wasn’t feeling very Christmas-like, so I flaked out a little and hatched a plan to address the stark lack of festiveness.

    I have a bunch of these old Garmin Nuvi 5000 model GPS displays in my office right now.

    garmin_5000

    We are replacing our fleet management software and with it our vehicle tracking system.

    Both the old and the new system have the ability to connect to Garmin GPS displays via FMI cable in order to push waypoints and information to the driver. Unfortunately the Garmin Nuvi 5000 displays are kind of old at this point, the FMI interface isn’t compatible with our new system (hence a pile of GPS screens on my desk). This cable previously wired in to the vehicle accessory power.

    garmin_fmi_serial

    I compiled a pile of useful ingredients.
    christmas_tools

    I twisted the power wires of the FMI cables together, soldered it up to some spare wire, and covered it with some shrink tube.
    fmi_twisted

    fmi_twisted_soldered

    Using the multimeter I measured the current of one of the Garmin displays, it fluctuated a bit as the system booted up and looked for satellites, but it seemed to stay pretty well under 150mA. I ended up using 6 Garmins, so figure maybe 900mA, add some buffer room, and I decided that this 12 volt DC 2 Amp power supply would be a good donor.

    garmin_xmas_power

    The whole time I had Garmin’s commerical jingles stuck in my head.

    Peace & Joy

  • Bash Snippet: Decimal to Binary Conversion

    Bash Snippet: Decimal to Binary Conversion

    Convert a decimal value into the binary representation and vice versa in Bash using only built-ins. If you know a better way, please let me know. To ensure a properly formatted expression for the arithmetic expansion in bin2dec, the dec2bin function prefixes zeros as needed to pad to a character count evenly divisible by 8.

    dec2bin () {
        num="$1"
        bin=""
        padding=""
        base2=(0 1)
        while [ "$num" -gt 0 ];
        do
                bin=${base2[$(($num % 2))]}$bin
                num=$(($num / 2))
        done
        if [ $((8(${#bin} % 8))) -ne 8 ]; then
                printf -v padding ‘%*s’ $((8(${#bin} % 8)))
                padding=${padding// /0}
        fi
        echo $padding$bin
    }


    bin2dec () {
            echo $((2#$1))
    }

    Examples:

    user@host:~$ dec2bin 1
    00000001
    user@host:~$ bin2dec 00000001
    1
    user@host:~$ dec2bin 255
    11111111
    user@host:~$ bin2dec 11111111
    255
    user@host:~$ bin2dec 1010101010101010
    43690
    user@host:~$ dec2bin 43690
    1010101010101010

    Perhaps not the most efficient way, but at least for small numbers it appears to be quicker than opening a subshell.

    user@host:~$ time dec2bin 43690
    1010101010101010

    real    0m0.001s
    user    0m0.000s
    sys 0m0.000s
    user@host:~$ time echo "obase=2;43690" | bc
    1010101010101010

    real    0m0.002s
    user    0m0.000s
    sys 0m0.000s
  • Detect Wi-Fi Clients on your DD-WRT Router

    Here is a script I wrote that scrapes the web interface of a router running DD-WRT. The script looks for the MAC addresses of wireless users. When it sees a MAC address that it hasn’t logged before it issues an alert. To help identify the new equipment, a portion of the MAC address is sent to an IEEE OUI database search (Internet connection required) to determine the manufacturer name. This script is intended to be ran periodically from crond on a system other than the router. When the script detects a new MAC address it writes to STDOUT, in most cron configurations this will result in an email being generated to the local system user running the process, or to another address specified in the MAILTO variable.

    Sample /etc/crontab entry

    MAILTO="5558675309@sms.mobile.example.org"
    * * * * *       root    /usr/local/sbin/wifi-macs.sh

    Sample output generated when a new iPhone connects to the ‘MySSID’ network.

    Alert new client found on MySSID MAC: 040CCECAFE00 (Apple, Inc.)

    Download wifi-macs.sh

    #!/bin/bash

    #Set the username used for web access to the router
    ROUTER_USER="root"
    #Set the password used for web access to the router
    ROUTER_PWD="admin"
    #Set the IP address where the router can be reached, optional port
    #number can be specified like 192.168.1.1:80
    ROUTER_IP="192.168.1.1"

    #If you have your router setup to support https, change to https
    PROTO="http"

    LOGS="/var/log/wifi"

    read_macs () {
            while read line
            do
                    if [ "${line//active_wireless/}" != "$line" ]; then
                            OFS="$IFS"
                            IFS="\’"
                            for word in ${line[@]}
                            do
                                    if [ "${#word}" -eq "17" ]; then
                                    mac="${word//:/}"
                                            if [ "${#mac}" -eq "12" ]; then
                                                    echo "$mac"
                                            fi
                                    fi
                            done
                            OFS="$IFS"
                            mac=""
                            word=""
                    fi
            done
    }

    read_ssid () {
            while read line
            do
                    if [ "${line//wl_ssid/}" != "$line" ]; then
                            line="${line##*"wl_ssid::"}"
                            line="${line%%"}"*}"
                            echo "
    $line"
                    fi
            done
    }

    read_company () {
            while read line
            do
                    if [ "
    ${line//"(base 16)"/}" != "$line" ]; then
                            line="
    ${line##*'(base 16)’}"
                            line="
    ${line:2}"
                            echo "
    $line"
                    fi
            done
    }


    if ! [ -d "
    $LOGS" ]; then
            echo "
    Logs directory $LOGS does not exist" >&2
            exit 1
    fi

    wldata="
    `curl -s –user $ROUTER_USER:$ROUTER_PWD $PROTO://$ROUTER_IP/Status_Wireless.live.asp`"
    ssid="
    `echo $wldata |read_ssid`"
    macs=(`echo $wldata |read_macs`)

    for mac in ${macs[@]}
    do
            if ! [ -f "
    $LOGS/$mac" ]; then
                    company="
    `curl -s "http://standards.ieee.org/cgi-bin/ouisearch?${mac:0:6}" |read_company`"
                    echo "
    Alert new client found on $ssid MAC: $mac ($company)"
                    echo "
    New MAC Address detected: `date`" >>$LOGS/$mac
                    echo -e "
    ${mac:0:6}\t\t$company" >>$LOGS/$mac
                    echo -e "
    Additional Data:\n$wldata" >>$LOGS/$mac
            fi
    done
  • Import Nextel iDEN Contacts to Google

    Import Nextel iDEN Contacts to Google

    Sprint is decommissioning it’s Nextel iDEN network in 2013. The Nextel network has been very popular with businesses for it’s push-to-talk (PTT) “walkie-talkie“-like service. Several rugged (and bulky) mobile phones like the Motorola i355 and i365 are well adapted to the sometimes harsh environments of field work and clumsy service technicians. Unfortunately it seems that many of these phones will outlive the network that supports them, leaving just SouthernLINC and a handful of small regional providers to offer any iDEN network service in the U.S. market.

    It seems that everyone is switching to smartphones these days, and my office is no exception. One of the nicest features from an information technology standpoint about this new generation of phone is cloud integration. Frequently setting up one Exchange server or Google Apps account on the phone will synchronize calendars, contacts, and email. It soon became apparent while migrating the staff off their beastly “dumb”-phones that people were going to be spending a lot of time manually transferring their contacts from one phone to the other. To speed up the process I created a VBScript that works with the Motorola iDEN Phonebook Manager to export the phone book Jet database into a CSV file compatible with Google Contacts.

    EDIT: Updated to add a kludgy work-around for 64-bit Windows

    Download iden2googlecontacts.zip

    CSVname = "export.csv"
    DBname = "import.mdb"

    ‘Optional Usage: iden2googlecontacts.vbs SourceDB TargetCSV

    If WScript.Arguments.Count => 1 Then
        DBname = WScript.Arguments(0)
    End If
    If WScript.Arguments.Count => 2 Then
        CSVname = WScript.Arguments(1)
    End If


    ‘So I guess this doesn’t work with the default WSH interpreter on 64-bit versions of Windows
    If WScript.Arguments.Count < 3 Then
        Set objShell = CreateObject("WScript.Shell")
        If objShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE") = "AMD64" Then
            WINDIR=objShell.ExpandEnvironmentStrings("%WINDIR%")

            Set fs = CreateObject("Scripting.FileSystemObject")
            If Not fs.FileExists(WINDIR & "\SysWOW64\wscript.exe") Then
                WScript.Echo WINDIR & "\SysWOW64\wscript.exe"
                WScript.Echo "Warning: Can’t find 64-bit Wscript.exe, this probably won’t work."
                Set colSystemEnvVars = Nothing
                Set objShell = Nothing
                Set fs = Nothing
            Else
                ‘The script won’t fork if there are 3 or more arguments on the command line
                Command = WINDIR & "\SysWOW64\wscript.exe "
                Command = Command & Chr(34) & WScript.ScriptFullName & Chr(34)
                Command = Command & " "
                Command = Command & Chr(34) & DBname & Chr(34)
                Command = Command & " "
                Command = COmmand & Chr(34) & CSVname & Chr(34)
                Command = Command & " "
                Command = Command & "NO_FORK"
                objShell.Run Command
                WScript.Quit
            End If
        End If
    End If
    ‘OK Things should be back to normal at this point

    If InStr(CSVname, "") = 0 Then
        Set objShell = CreateObject("WScript.shell")
        CSVname = objShell.CurrentDirectory & "" & CSVname
        Set objShell = Nothing
    End If

    If InStr(DBname, "") = 0 Then
        Set objShell = CreateObject("WScript.shell")
        DBname = objShell.CurrentDirectory & "" & DBname
        Set objShell = Nothing
    End If

    Set fs = CreateObject("Scripting.FileSystemObject")
    If Not fs.FileExists(DBname) Then
        WScript.Echo "Error: Database " & DBname & " was not found!"
        WScript.Quit
    End If
    Set fs = Nothing

    WScript.Echo "Exporting " & DBname & " to CSV file " & CSVname

    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objTextFile = objFSO.CreateTextFile(CSVname, True)

    i=0

    objTextFile.Write("Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Group Membership,E-mail 1 – Type,E-mail 1 – Value,E-mail 2 – Type,E-mail 2 – Value,Phone 1 – Type,Phone 1 – Value,Organization 1 – Type,Organization 1 – Name,Organization 1 – Yomi Name,Organization 1 – Title,Organization 1 – Department,Organization 1 – Symbol,Organization 1 – Location,Organization 1 – Job Description" & vbCRLF)

    SQL = "SELECT ContactName, Number, NumberType FROM tblContactList WHERE NumberType<>1 AND NumberType <= 6;"

    set oConn=CreateObject("ADODB.Connection")
    oConn.Open "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" & DBname & ";"
    Set oRS=oConn.Execute(SQL)

    Do While Not oRS.EOF
            ‘Name
        objTextFile.Write(oRS.Fields("ContactName"))
        objTextFile.Write(",")
        ‘Given Name
        objTextFile.Write(",")
        ‘Additional Name
        objTextFile.Write(",")
        ‘Family Name
        objTextFile.Write(",")
        ‘Yomi Name
        objTextFile.Write(",")
        ‘Given Name Yomi
        objTextFile.Write(",")
        ‘Additional Name Yomi
        objTextFile.Write(",")
        ‘Family Name Yomi
        objTextFile.Write(",")
        ‘Name Prefix
        objTextFile.Write(",")
        ‘Name Suffix
        objTextFile.Write(",")
        ‘Initials
        objTextFile.Write(",")
        ‘Nickname
        objTextFile.Write(",")
        ‘Short Name
        objTextFile.Write(",")
        ‘Maiden Name
        objTextFile.Write(",")
        ‘Birthday
        objTextFile.Write(",")
        ‘Gender
        objTextFile.Write(",")
        ‘Location
        objTextFile.Write(",")
        ‘Billing Information
        objTextFile.Write(",")
        ‘Directory Server
        objTextFile.Write(",")
        ‘Mileage
        objTextFile.Write(",")
        ‘Occupation
        objTextFile.Write(",")
        ‘Hobby
        objTextFile.Write(",")
        ‘Sensitivity
        objTextFile.Write(",")
        ‘Priority
        objTextFile.Write(",")
        ‘Subject
        objTextFile.Write(",")
        ‘Notes
        objTextFile.Write(",")
        ‘Group Membership
        objTextFile.Write(",")
        ‘E-mail 1 – Type
        objTextFile.Write(",")
        ‘E-mail 1 – Value
        objTextFile.Write(",")
        ‘E-mail 2 – Type
        objTextFile.Write(",")
        ‘E-mail 2 – Value
        objTextFile.Write(",")
        ‘Phone 1 – Type
        Select Case oRS.Fields("NumberType")
            Case "0"
                objTextFile.Write("Mobile")
            Case "2"
                objTextFile.Write("Home")
            Case "3"
                objTextFile.Write("Work")
            Case "4"
                objTextFile.Write("Mobile")
            Case "5"
                objTextFile.Write("Work Fax")
            Case "6"
                objTextFile.Write("Pager")
            Case else
                objTextFile.Write("Mobile")
        End Select
        objTextFile.Write(",")
        ‘Phone 1 – Value
        objTextFile.Write(oRS.Fields("Number"))
        ‘Organization 1 – Type
        objTextFile.Write(",")
        ‘Organization 1 – Name
        objTextFile.Write(",")
        ‘Organization 1 – Yomi Name
        objTextFile.Write(",")
        ‘Organization 1 – Title
        objTextFile.Write(",")
        ‘Organization 1 – Department
        objTextFile.Write(",")
        ‘Organization 1 – Symbol
        objTextFile.Write(",")
        ‘Organization 1 – Location
        objTextFile.Write(",")
        ‘Organization 1 – Job Description
        objTextFile.Write("," & vbCRLF)
        i = i + 1
        oRS.MoveNext
    Loop

    objTextFile.Close
    Set objFSO = Nothing

    If i > 1 Then
        WScript.Echo "Exported " & i & " record"
    Else
        WScript.Echo "Exported " & i & " records"
    End If

    If oRS.State = 1 or oRS.State = True Then
        oRS.Close
            oConn.Close
            set oRS = Nothing
            set oConn = Nothing
    End If

    The Motorola iDEN Phonebook Manager is a free download, but you’ll need a cheap cable (available on eBay for under $5 for many phones) to dump the contacts off the iDEN SIM card.

    Dock the phone to the USB cable and connect it to the computer you’ll be working with. You may be prompted to install additional drivers for your phone, but most of what you need will probably be included with the Motorola iDEN software download.

    Open up Motorola iDEN Phonebook Manager and select “New/Edit Phonebook“.

    Next select “Load From Phone“.

    The software will prompt you to make sure the cable is connected between the phone and computer. Press “OK“.

    An activity screen will open showing communication in progress between the computer and the phone.

    The phone’s display may also show some indication of something unusual happening (as seen on an i355) or may just go blank (i365).

    Once all the contacts are imported click the “Continue” button on the bottom of the window.

    Select “Save To File“.

    Pick a name for your file. I chose “import.mdb“, if you choose something else, you’ll have to edit the VBScript accordingly. Remember where you save the file.

    Download iden2googlecontacts.zip and extract the iden2googlecontacts.vbs script into the same directory as your phone book export (“import.mdb” in this example).

    Edit the script to change the input or output file names if required. When you are ready to run the script, double-click on iden2googlecontacts.vbs. The script will output the file names for verification, or warn you if it is unable to find the database to import contacts from.

    When the script is complete it will tell you how many contacts it exported into the new CSV file (named export.csv by default).

    Armed with the new CSV file export you just created, open up Google Contacts. under the “More” button choose “Import…“.

    Click the “Choose File” button.

    Navigate to the location where your export file was created and select the file (export.csv in this example). Click “Open” to proceed.

    Click the “Import” button.

    If everything worked OK, you should now see the new contacts. Click “Find & merge duplicates” to reconcile the import with any contacts the user may have already had in Google Contacts.

    To be useful on the smartphone you may have to move these contacts to the “My Contacts” group label. Click the square selection box as shown below and then choose “All” to select all contacts.

    Click the group button (the thing with three heads on it) and remove the check mark from the auto-generated label (shown here as “Import 9/28/12”). Place a check mark next to “My Contacts” and click “Apply

    The contacts should all be removed from the auto-generated group label. You may optionally remove this group label now. Click the “More” icon again and choose “Delete group“.

    Google will prompt you to confirm the deletion.

    That’s it. Depending on the model of your mobile phone additional steps may be required to resynchronise your contacts with the server, but many phones handle this automatically.

    If you are processing many phone books, consider the following command for batch processing

    for %f in (*.mdb) do cscript iden2googlecontacts.vbs %~nf.mdb %~nf.csv

    If you use this script and find it helpful (or run into problems), please let me know in the comments.