Saturday, May 15, 2010

Using Ubuntu 10.04 LTS server for Subversion

My old subversion server is in need of a bit of an upgrade. I decided to move it to one of my VMware ESXi servers. (Yes, I really have ESXi servers in my basement. What can I say?) Anyway, since this is a low volume service, moving to an ESXi server seems to be the most economical way to keep my code safe without running the power bill (any farther) through the roof.

Since I have enough VMs to keep track of, I am going to build this one on Ubuntu 10.04 LTS, since Ubuntu seems easier to keep up-to-date. However, taking you step-by-step through the installation isn't something I am going to do. Rather, I will comment on any "non-standard" steps I take, and then include all of the follow-up information needed to get the subversion server up and running.

When I installed the server, I didn't select any of the options on the type of server I wanted to set up. Instead, I just continued past that screen and completed the installation. Once the machine rebooted, I logged in with the account I created, and got to work.

The first two things you will probably want to do is set a static IP address for your server, and install the openssh server so you can work on the machine remotely. Setting the static IP is easy. Good instructions can be found here : http://www.howtogeek.com/howto/ubuntu/change-ubuntu-server-from-dhcp-to-a-static-ip-address/. Installing OpenSSH is also easy. At the server's command line run the command "sudo apt-get install openssh-server".

Once the IP address is set, you will either need to reboot the machine, or manually change the address by hand. I suggest a quick reboot, as it shouldn't take too long. Once the machine reboots, we can get on to setting up and configuring the subversion server.

There are several different ways to configure a subversion server. And I have used many of them. By far, my preferred method is to do subversion over http as the Tortoise SVN client for Windows will let me cache my username and password in this mode, and not have to enter it a bunch of times anytime I do any work in the repository.

So, the first thing we need to do is install Apache. I went ahead and installed it using the command "sudo apt-get install apache2". After a few seconds, I had Apache installed and ready to rock.

The next thing I needed to do was actually install subversion. This is easily done by running the command "sudo apt-get install subversion". After a few more seconds, I had subversion installed.

If we Google around, we can find some information on what to do next at https://help.ubuntu.com/community/Subversion. The only problem is, that I am using the server version, so the UI steps are of little help. But no problem, we can easily do the same thing from the command line!

First, we want to create a subversion group to use. To do that, we need to run the command "sudo addgroup subversion". You should get a message indicating that the group was added, along with listing the GID (group ID) of the group that was just created.

To do that, run the command "sudo nano /etc/group", then find the group we just created, and add both "www-data" and your username to the end of the subversion group line.

Now, you should be a member of the subversion group, but you will need to log out and back in before the change will take affect. So do that now.

Next, we need to create the directories to store the files that we upload via subversion. To do that, execute the following commands :

cd /home
sudo mkdir svn
cd svn
sudo mkdir repo
sudo svnadmin create /home/svn/repo


Then, fix the permissions with these commands :

cd /home/svn
sudo chown -R www-data:subversion repo
sudo chmod -R g+rws repo

Now, to bring things full circle, we need to make sure we have the Apache 2 SVN libraries installed. To do that, run the command "sudo apt-get install libapache2-svn".

Now, we need to edit the Apache config so that it knows how to deal with the subversion requests. Change in to the directory /etc/apache2/mods-available, and run the command "sudo nano dav_svn.conf". Then, add the following block to the end of the file to enable subversion through Apache :


DAV svn
SVNPath /home/svn/repo
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/subversion/passwd

Require valid-user




