SMS class for GSM programming

This will be my first VB.net posting as far as I could remember.
After several hours of trial and error (good thing I had unlimited sms plan for this one) I successfully able to get it work properly. This was also my first USB programming experience. Well due to the strict “language requirements” by the academe people I’ve initially written this class from C# where it all began then converted them to a usable and clean code in VB.net. There are plenty of codes out there that tackles SMS/GSM programming. But I could not find a well suitable, as simple as possible,  stable and reliable code for VB.net. As a lot of people say that its easy for them to communicate with GSM Modems as long as you know the fundamentals of AT commands but I found more issues to consider before and one of them was getting the status result from the Phone provider after sending SMS from the modem. So here it is…

'///////////////////////////////////////////////
'SMS Class
'
' Class for sending SMS with return status
' (C)opyright 2011 by www.michael-yap.com
' All Rights Reserved.
'///////////////////////////////////////////////
 
Option Explicit On
Imports System
Imports System.Threading
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.IO.Ports
 
Public Class SMS
    Private WithEvents SMSPort As SerialPort
    Public receiveNow As AutoResetEvent
 
    Public Sub New(ByRef COMMPORT As String)
        receiveNow = New AutoResetEvent(False)
 
        SMSPort = New SerialPort
        With SMSPort
            .PortName = COMMPORT
            .BaudRate = 9600
            .Parity = Parity.None
            .DataBits = 8
            .StopBits = StopBits.One
            .Handshake = Handshake.RequestToSend
            .DtrEnable = True
            .RtsEnable = True
            .NewLine = vbCrLf
        End With
 
        AddHandler SMSPort.DataReceived, AddressOf port_DataReceived
 
    End Sub
 
    Public Sub SendSMS(ByVal CellNumber As String,
        ByVal SMSMessage As String)
        Dim MyMessage As String = Nothing
        'Check if Message Length < = 160
 
        If SMSMessage.Length <= 160 Then             MyMessage = SMSMessage         Else             MyMessage = Mid(SMSMessage, 1, 160)         End If         If IsOpen = True Then             Dim recievedData As String = ExecCommand("AT", 300, "No phone connected")             recievedData = ExecCommand("AT+CMGF=1", 300, "Failed to set message format.")             Dim command As String = "AT+CMGS=" & CellNumber & vbCr             recievedData = ExecCommand(command, 300, "Failed to accept phoneNo")             command = MyMessage + Char.ConvertFromUtf32(26) + "\r"             recievedData = ExecCommand(command, 4000, "Failed to send message")         End If     End Sub     Private Function ExecCommand(ByVal command As String, ByVal responseTimeout As Integer, ByVal errorMessage As String) As String         Try             SMSPort.DiscardOutBuffer()             SMSPort.DiscardInBuffer()             receiveNow.Reset()             SMSPort.WriteLine(command)             Dim input As String = ReadResponse(responseTimeout)             If ((input.Length = 0) Or ((Not input.EndsWith("> ")) And (Not input.Contains("OK")))) Then
                Throw New ApplicationException("No success message was received.")
            End If
 
            Return input
 
        Catch ex As Exception
            Throw ex
        End Try
 
    End Function
 
    Private Sub port_DataReceived(ByVal sender As Object, e As SerialDataReceivedEventArgs)
        Try
            If e.EventType = SerialData.Chars Then
                receiveNow.Set()
            End If
        Catch ex As Exception
 
        End Try
    End Sub
 
    Public Function ReadResponse(ByVal timeout As Integer) As String
        Dim buffer As String = String.Empty
 
        Try
            Do While (Not buffer.Contains("OK") And Not buffer.EndsWith("> ") And Not buffer.Contains("ERROR"))
                If receiveNow.WaitOne(timeout, False) Then
                    Thread.Sleep(500) ' you need to adjust this settings depending on how your modem can
                                              ' able to get response to the provider, its recommended also to use the
                                              ' thread timeout instead of adding this. sorry its a quick fix :(
                    buffer += SMSPort.ReadExisting()
                Else
                    If (buffer.Length > 0) Then
                        Throw New ApplicationException("Response received is incomplete.")
                    Else
                        Throw New ApplicationException("No data received from phone.")
                    End If
                End If
 
            Loop
 
        Catch ex As Exception
            Throw ex
        End Try
 
        Return buffer
    End Function
 
    Public ReadOnly Property IsOpen() As Boolean
        Get
            If SMSPort.IsOpen = True Then
                IsOpen = True
            Else
                IsOpen = False
            End If
        End Get
    End Property
 
    Public Sub Open()
        If IsOpen = False Then
            SMSPort.Open()
        End If
    End Sub
 
    Public Sub Close()
        If IsOpen = True Then
            SMSPort.Close()
        End If
    End Sub
 
End Class

a sample usage will be

            'send sms
            Dim Retries as Integer=1
            Dim SMSEngine = New SMS("COM3") 'replace with your actual modem USB/Serial Port
            Dim validnumber as String = "+639221234567" ' replace with your number, be sure it includes
                                                                          ' the country code
 
            SMSEngine.Open()
 
            Try
                SMSEngine.SendSMS(validnumber, textmessage)
            Catch ex As Exception
                If Retries >= 3 Then
                    Console.Write("Failed after 3 retries: " & ex.Message) 'you can customize this base on the failed result status
                Else
                    Retries + = 1
                End If
            End Try
 
            SMSEngine.Close()

