SIPping from the fountain of VoIP

by Ivan Hamilton 12/17/2007 12:22:00 PM

VoIP is one of those great acronyms floating around in IT that is a general idea, not a particular specififcation. The two main ones are the ITU standard H.323 and the IETF standard SIP. I played with a VoIP phone service provider a number of months ago, and you can't argue with the numbers. In this case, I used the Ekiga softphone.

One issue I had is that we're all too used to a phone as a discrete device. We don't want to have a PC running 24/7, we don't want a PC reboot causing call drop-outs, and we don't want to lose the dial-tone reliabilty of standard phone services.

Enter the Linksys SPA3102. It includes my must-have feature: "If power is lost to the unit or Internet service is down, calls can be redirected to a traditional carrier via the FXO interface." I'll never trust my ISP completely.

These units were available for about $95 delivered (beware the ones locked to a single provider). I grabbed mine from Warcom. I like these guys... order one day, on the door-step the next. I've used them before, and probably will again.

I was concerned about the complexity of configuration to get this little machine to work. The configuration pages are pretty daunting. Bravely, I plugged it in, entered the name, password and server from my VoIP provider. Just for kicks, I picked up the phone and rang my mobile. It worked. Damn... it worked. I called back my VoIP number from the mobile... the phone rang.

We'll see after a decent test duration, but in the last few days my call charges are 1/30th of what I was paying with my POTS provider.

All we need now, is to be able to get the copper pair for our ADSL without having to get a phone service. This has been made possible recently, but the total saving would be about $2 a month. Not worth losing the POTS for.

If you've been thinking about trying VoIP. Dive in... it's not too bad.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Pragmatism

Generic Obscenity

by Ivan Hamilton 12/12/2007 6:33:00 PM

I've been trying to fix outstanding issues in my MonoMerge build and most problems appear to resolve around generics.

I have 3 test assemblies (1 EXE, 2 DLL) that I use to test. The EXE references the two DLLs and they reference each other. To test, I build the 3 assemblies, Merge the three assemblies into 1, disassemble the 3 original and 1 merged assemblies. I then run a custom little tool over the IL text to compare the method bodies. The custom tool is needed because the order of items in the merged assembly isn't preserved.

My little test assemblies only cover what my mind can come up with... and I'm pretty gentle. For a final test, I use "the most terrifying assembly for generics stuff: the great C5 library". I was introduced to the C5 Generic Collection Library by a jbevain post. He was happy that Cecil could round-trip C5 (I don't know how he tested the result). So that seemed like a good test for MonoMerge. My god, C5 IL looks like an exclamation mark factory exploded. Here's a couple of examples:

.method public virtual  hidebysig  newslot instance default class C5.IList`1<!!V> Map<V> (class C5.Fun`2<!T, !!V> mapper)  cil managed
IL_0015:  call instance class C5.IList`1<!!0> class C5.ArrayList`1<!T>::map<!!0> (class C5.Fun`2<!0,!!0>, class C5.ArrayList`1<!!0>)

Ugly as it may seem, it is a very good test. There have been quite a number of possible generic usage scenarios that I wouldn't have thought up myself.

At this point, I'll state that there's no way in the world I could debug the issues I'm having without ILDasm, PEVerify & MonoDis. If you ever try assembly manipulation, you can not live without these.

After undoing some work (that I shouldn't have done), my own tests appear to pass (again), but C5 brings everything crashing down (in new and interesting ways). Argh!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Mergin', mergin', mergin', Though the GC's purgin'

by Ivan Hamilton 12/10/2007 6:36:00 PM

Call me old-school, but one thing that I miss in all this new fangled .NET world is the neat single EXE solution. If you grew up with C object or Pascal unit files, then you might miss the ability to combine pre-compiled code into the target file under .NET.

Static linking it's called, but it's fallen terrifically out of fashion in these days of dynamic linking with DLLs and shared objects.

Mono has a linker project that aims to produce the minimal possible set of functions that a program might require to run (as opposed to the full libraries). It creates a set of reduced assemblies that can fulfill the needs of the program.

That's part of the way... I like the reduction in code size through linking, but I also want a single file solution (mainly because I'm too lazy to think about multiple files).

