| | Stumble It! | Add to Mixx! | | diigo it | | Slashdot |

Friday, January 22, 2010

Tabs Web Part

Before I get too far into this, let me first shine a light on another "tabbing" solution that was published a while ago by Christophe at Path to Sharepoint that, I feel, is a much more polished tabbing solution than this one.

The reason that I'm bothering putting any work into my own tabbing solution is that I'm more of a hobby hacker than a professional developer and I like to come up with solutions that don't require a great deal of ... shall we say ... coordination with third-parties. I'm unclear as to the privilege requirements needed to use Christophe's Easy Tabs Web Part, but I know that if I can add a web part to a page, I can implement this code without having to ask an admin to install anything for me.

So here's an example of what you'll end up with after pasting the code below into a Content Editor Web Part. And here's the code:
<span id='skip_this'></span>
<style type='text/css'>
.tab {
float:left;
color:darkgray;
margin:0px 3px -1px 3px;
padding:0px 3px -1px 3px;
border:1px black solid;
border-bottom:1px white solid;
font-size:1.5em;
cursor:pointer;
}
.actTab {
float:left;
font-size:1.5em;
margin:0px 3px -2px 3px;
padding:0px 3px -2px 3px;
border:1px black solid;
border-top:2px black solid;
border-bottom:2px white solid;
cursor:pointer;
position:relative;
z-index:10;
}
</style>

<div id='wpFrame' style='height:100%;width:100%;background:;'>
<div id='wpTabs' style='width:100%;background:;float:left;'>
</div>
<div id='wpBody' style='width:100%;border:1px black solid;float:left;'>
</div>
</div>

<script type="text/javascript">
// This will check to see if the page is not being edited, collect all the Web Parts on the page and put them in the Tab Format
// Also, you may specify, by Web Part Title, which Web Parts you would like to exclude from the Tab Format.
if (!document.getElementById("ctl00_WSSDesignConsole_IdDesignModeConsole_DesignModeContainer")) {
_spBodyOnLoadFunctionNames.push("setupTabs");
var webTabs=[];
var webParts=[];
var wpsToSkip=[''];
}

function setupTabs() {
var theTDs = document.getElementsByTagName('TD'); // collect all the TDs on the page
var wpTabs = document.getElementById('wpTabs'); // the DIV where the tabs will be added
var wpBody = document.getElementById('wpBody') // the DIV where the Web Part content will be added
for (var t=0;t<theTDs.length;t++) { // loop through all the TDs on the page
var i = theTDs[t].id;
if (i.match(/WebPartTitleWPQ/)) { // if it's a Web Part
var title = (theTDs[t].innerText || theTDs[t].textContent).replace(/[\n\r]/g,"");
i = i.substr(i.indexOf("WPQ"));
var wpBod = document.getElementById("WebPart"+i);
if (wpsToSkip.join().match(title) || // skip Web Parts that have been excluded
wpBod.firstChild.id == 'skip_this') { // skip the CEWP that holds this code
continue; // skip it
} else {
wpsToSkip.push(title); // add the Web Part being incorporated to the skip list to prevent duplication
}
// build a tab for the Web Part
var newTab = document.createElement("DIV");
newTab.innerHTML = title;
newTab.className = 'ms-WPTitle tab';
newTab.id = i;
addEv(newTab);
wpTabs.appendChild(newTab);
webTabs.push(newTab);
// incorporate the body into the tabbed display
wpBody.appendChild(wpBod);
wpBod.style.display = "none";
webParts.push(wpBod);
document.getElementById("MSOZoneCell_WebPart"+i).style.display = "none";
}
}
}

function showHide() {
var i = event.srcElement.id;
for (var t=0;t<webTabs.length;t++) { // bring the proper tab to the front
webTabs[t].className = (webTabs[t].id.match(i)) ? "ms-WPTitle actTab" : "ms-WPTitle tab";
}
for (var w=0;w<webParts.length;w++) { // display the body element for the tab selected & hide the rest
webParts[w].style.display = (webParts[w].id.match(i)) ? "" : "none";
}
}