BTW: I used Wavecom Fastrack GSM USB Modem as my SMS gateway.

Creating Debian Squeeze Xen image for Cloudmin

4 days since this article was written, Debian Squeeze was officially released (as current STABLE). And one of the things I was excited about was the full support of Xen 4. Upgrading from Lenny to Squeeze was easy as 1,2,3 but after I configured my newly “fresh installed” Squeeze Xen server I was bit surprised that there were no (based on several hours of googling?) “free” downloadable Xen images for Squeeze though I found this site that exactly offers the same images but its not free (thought it was always an OpenSource eih?). So I decided to make my own.

Cloudmin GPL is really awesome! (and of course my all-time favorite Webmin), it saves me a lot of time creating and managing Xen guest servers because I’m not really a hardcore Unix guy you know (btw I ‘m a Windows Sysadmin and .NET developer right?) that is why I stick to GUI as much as possible. Anyway here is the trick to make an instant Squeeze Xen image.

1. You must find a way to get a fresh and clean Squeeze environment to be use as your base image. There were lot of ways to do this, in my case I used my VMware Workstation 7 to setup and make Debian Squeeze (using the debian-6.0.0-xxx-netinst iso file downloaded from debian website).

2. After successfully setup a fresh OS turn it off (be sure to Power Off, do not suspend).

3. Get the VMware Virtual Disk drive file of the Squeeze you created in VMware (just find it in your computer -> or check it in your VMware settings).

4. Copy the file to your Xen/Cloudmin server (in my case the file is Debian Squeeze.vmdk).

5. You must convert the file first to xen compatible format. To do this You will need the qemu-img disk image manipulation tool. You can install using-> apt-get install qemu

6. After successfully installing the tool, run -> qemu-img convert -f vmdk vmware_image.vmdk -O raw xen_image.img

7.  Then rest of it will be in the cloudmin.

8. Login to your Cloudmin using the root account (unless you made a user that has enough privileged to create new images its fine).

9. Go to Cloudmin Settings -> New System Images.

10. Click the Create Image for Xen link at the lower right part just above the Download Selected Images

11.  In the details form, select whole disk as Image file format then Debian Linux in Operating System. Specify the location of the converted image file you made before in the Image Source textbox. You have the option also to put the processed image to the Cloudmin storage location after, but in my case I didn’t selected it cause it gets me trouble looking the file after. Please put the unique ID of the image you wanna create and also DO NOT USE SPACE! You can only do that on the description box below. I highly recommend to compress the file to save disk space.

12.  After reviewing the settings, Click Create button below. It will start processing so be patient.

13. When it successfully finished You can now start creating your new Xen “Squeeze” guest systems. Congrats!

Microsoft RemoteFX VMware and Virtualbox issue

Yesterday I was really excited when I got the RC release of Service Pack 1 of Windows 7 and Windows Server 2008 R2 to test the new feature they added which will be a promising technology called RemoteFX. This new technology will impact those users who always or frequently uses Remote  Desktop to access their system. One of my(and others for sure) current problem with Remote Desktop is the way it communicates with the system being remotely accessed. I won’t explain technically how it works but the thing is with todays technology applications tends to be more and more complex in a way on how it presents its user interface (UI). Example of this is applications built with Windows Presentation Foundation or WPF. Since most of the UI layers built are Double Buffered, when you view the application inside Remote Desktop it shows significant performance degradation because the way it renders comparing the same application when you run it physically on the system it was installed. RemoteFX will eliminate that issue and improved UI responsiveness. In fact, you can play those high graphics games now via Remote Desktop.

The Bad news is… You can’t do RemoteFX on VMware and VirtualBox- FOR SURE!. Answer: RemoteFX needs Windows Virtualization technology called Hyper-V as as its pre-requisite in order for you to install and use it. Since you’re Windows 7/Windows 2008 R2 was running already as “Virtualized”  on top of your existing Host Operating System. Hypervisor could not be passed from to the Host OS to the Guest OS. Put simply, you can’t virtualized another system if you are on top of already virtualized OS.

Well, I know some of people think it was stupid to use RemoteFX in already had “remote desktop” virtual software. But all I can say is how Virtualbox sucks on graphics which is poorer than VMware(I know Virtualbox is faster in terms of CPU,Memory Access and IO Operations but can it run Aero desktop support?I don’t think so). VMware can support Aero graphics but really not as good as it is. Yeah I know VMware uses same protocol as RDP and Virtualbox uses VNC protocol for theirs but don’t you think its time for them to step forward and do something “seriously” about Graphics Virtualization. Not until Intel and AMD release their CPU support for it. By the way, RemoteFX utilizes GPU  power for rendering and not CPU as opposed to the current Remote Desktop. I forgot how great VMware and Virtualbox graphics adapter!

My point is, people who has capable of running multiple virtualized desktop OS for different purposes like for “Testing” could not use this upcoming technology. I can blame both Microsoft and those Virtualization companies for my failure. Why Microsoft depends Hypre-V for the RemoteFX (I know there was technical reasons for it) and why virtualization companies couldn’t improve graphics. We were almost a year or so before using 22 nanometer silicon technology why software was still in a hundreds until now?

Virtualbox RemoteFX

Virtualbox RemoteFX Failed

VMware RemoteFX

VMware RemoteFX Failed