There's tool over at Microsoft Research, ILMerge, which can combine multiple assemblies into one. But it's proprietary, so usage is restricted and source is unavailable... meaning no derived tools can be created.

Enter MonoMerge, a tool that takes a set of assemblies, and merges them in a single one. But it appears that it's been abandoned. What's a geek to do?

I had a look at this tool and it appeared good enough during a simple test. A little more testing, and it started to fall apart. There appears to be two areas where the code falls down: name clashes & generics.

If two assemblies had private classes with matching names (like the ubiquitous <PrivateImplementationDetails>), then all code would incorrectly refer to only one of the classes. This would result in either an inability to resolve members during merging, or resolving to a similarly named member in the wrong class! This is a real problem as the compiler will often use such classes for array initializers or caching dictionaries used in switch statements. I originally tried to make a few small changes to the existing code to add class renaming support, and while this partially worked... a complete implementation along those lines would just scatter if/else statements throughout the code. It also didn't help resolve the generics issue.

Generics were a problem because in resolving MethodReferences equality was judged upon the ToString() result of MethodReferences. This causes problems because two different calls can share the same ToString() signature. A simple example:

    public class CalledGenClassClass<U>{

        public static void CalledMethodMethod(){}

    }

    public class CalledGenMethodClass{

        public static void CalledMethodMethod<V>(){}

    }

    public class GenMethodClass{

        public static void DemoMethod<T>(){

            CalledGenMethodClass.CalledMethodMethod<T>();

            CalledGenClassClass<T>.CalledMethodMethod();

        }

    }

    public class GenClassClass<T>{

        public static void DemoMethod(){

            CalledGenMethodClass.CalledMethodMethod<T>();

            CalledGenClassClass<T>.CalledMethodMethod();

        }

    }

We've got four calls, happening here. A generic method & generic class call, each using a generic method & generic class parameter. The problem is both calls have the same ToString() signature from a Cecil point of point (CalledGenMethodClass::CalledMethodMethod<T>() & CalledGenClassClass`1<T>::CalledMethodMethod()). Which is fine, but the parameter T is only valid within the scope of the body calling the reference, you can't use it outside of a method body, because T might mean something different.

In IL these signatures differ using the (!) notation:
GenMethodClass.DemoMethod: CalledGenMethodClass::CalledMethodMethod<!T>() & CalledGenClassClass`1<!T>::CalledMethodMethod()
GenClassClass.DemoMethod: CalledGenMethodClass::CalledMethodMethod<!!T>() & CalledGenClassClass`1<!!T>::CalledMethodMethod()

I originally tried to change Cecil to return !T or !!T in ToString(), but then realised the notation wasn't the solution. There would still be a deeper issue of resolving references.

I set off to find a better way to resolve MemberReferences...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

Generics Variance: Covariance, Contravariance and Invariance

by Ivan Hamilton 12/6/2007 5:23:00 PM

There's alot of things you don't think about until... you have to think about. I recently came across generics variance in C# (or lack of it). Best explained with a quick example.

Firstly get yourself a simple structure:

    class Animal { }

    class Mammal : Animal { }

    class Dog : Mammal { }

    static void AnimalMethod(Animal animal) { }

    static void AnimalArrayMethod(Animal[] animal) { }

    static void AnimalListMethod(List<Animal> animal) { }

Then do something very simple:

    AnimalMethod(new Dog());

    AnimalArrayMethod(new Dog[0]);

    AnimalListMethod(new List<Dog>());

Just think about that for a moment. Is it safe to pass a reference to a Dog for an Animal parameter? Can a Dog[] be treated as an Animal[]? Does it make sense to pass a List<Dog> for a List<Animal>?