function addEv(o) {
if (o.addEventListener) {
o.addEventListener("click",showHide,false);
} else if (o.attachEvent) {
o.attachEvent("onclick",showHide);
} else {
o.onclick = showHide;
}
return o;
}
</script>
Enjoy!

Monday, December 28, 2009

Tethering your non-rooted Android-based phone

My last article detailed how to use the Proxoid application on your Android-based phone which is all well and good, but you're stuck with HTTP and any protocols that can be tunneled over HTTP.

Thanks to ConnectBot, that's not a problem any more.

ConnectBot is a free(!) SSH client for Android that is capable of port-forwarding. Using ConnectBot and adb (from the Android SDK), it's possible to connect your laptop to ports on remote servers.

For example, at the end of this tutorial, you should be able to securely tunnel your web traffic over an SSH tunnel and your Android phone! But don't stop there, if your geek-fu is strong enough, you can connect to any number of services/servers via your phone's 3G connection.

Here's how to set up the SSH tunnel for web browsing:
Need to have:
1 - A laptop with:
a - SSH client - sudo apt-get install openssh-client
b - Web browser - http://google.com/chrome
c - Android SDK - http://developer.android.com/sdk/index.html
2 - Android-based phone with ConnectBot installed
3 - An SSH server with a public IP address
My setup:
1 - [Lappy] - Asus EeePC701 w/ Ubuntu 9.04
2 - Droid [Eris]
3 - [Desky] - VirtualBox on home PC running Ubuntu 9.10
Connections to be made:
0 - [Lappy]--(usb cable)---[Eris]
1 - [Lappy]---(./adb forward tcp:10022 tcp:10022)---[Eris]
2 - [Eris]---(ConnectBot port fwd:local, 10022, localhost:22)---[Desky SSH Server]
3 - [Lappy]---(ssh -D 9090 localhost -p 10022)---[Desky SSH Server]
4 - [Browser on Lappy]---(proxy socks, port 9090)---[Desky SSH Server]
So what the heck does all that stuff do? Let me explain:
0 - Plug your laptop into your phone with the USB cable. On Linux machines, I've found it necessary to start the "HTC Sync" application on the phone. Otherwise the adb application was unable to connect to the phone.
1 - From the command line on the Lappy, you're initiating the adb connection. This will forward ports on your laptop to ports on your phone. In our case, we're forwarding port 10022 on the laptop to port 10022 on the phone.
2 - From ConnectBot on the Eris, we're creating a SSH port-forward from port 10022 on the phone to port 22 on my SSH server. Now, any connections made to port 10022 on the Lappy will be forwarded to the phone which will, in turn, be forwarded to port 22 on the SSH server.
3 - From the command line on the Lappy, open a dynamic port forward on port 9090 on the Lappy to 'localhost' (a.k.a. the Lappy) on port 10022 (which is being forwarded to the SSH server port 22).
4 - In your browser on the Lappy, point it to use a SOCKS proxy of 'localhost' port 9090. Now when you hit "http://google.com" in your browser, it will be sent to port 9090 on your Lappy, which is tunneled over port 10022 on your lappy, which is forwarded to port 10022 on your phone, which is forwarded to port 22 on your SSH server, which is the end point for the dynamic port-forward on port 9090. Got all that? If you're a visual person, try this:
[Lappy Browser]
\
(SOCKS proxy - localhost:9090)
\
(ssh -D 9090 localhost -p 10022)
\
(./adb forward tcp:10022 tcp:10022)
\
[Eris]
\
(ConnectBot port fwd - local, 10022, localhost:22)
\
[SSH Server]
\
plain old internet

If you REALLY want to have some fun, connect your Lappy to your iperf server and you'll be able to check your bandwidth as you go =) I averaged about 200kb/s
1 - [Lappy]---(./adb forward tcp:15001 tcp:15001)---[Eris]
2 - [Eris]---(ConnectBot fwd:local, 15001, iperf_server:5001)---[Desky]
3 - [Lappy] $ iperf -c localhost -P 15001


Have fun and merry Christmas/Happy New Year! =)

Tuesday, December 22, 2009

Google Voice via SIP! (w/o Gizmo5)