Whew! This is a lot of work. BUT, we are almost there! The last thing we need to do is set up authentication for the web interface so that not just anyone can muck around in our repository. Doing that is easy. Run the command "sudo htpasswd -c /etc/subversion/passwd " where is replaced with the user name you want to use to log in. To add additional users, use the same command line, but remove the "-c" option. (If you don't remove the -c option you will erase the first user you created!!!)

Congratulations! At this point, you should have a subversion server all set up! To access the server, you would use the URL http://
/svn .

What does it take to add the Mob to your existing Android applications?

When I get bored, I code. And when I get money hungry, I also code. I currently have one app out on the Android marketplace, that has been downloaded several times. In all honesty, I didn't expect the app to become the next big thing. I also wasn't sure it would be useful to people beyond myself. But, it seems that there are at least a few other people out there that believe my Movie Track app has some value.

Now, to be fair, I am all for free apps. I have done a lot of free open source development in my time, and have generally enjoyed it. But, I also like to get a little something extra out of my work when possible. So, I have decided I am going to try adding AdMob to my Movie Track program, and see if I can generate a few bucks along the way. (For those that hate ads, I'll also offer an ad-free version for $1.)

Signing up for AdMob is pretty easy. Just hop over to the AdMob web site, and create a new account. Once the account is created, you will get an e-mail with a link that needs to be clicked in order to verify the e-mail account is yours. But, once you have done that, it starts to get confusing in a hurry as to what to do next.

First, some terminology. When I first logged in with my shiny new account, there was a lot of talk about "Advertisers" and "Publishers". Since we are putting ads in to our programs, we are "Publishers". So, unless you want to advertise things in other people's programs, you should look for information that pertains to publishers.

Once you log in to the site, and click on the Marketplace link, the Campaigns tab shows information that is only relevant to advertisers. Or does it? Clicking on the "New Advertiser Training Videos" takes you to a page with videos about how to use AdMob to advertise new products and services. However, if you scroll down toward the bottom of the page, you will also find that there are videos for publishers down there as well.

A quick look at some of those links tell us that we need to create an Android App profile on the AdMob site in order to allow us to put ads in, and track the results. To do this, we need to hover over the "Sites & Apps" tab, and select the "Add Site/App" option from the drop-down menu. Next, click on the "Android App" icon, and scroll down to enter the rest of the information.

As you fill this form out, there is a section for the Android package URL. The help information that is available says it must be a mobile site, or the URL to your package in the market place. (The FAQ says the URL in the market place will be formatted as : market://details?id) However, digging around, it seems there should be a "=" between the "id" and the "". You can find more information at http://developer.android.com/guide/publishing/publishing.html.

This left me with a couple of questions that I will probably post more about later as I dig deeper. The first one is, "What is this URL used for?". And the second is, "What if I have not yet published the app? What do I put in there?".

Since this field isn't in bold, I am going to guess that it may not be important what goes in there. But, I like to be complete where possible, so I will be putting in the link to my app in the form of "market://details?id=info.geektaco.movietrack". For the category, I selected "Entertainment", and then I entered a description of the Movie Track program, and clicked the "Continue" button.

It would appear that I entered the correct information, as the next screen I was presented with is a link to download the "Install Code" to add to my program. I went ahead and grabbed the SDK, and a copy of the PDF version of the SDK documentation for later use, and then clicked "Go to Sites/Apps".

Now, we are getting somewhere. We should now see the dashboard for AdMob. In the dashboard is a link to update your payment information. That part seems pretty straight forward, so I won't go in to detail here.

And now, for the fun part! Let's add the ads to our program, and go make some money!!!

(Continued in later posts)

Friday, May 14, 2010

The final(?) word on the QuickPhones phone.

It has been a while, but a few weeks ago I go another update from the QuickPhones guys about the multiple AP issue that I ran in to. I was extremely disappointed to hear that they were unable to find a fix for the multiple AP issue, and have given up trying.

So, what can I say? I will still tell you that this phone has the best battery life of any of the lower priced wifi phones out there. (I have not had a chance to try the more expensive ones. Feel free to contact me if you want to send me one!) When I didn't have it associated to a network, and just sitting on my desk the battery lasted about a month. When connected to an AP, the battery lasted about a week.

Now, just to be clear, it is possible that this phone would work perfectly on wireless gear that "pretends" to be a single huge AP. The one that comes to mind is Meru networks. I have some Meru gear that I am going to install, and will post a follow-up on this phone once I get it installed.

I have, however, discovered a bit of a workaround to the multi-AP issue. If you happen to have a single AP around that can broadcast another SSID, you can still use the phone in an area with multiple APs on one SSID. To do this, you need to shut down all of the APs that are broadcasting the same SSID so that the phone can pick up the AP that is single.

That didn't make a lot of sense, so let me expand on it. Lets say you have 5 "brand X" APs, all broadcasting an SSID called "CorporateFoo". While those APs are all broadcasting the SSID, the phone will be unable to consistently see any SSIDs around you. So, to get the phone working, you need to run to your local electronics store and purchase an inexpensive "brand Y" AP. Set that AP up and name it something like "IWishQuickPhonesWorkedOnMultiAPNets". (yes, I know that is too long for an SSID.. work with me here.) Now, shut down all of the APs that are broadcasting the "CorporateFoo" SSID, and reboot your QuickPhone. When the phone comes back up, it should be able to see your single AP that is broadcasting the "IWishQuickPhonesWorkedOnMultiAPNets" SSID. Configure the phone to use this SSID, make sure it connects and can talk to your SIP server. Once you verify it is working, you can turn your other APs back on. Now that you have the configuration set in the phone, it should always talk to the single AP. When it is powered on, it might take a while to find the AP, but it should eventually connect to it.

So, in a nutshell, if battery life is king for you, and you either only have a single AP, or don't mind jumping through hoops to get your phone working, the QuickPhone is what you want. If having a phone off the charger and on standby for more than 24 hours isn't important, then I recommend the UniData phone I reviewed a few months ago. It is a solid phone that has been working perfectly in my environment.

Monday, May 3, 2010

Xfce and Ubuntu

The title may be a bit misleading. It is likely that this is really an Xfce issue only.

When I upgraded my Revo from Gentoo to Mythbuntu I ended up with a situation where the font size was significantly larger than it should have been. Okay, perhaps "significantly larger" would be an understatement. The clock on the menu bar was so large, I could only see the bottom lines for the numbers!

Googling around found that the issue was with Xfce trying to determine the best font size by using the DPI values from X. X, in turn, got the DPI information out of the EDID information from the monitor. I am sure in most cases this works just fine, but when you bring a cheap LCD flat panel TV in to the equation along with an ION graphics card, the results are less than stellar.

After searching many web pages looking for the answer, I finally found it in the first place I SHOULD have looked. (Yeah, I can admit when I was being stupid.) If you hop over to the MythTV Wiki at http://www.mythtv.org/wiki/Specifying_DPI_for_NVIDIA_Cards you can find the "magical" answer to the problem.

Specifically, you need to add the following options to the "Monitor" section :

Option "UseEdidDpi" "FALSE"
Option "DPI" "100 x 100"


After this, everything started to look reasonable on my screen again!

Sunday, May 2, 2010

Of Acer Aspire Revo and Ubuntu 10.04 LTS

I have been running one of my Myth frontends on an Acer Aspire Revo for a while now. When I first got it, I loaded it up with Gentoo, which was my favorite distro at the time. Since then, I have set up several other frontends using Mythbuntu, all of which speak to my backend still running on Gentoo.

Since all of my frontends except one were running Mythbuntu, I decided to do myself a favor, and convert the last one to Mythbuntu as I upgraded toward the final 0.23 release of Myth. It seemed like it would be a pretty straight forward thing to do, but it turns out, it isn't so straight forward.

I managed to get the system to install reasonably pain free. I selected my usual options during install, such as using the proprietary NVidia drivers, instead of the open source ones. (Mainly because I need VDPAU, or else these low power machines won't be able to keep up.) Following the final reboot, I saw some text on the screen about a failure to load something related to the NForce chipset, quickly followed by a blank screen. But, not just any blank screen, the blank screen my TV gives when there is either no signal, or an invalid signal on the input.

Needless to say, this was annoying. After running some nmap to chase down the DHCP address given to this machine, I was able to log in. While looking through a "ps xaf" output, I noticed that there was a process called "zenity" running, that seemed to be trying to display an error message about Ubuntu running in low graphics mode. Googling around found that this usually happens when the driver installed is incorrect, or improperly configured.

A quick "lsmod" showed that the expected nvidia kernel module wasn't running! At this point, it seemed pretty clear why the configuration didn't work! Looking through the available apt packages, I couldn't locate the proprietary nvidia drivers. (Or, at least they weren't where I expected them to be.)

A bit more Googling around came across this web site : http://www.ubuntugeek.com/howto-install-nvidia-drivers-manually-on-ubuntu-10-04-lucid-lynx.html

So, what does it all mean? Darn good question. I am far from an expert on the subject, but it would seem that the latest version of Ubuntu doesn't have a way to install the NVidia driver without going through the old method of downloading it directly from NVidia, and doing the work yourself.

What I can say, however, is once I followed the instructions from the link above, my machine booted right up in to X, and started working as I would have expected.

Wednesday, March 17, 2010

Marshal double dereferenced strings in C#

I have been working on some interesting bits and pieces of software that involve the use of C# on Windows Mobile. Specifically, I am using the DMProcessConfigXML() function call to feed an XML provisioning document in to Windows Mobile to change settings on the device.

Today I ran across the need to make full use of the function to query existing settings. To date, I had only pushed data in, I didn't have a need to actually read anything back out.

Where is where it gets fun. The data that is returned is defined as "LPWSTR* ppszwXMLout". Marshaling simple data types in C# isn't terribly hard, but a pointer to a pointer!? Such things are the crazy constructs of a C programmer! After digging around, I found a sample on jaredpar's blog that showed how to marshal a double dereferenced pointer to an integer. I figured getting a string would be similar, except the final step would be to marshal a string, instead of an int. Lucky for me, it really is that simple.

For more on the gory details, I would suggest clicking on the list to jaredpar's blog. He describes the details well, so I won't bother repeating his work. Instead, here is a quick bit of code that shows the difference for dealing with a string instead of an int :


public void queryProxyData()
{
IntPtr outptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
string query = "";

if (DMProcessConfigXML(query, 1, outptr) == 0)
{
// See if we can demarshal that crazy thing!
IntPtr newPtr = (IntPtr)Marshal.PtrToStructure(outptr, typeof(IntPtr));
string xmlData = Marshal.PtrToStringUni(newPtr);
Debug.WriteLine(xmlData);
Marshal.FreeHGlobal(newPtr);
}

Marshal.FreeHGlobal(outptr);
}


Pretty simple, huh? I can safely say this is a much better solution that a previous one that I found!

Friday, March 12, 2010

Well, isn't this QT... (Building 64-bit binaries on Windows 32-bit)

For a project that I work on, we have a 32-bit build "server" running on Windows XP Professional. We are starting to expand this project to support 64-bit systems. No problem, right? Visual Studio has cross-compilers for x64 machines. So, we can still use our 32-bit system to build 64-bit binaries.

Umm.. Sure... Something like that.. I spent a rather long weekend trying to figure out how to do this very thing. The problem that I ran in to is the UI for the project uses the QT libraries.

I started off trying to build the x64 QT libraries using the x64 compilers on a Windows XP development machine. I didn't get very far in the process before I hit a dead end. The build would bail out when it attempted to run qmake.exe. After beating my head on it for a bit, I realized that the build system that QT uses expects to compile tools like qmake, and then execute them to complete the rest of its build process. So, the build process would build qmake for the x64 architecture, then attempt to run it, which obviously wouldn't work. (Remember, I was on a 32 bit system.)

I suspect that someone that wanted to badly enough could work around this with various types of trickery. But, I happened to have an x64 machine kicking around my house, so I just built it on that machine, and then decided to try to move it to the 32-bit build system. The x64 build went smoothly when it was done on an x64 machine. (Imagine that!)

Of course, once I moved my shiny new x64 libraries over to the Windows XP build machine, nothing worked. It didn't work because all of the .exe files that were used to handle the QT magic were 64 bit binaries! So, to get things working, I had to find a way around it.

Since the tools that are used in compiling QT programs basically take some type of data (usually XML) and translate it to code that can be compiled. The code that is generated is nothing more than a text file that is then fed in to a compiler. So, it seemed that I might be able to replace some of the .exe files that QT was attempting to call, and end up with something that worked, even if it was something the QT guys would turn up their noses at.

My first attempt was to copy all of the .exe files from the /bin/ directory of a 32-bit install over the .exe files in the /bin/ directory of the 64-bit install. After doing this, I kicked off a build and waited to see what blew up so I could figure out how to fix it. To my surprise, the project built without complaining.

I figured it couldn't POSSIBLY be THAT easy. But, it looks like it is. The binary that was built seems to work on x64 versions of Windows when cross-compiled from a 32-bit version of Windows.