Yes, no & maybe. (Compiler: AnimalMethod & AnimalArrayMethod calls are valid and AnimalListMethod call is invalid)

Let's look at the above examples:

  • AnimalMethod - Simple reference conversion: Nothing new here.
  • AnimalArrayMethod - Array Covariance: A controversial C# feature. If I pass a Dog[] thru an Animal[] parameter, it's valid at compile time for that method to assign a Cat into the array. Because of array covariance, assignments to elements of reference type arrays include a run-time check that ensures that the value being assigned to the array element is actually of a permitted type.
  • AnimalListMethod - Generic Covariance: A non-existant feature... but does it make sense? Well... as much sense as array covariance.

The compile time validity of array & generic variance would depend upon the action being performed. If we were to only read an element, covariance is safe (each Cat can be treated as an Animal). If we only write, contravariance is safe (into Animals we can place a Cat). If we read and write, then invariance is safe (only Cat into Cats and Cat from Cats).

C# array variance is broken. Why? Because it's unbalanced: covariance is supported while contravariance is not. For every instance you may want covariance to support passing in subtypes, there's a case for contravariance to pass out to supertype referenece.

C# generic constraints are broken. Why? Because it's unbalanced: subtypes are supported while supertypes are not. For every instance you may want subtypes to support passing in subtypes, there's a case for supertypes to pass out to a supertype referenece.

I don't know if variance be can "fixed". Any changes to existing array covariance, would probably make far too many people have to think about their code. Compiler designers hate breaking changes (new compiler won't compile old code). You'd also need language extensions to allow you to declare whether you permit covariance/contravariance at certain points.

I doubt it will get addressed... we must learn to live with what our compiler allows. Human sacrifice, dogs and cats living together - mass hysteria.

P.S. Eric Lippert has a brilliant set of posts on Covariance and Contravariance.

Currently rated 3.0 by 5 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET

I'd get it one piece at a time...

by Ivan Hamilton 12/6/2007 11:10:00 AM

My BlogEngine.NET on Mono experience continues. It kind of reminds me of a Johnny Cash song:

"I'm goin' ride around in style. I'm gonna drive everybody wild. 'Cause I'll have the only one there is around."

"Now up to now my plan went alright, 'Til we tried to put it all together one night. And that when we noticed that somethin' was definately wrong."

It could be a recognised design-pattern.

The main issues so far in getting it up and running:

  • Compilation - xbuild doesn't embed file resources. <EmbeddedResource> is ignored in .csproj files. Worked around with a MakeFile.
  • Path Construction - e.g. pathName+"\"+fileName doesn't work on Unix. Change to Path.Combine().
  • Filesystem Case Sensitivity - "App_data" won't find "App_Data". Fix string case in string literals.
  • Issues with Server.Transfer() - error transferring to non-execable path files. Use context.Server.Transfer().

So, far... so good. But I haven't tested all areas of it yet. As I find problems, I'm looking into them. I'd get it one piece at a time...

P.S. Comments & Contact appear to work now. So if you find part of the site that isn't working...  let me know.

Currently rated 1.7 by 32 people

  • Currently 1.749999/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET | BlogEngine.NET

Oh, you guys, my ass, seriously…

by Ivan Hamilton 12/3/2007 4:33:00 PM
Now I know it's not the world's biggest trip, but I'm just back from a couple of days away on the bike. 2000kms later, I'm home. Some great riding, lots of twisties... but it's worth remembering that the Blackbird isn't a sports bike.

Damn! I was so glad to get home, but at the same time... I yearn to be out on the road again. If only my darling Tracey would come with me...

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Motorcycling

Powered by BlogEngine.NET 1.3.1.30
Original theme by Mads Kristensen

About the author

Name of author Ivan Hamilton
"My inner nerd can beat up your inner nerd."

E-mail me Send mail

Adsense

Calendar

<<  July 2017  >>
MoTuWeThFrSaSu
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar

Recent comments

Tags

None

    Entropy

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2017

    Sign in