If you were one of those people lucky enough to get a Gizmo5 account set up before Google bought it, you can ignore this post. If, however, you are like me and you want to be able to use your Google Voice number on a SIP softphone, read on.

First, a quick "so what" about the whole thing. At the end of this how-to, you should be able to place and receive free phone calls using a normal Plain Old Telephone System (POTS) number. Yep, place and receive. For free.

Second, a hat-tip to Bernal Schooley for the X-Lite registration tip!

Here's what you'll need in order to put this all together:
  • A Google Voice account (invite, free)
  • A VOIP/SIP capable device (computer, iPod, Droid, etc.)
  • An always-on broadband connection
Ok, so you have to pay for those last two things, but the phone service is free.

Once you have these three things, everything else is just a matter of filling out the proper online forms and such. Here is the list of other services that you'll need to sign up for in order to make the POTS to SIP transfer:
  • An IPKall.com account (free)
  • A PBXes.org account (free)
  • X-Lite SIP Softphone (free)
And now the caveats:
  • This may not be the best or most elegant method, but it works.
  • When/If GV finally releases their own SIP method (via the acquisition of Gizmo5), this method should be abandoned & you should use the native GV method.
  • Quality may be dodgy and there are a number of settings tweaks that can improve or harm your sound quality. Most of these settings changes can be tweaked in your SIP softphone.
  • If you find a better way, please share it with us here. It's about doing things better, not doing things my way.
  • I made a lot of configuration settings changes in my quest to get this working so if you encounter a road block, let me know as I may have simply neglected to include a certain setting in my documentation.
  • This is not a supported solution. It's very much held together with chewing gum & duct tape.
  • Each of the services that link together to give you your free phone service is a free service and may decide to stop being free at any time.
And now, the fun =)
Step 1 - PBXes.org
1a - Create account
1b - Create an Extension
1b1 - SIP (click)
1b2 - Extension Number: 100
1b3 - Display Name: (anything)
1b4 - Password: (pick a password)
1b5 - Voicemail: disabled
1b6 - After creating your extension, open it up and make these changes:
1b6a - dtmfmode: rfc2833
1b6b - audio bypass: no
1c - Add a Ring Group
1c1 - Group: 1
1c2 - ring strategy: ringall
1c3 - extension list: 100
1c4 - ring time: 60
1c5 - Destination if no answer: Extension [(anything) <100>]
1d - Add an Inbound Route
1d1 - Trunk: yourPBXes.orgUsername-100
1d2 - Destination: Extension: [(anything) <100>]
Congratulations, you now have your very own SIP extension. You should now be able to call other SIP phones, but let's not stop there, let's hook into the POTS network so you can call any phone!
Step 2 - phone.ipkall.com
2a - type: SIP
2b - area code: pick your prefix
2c - SIP Phone number: yourPBXes.orgUsername-100
2d - SIP Proxy: pbxes.org
2e - Email: youremail
2f - Password: yourPBXes.orgPassword
2g - Check your email for your SIP phone number
This phone number is able to receive calls from POTS phones. If you've done it right, you should be able to call this number and have your SIP softphone ring. Oh, but you'll need to set up a SIP softphone first, here's how:
Step 3 - Install X-Lite
3a - Download and install X-Lite: http://www.counterpath.com/x-lite-download.html
3b - Set up your PBXes.org account:
3b1 - Display Name: PBXes.org
3b2 - User name: yourPBXes.orgUsername-100
3b3 - Password: yourPBXes.orgPassword
3b4 - Domain: pbxes.org
3b5 - Check for voice mail: unchecked
3b6 - You should be connected, if you call your IPKall number it should ring the X-Lite client
3b - After install, launch X-Lite and dial "***7469" to open the config
3b1 - Enter "dtmf" for the filter and make sure "system:dtmf:force_send_in_band" is set to "1"
3b2 - Enter "2833" for the filter and set "rtp:2833:enabled" to "0"
The last three steps are necessary for registering your number with Google Voice. The process of registering a SIP phone with Google Voice is a bit tricky at the moment. There are some differences in how GV interprets the touch tones of the registration code and how SIP softphones encode tones. Steps 3b, 3b1, & 3b2 should help bridge the gap.
Step 4 - Add Number to Google Voice
4a - Log in to Google Voice
4b - Settings > Phones > "Add another phone"
4b1 - Name: "SIP"
4b2 - Number: yourIPKallNumber
4b3 - Phone Type: Home (You can change this later)
4b4 - Save
4c - Verify the number
4c1 - Google will call your X-Lite client & ask you for the 2-digit code
4c2 - Click the buttons on the X-Lite pad & your number should be registered
4c3 - You can now make any changes to your GVoice "SIP" profile
If step 4c doesn't work for you, please let me know! It took me a LOT of configuration changes to get a combination of settings that finally worked and I grew very accustomed to the Google Voice lady telling me, "Sorry, I didn't understand that. Please enter the two-digit code from the website." The settings that you see on this page are the settings that I had when I finally heard her say, "This phone is now registered with Google Voice. Thank you."
Step 5 - Enjoy!
You should now be able to place a call to your Google Voice number and have the X-Lite (or other SIP softphone) ring.
When you're done, you should be able to use Google Voice to place a phone call that will first call your SIP phone and then call the number that you were dialing. For free.

The connection is as follows:
Inbound calls:
Caller > GV > IPKall > PBXes > Your SIP softphone

Outbound calls:
1) GV > IPKall > PBXes > Your SIP softphone
2) Phone # you're calling < GV

Wednesday, December 16, 2009

Ubuntu Laptop Tethered to Droid Eris via Proxoid

I finally got it sorted out and I can now connect my lappy (EeePC 701) through my Eris' internet connection (3G or WiFi). Technically it's a proxy and not a tether, but IP by any other name is still teh tubes.

Here's how I got it working:
The Eris
1 - Install "Proxoid" from the Market
2 - Configure the port number - I used 8181
3 - [Optional] Set up your user-agent filter
4 - Start Proxoid
5 - Connect your phone to your laptop via USB
6 - In the alert menu (swipe down from the status bar), tap 'HTC Sync' - you can ignore the fail message

The Lappy
1 - Create the following file
$ sudo gedit /etc/dev/rules.d/11-android.rules
with these two lines:
SUBSYSTEMS=="usb", SYSFS{idVendor}=="0bb4", SYSFS{idProduct}=="0c02", MODE="0666", OWNER="yourusername"
SUBSYSTEMS=="usb", SYSFS{idVendor}=="0bb4", SYSFS{idProduct}=="0c01", MODE="0666", OWNER="yourusername"

2 - Restart udev
$ sudo /etc/init.d/udev restart

3 - Download and extract the Android SDK - http://developer.android.com/sdk/index.html
4 - Install corkscrew
$ sudo apt-get install corkscrew

5 - Create the following script with executable privs: (CAUTION, this will overwrite your ~/.ssh/config)
#!/bin/bash
if [ "$1" == on ]; then
echo "TURN IT ON"
/path/to/android-sdk-linux_86/tools/adb forward tcp:8181 tcp:8181
echo "Host *" > ~/.ssh/config
echo " ProxyCommand corkscrew localhost 8181 %h %p" >> ~/.ssh/config
elif [ "$1" == off ]; then
echo "TURN IT OFF"
/path/to/android-sdk-linux_86/tools/adb kill-server
rm ~/.ssh/config
else
echo "So are you going to turn me 'on' or 'off'?"
fi

6 - Start the tether
$ ./tether.sh on

7 - In Firefox - Preferences > Advanced > Network > Connection Settings > Manual proxy
> HTTP Proxy = localhost
> Port = 8181
> Use this proxy server for all protocols = yes
7.1-I just use the FoxyProxy Basic add-on to manage all this for me
Don't expect to be able to watch Hulu or anything, but you should be able to check your email or connect via SSH with ease =)

Please let me know if any part of this doesn't work for you or if you find a better way to do it.

Cheers!

Monday, December 14, 2009

Cisco Hardware Inventory Web App v0.1a

If you're one of those people that manages a bigish Cisco network, you might also know that tracking inventory for those Cisco devices can be very painful. Each router and switch has several different cards and ports installed, each with it's own serial number. Multiply that by, say, 50 routers and your Excel spreadsheet is getting pretty big.

Oops, now that SFP died and had to be RMAed, but you were too busy soothing an angry user that couldn't check email for 2 hours while you were troubleshooting and you forgot to update the entry on your spreadsheet so now you have the wrong serial number.

GAH!


This little (11k) bit of code will collect inventory information from your Cisco routers and present it in a simple, but effective web page. To get it working, you'll need a webserver (I use XAMPP on a virtual install of Xubuntu) running PHP that has the expect package installed.

The gory details on how to get it running are available on the project page, but feel free to contact me if you need help getting it set up on your network.

Friday, December 11, 2009

Introducing the Eris

"There are many like it, but this one is mine."
-The Rifleman's Creed

Yep, I got a Droid Eris.

Actually, I got it about a week ago and I've been so busy figuring it out (and working) that I've been neglecting the blog. Mea culpa.

So what do I think of it so far? It is awesome. I had been using a BlackBerry Pearl for the last 2ish years so to upgrade to a large touch-screen with a Linux-based OS is a very good change!

The screen is large, bright and clear. It's very responsive to the touch input and the keyboard, even in portrait mode, is still very usable even with my big fingers (I'm 6'4" and have 'big' hands for my size).

The only disappointment I've had so far with it is the Proxoid application doesn't work with my EeePC. The instructions say to use the Android 1.5 SDK to complete the connection, but all I could find was the 2.0 SDK so I'm not sure I'm doing it right and I haven't put any serious effort into solving it just yet.

While I'm on the topic of third-party apps, here's the list of apps I've installed so far (all free):
  • Listen (podcast app, just starting to figure it out)
  • Places Directory (Google's find local business app)
  • My Tracks (for hiking/travelling)
  • Google Sky Map (to show how cool the positioning is)
  • Andoku (Sudoku)
  • RemoteDroid (remotely control a PC's mouse & keyboard)
  • Layar (augmented reality - very cool)
  • Astro (file/task manager)
  • Dolphin Browser (replacement web browser w/ touch gestures)
  • Mobiqpons (coupon app)
  • Android LightSaber (for battling my iPhone counterparts)
  • Proxoid (proxy app that is supposed to let me use my phone's data plan to surf w/ my laptop)
  • Qik (live video streaming from my phone to the web - also very cool!)
  • TV.com (for when I'm bored of Sudoku)
  • Ringdroid (haven't used it much, create custom ringtones)
  • ScanLife (for reading those cool square bar codes)
  • SlackerRadio (cuz slacker.com is awesome!)
  • DigitalClock (turns the phone into a big digital clock)
  • Yelp (it's ... yelp)
  • Compass (for fun navigation)
  • G-MoN (doing my part to map the WiFi world)
  • Finance (because I like to pretend I know what's going on in the financial world)
  • Network Widget (display's network info on the 'desktop')
  • Google Voice (I don't even use the regular phone number any more)
  • Network Discovery (a port-scanner on my phone!)
  • LiveBible (not entirely happy with the navigation, but it's the best one I've found so far)
  • NetCounter (for tracking my network usage)
  • ConnectBot (MUST HAVE APP!!! - lets you SSH to remote hosts & provides a console to your phone!)
  • DynDNS (so I can track my phone via IP)
  • VLC Remote (control a running VLC instance on your desktop)
  • MyIP (displays my network info)
  • SilentMode OnOff (one touch silent mode)
  • Where's My Droid (send a text to have your phone start ringing even if it's on silent)

Friday, December 4, 2009

Tschuss, Expert's Exchange!

I've had it with Expert's Exchange. Almost every time I search Google for something technically oriented, I get results from Expert's Exchange that seem to be exactly what I'm looking for and without bothering to look at the site providing the answer, I eagerly follow the link only to find that my supposed solution is hiding behind a pay wall.

SRSLY?! You want me to pay for this stuff?

I know, I know - they've got to make a living too and all that so I can't be too hard on them. But I have decided that I won't tease myself anymore with near solutions. Instead I wrote this little script to simply block the display of links pointing to Expert's Exchange in Google search results.


BAH!