Nicholas Skinner

Freelance website and web application developer

8-bit SMS PDU Decoding via PHP

May 14th, 2013

SMS DecodedAlong with needing to encode 8-bit SMS PDU messages via PHP I also needed to decode them, therefore after looking into what was involved I wrote my own class.

Download: PHP SMS PDU Decoder

PHP Class: Image Resizing

March 26th, 2013

Image Resize Code ScreenshotFor a new website project I had the need to resize images in PHP so decided to rewrite some of my years old image resizing functions to more be up-to-date with my current coding practices.

Class supports source/destination images as jpeg, png, or gif automatically identifying the type from the filename, and allows for:

  • Proportional resizing based on a provided width or height (but not both) resulting in e.g. a 200px wide image, and a height proportionally scaled to the original.
  • Fixed proportional resizing with cropping based on a provided width and height resulting in an image that will first be scaled and then cropped from the centre to exactly match both provided dimensions.

[Download: img.php]

8-bit SMS PDU Encoding via PHP

February 28th, 2013

SMS PDU Encode PHP ScreenshotFor a recent project to remotely update software on Telit GSM modems I had a need to create 8-bit PDU messages using PHP, with support for the validity (expiry/timeout) period.

After searching on Google I found several online JavaScript based tools available including those by rednaxela, twit88, kekekasvi, and a C# SMS/PDU library by Stefan Mayr (which I have used in other desktop based tools) however the PHP side of things was somewhat lacking. The only code I could easily find was some by Vincent Heet however it is not licensed for commercial use, only supports 7 bit encoding, and does not support the validity period in a “clean” way (i.e. without manually calculating it and specifying the value in hex).

I therefore spent some time looking over the available documentation, working out how to encode PDU messages, and writing my own basic PHP PDU SMS encoding class supporting 8-bit PDU and (relative type) message validity periods.

Download: PHP SMS PDU Encoder

Plus.net FTTC Review

January 31st, 2013

Plus.net LogoI have been on a standard ADSL service for a number of years which started out as Bulldog, then automatically moved to “Pipex” / “Pipex Home Telecom” the result of Bulldog exiting the home broadband market. I stuck to the service primarily because it was fairly reliable, cost effective, and just about fast enough for my needs.

Recently however I decided it was finally time to upgrade. I looked into a number of providers, including Plus.net, AAISP, and Virgin Media. As a company AAISP seem to be very technically proficient offering IPv6, IP blocks, reverse DNS etc and (as far as I can see) good support however price wise they are not particularly competitive.

I very nearly went with Virgin Media however the upload speed somewhat put me off (part of the reason for upgrading is faster FTP upload of clients websites, and use of VoIP), I was also put off a little by it being a cable broadband service provided by a mainly TV company, especially not having used one before (rather than a regular phone line based broadband service provided by a dedicated ISP).

In the end I decided on Plus.net – a reasonably usage allowance, download (~50MB), and upload (~20MB) speed with options such as fixed IPs available.

Using it for just less than a month so far, overall I have been happy with the service, there are however several areas that could be improved:

  • I placed an order on the 10th November and it took nearly 2 months to install the service on the 9th January (due to BT engineer delays).
  • Supplied TG582N Router is not particularly easy / intuitive to use (for advanced options such as port forwarding, changing IP, setting DHCP ranges), and repeatedly kept logging me out on the initial setup.
  • Plus.net call centre seem to take their time to answer the phone ~15 minutes+ on the two occasions I called.
  • Line was not activated when the BT engineer arrived meaning we had to call Plus.net and ask them to turn on the service which I gather should have already happened prior to his arrival.
  • Received a previously used telephone number (opted for the phone + broadband package) which has resulted in a number of automated marketing calls intended for someone else.

PHP Class Libraries: Design Patterns

December 31st, 2012

form_class_codeAfter using them for many years I have recently been rewriting some of my existing class libraries (both due to their age and their growing inflexibility for current requirements):

  • Authentication
  • HTML Page Template
  • HTML Tables
  • HTML Forms
  • Button Generation
  • Exceptions
  • HTTP Requests
  • Persistent Navigation

Most received only minor updates however for others I made some more major changes.

Button Generation

For rounded corner buttons I used to rely on PHP generating images using the GD Extension, I would stitch together the left corner of the image, repeat the middle section depending on the text width, and then stitch on the right corner, optionally adding in an icon as well. This worked well however with most modern browsers supporting CSS “border-radius”, and styling of submit buttons seemingly working more reliably cross platform images were nolonger needed and I switched to using regular HTML / CSS.

HTML Tables

table_class_smallOne of my more frequently used classes this one received quite a few modifications.

I used to try and embed all possible required functionality inside the “standard” class itself, and use function callbacks, function arguments, and return values to customise specific functionality depending on requirements for the particular page it was being used on. This approach however slowly started becoming less ideal as it got increasingly more complicated to cater for particular infrequently used edge cases. It also sometimes increased development time due to needing to work out how to incorporate the functionality properly into the “standard” class, and then test it, and potentially test other pages also using the class rather than just customising it for a specific page.

The rewritten class now relies more on the principle of “object inheritance” and uses PHPs “extends” functionality. As much as possible distinct operations e.g. generating navigation links, generating table titles, retrieving table data, generating table cells are all now separate “functions”.

This means that if any customisations are required for specific pages it is generally a much simpler / quicker case of just using the “extends” keyword to inherit the class functionality, and overwriting particular methods sometimes in combination with the “parent::” operator to retain existing functionality. This gives a lot more flexibility than just relying on specific pre supported functionality and customising more via augments, and callbacks.

HTML Forms

form_class_smallI have written HTML form classes before however after writing them have usually not ended up using them and instead fallen back to using a standard template which I customise in multiple places for database record add/edit pages (which most of my forms are). I just never seemed to be able to get the balance right between writing a class that actually saved development time long term without being over complicated or too inflexible to cater for ever changing requirements, something which turned out to be even bigger problem for forms (generally requiring more customisations) than was required for tables.

I believe I may however have found the answer in terms of using object inheritance (as described above for the table class) which I am hoping will both cut down development time while at the same time being flexible enough (and flexible enough in a simple way, similar to my old fully customisable template based approach).

Download: Table Class
Download: Form Class

Note: Classes are not really usable as is, and are a work in progress. I have included them more to illustrate points made in the blog post.

PHP Database Access: Switching to PDO from “mysql_” functions

November 28th, 2012

PDO PHP Class ScreenshotWhen I first learnt PHP several years ago the most common way to access MySQL databases was through the original MySQL extension (“mysql_” set of functions) that I have been using ever since (through some custom classes). During that time however the original extension has become “Maintenance only” with usage being “strongly” discouraged by the PHP documentation, and “Long term deprecation announced”.

After becoming aware of the original extension becoming out of favour I initially ignored it (in terms of having any practical impact on coding PHP applications using databases), since as with any change it usually takes time for everyone else to catch up (in this case web hosting providers) and limiting my code to only run on certain supported web hosts would not be ideal for clients.

It is however usually a good idea to get ahead of such changes so that old websites / applications are more likely to be naturally replaced rather than requiring updates to be compatible when a change is later forced. Therefore I recently looked into things again, and testing on some of the more well known hosts / control panel software that my clients use, including 1&1, 123-Reg, Pulsant, HostDime, cPanel and finding support for the newer alternatives I started considering my options.

I mainly looked into mysqli and PDO. As far as I could see practically there was not too much difference between them, however favouring object orientated programming (PDO supports only OOP, while mysqli supports both Procedural and OOP style programming), and that PDO also supports other types of database such as SQLite (which seemed like it may be useful in the future for smaller projects) I decided to go with PDO.

[Download: PDO Database Class Library]

Command Line RPC, and Multicast RPC Sender For Synapse SNAP Connect

October 30th, 2012

Home Automation CMD Code ScreenshotI had a need to send Synapse RPC, and Multicast RPC calls from PHP to trigger events for my Home Automation System. The simplest option I could come up with was coding a command line utility (using the example Synapse code provided) that links to SNAP Connect via XML forwarding on RPC / Multicast RPC calls based on command line arguments that have been passed in.

RPC Example:

HomeAutomationController2CMD.exe "http://server:8080" "00.00.99" "rpc" "00.00.01" "myfunction" "B:1" "S:abc123" "I:33"

Example shows an RPC call using SNAP Connect server running on localhost port 8080 from local node address “00.00.99” to node “00.00.01” calling function “myfunction” passing in a boolean true on the first argument, string “abc123” on the second, and integer “33” on the third.

  • Arg[0]: SNAP Connect Server URL
  • Arg[1]: Local Node Address
  • Arg[2]: Action (e.g. rpc, or mrpc)
  • Arg[3]: Remote (destination) Node Address
  • Arg[4]: RPC Function Name
  • Arg[5]: RPC Function Argument 0 (Boolean: 0/1)
  • Arg[6]: RPC Function Argument 1 (String)
  • Arg[7]: RPC Function Argument 2 (Integer)

RPC function arguments can be added/removed as needed, the type of argument (Boolean/string/integer) can be specified by using the B/I/S prefixes.

Multicast RPC Example:

HomeAutomationController2CMD.exe "http://server:8080" "00.00.99" "mrpc" "myfunction" "B:1" "S:abc123" "I:33"

Example shows a Multicase RPC call using SNAP Connect server running on localhost port 8080 from local node address “00.00.99” calling function “myfunction” passing in a boolean true on the first argument, string “abc123” on the second, and integer “33” on the third.

Download

Transferring Inbound Calls Manually Before Pickup Using Asterisk PBX

September 27th, 2012

Cisco Service, Transfer CallWhen I first started using Asterisk PBX I setup a few small but useful Perl scripts (run via dialling extensions) to do tasks such as:

  • Transfer an incoming call to an external mobile number without needing to answer the call (i.e. call comes in, and based on the Caller ID I could manually choose to answer or forward it).
  • Forced remote call transfer / local pickup an active call (i.e. call comes in on another phone and the person who answered is unable to remember how to transfer it, to save having to physically go to the other phone and transfer the call).
  • Transfer a ringing call to voicemail immediately without waiting for a delay.

After switching to the Rowetel IP04 IP-PBX I could not work out a simple way to port over the scripts (IP04 does not have Perl support by default) so lived without the functionality for a few years.

Recently I also had another requirement come up, the ability to based on Caller ID either decide to pickup the call or to transfer it (without needing to answer it) to an external answering service. After this I started looking into the options and came up with using the Cisco 7960’s mini XML browser.

When a call comes I can not press “Services” on the phone, this loads a PHP script running from a server which shows a list of the transfer options. I then choose an option and the PHP script connects to the Asterisk AGI gateway and transfers the call to the specified party (i.e. voicemail, external mobile, call answering service, or the local phone itself). It also has the advantage of providing a text menu of options rather than needing to remember an extension to dial.

Download: service_transfer.zip

Note: Script assumes calls come in externally on the line “Zap/1-1″, and internal extensions are in the context “myinternal”. Change these in the transfer_call() function if required.

Backing Up Gmail Accounts (Part 2)

August 27th, 2012

Spanning Backup ScreenshotEver since switching to Gmail in 2009 I have been trying to find a reliable long term backup solution. First I used GMail Backup (but it had problems with large folders, and setting messages as read), then switched to Gmail Keeper (but it started crashing / using up large amounts of CPU time).

I have now switched to Spanning Backup. It is a subscription service ($35 per year) but does also backup contacts, calendars, documents as well which is handy. I also like that it actually shows an inbox type view allowing you to see all backup messages, filter by label, and tick a box to restore them.

Seems to work very well for a single account however, I have had some issues trying to use it on domain accounts. As best I have been able to determine if you want to restore messages on a domain account you need to login to the Spanning control panel as that user with their password, i.e. logging in with a Google Apps “Super Admin” account does not work. Possibly this might be due to not activating the backup service on the “Super Admin” account itself, but this is not something I want to do because the Admin account does not need backing up (and it is an extra cost to do so).

Spanning Backup also have an affiliate program where they give you a code which allows others to get the $35 per year discount rate (normal cost $40), and also saves you $5 as well.

Discount Code: 7K8HAN

Reliable UK Caller ID On The Asterisk IP04

July 28th, 2012

Comet DeviceSince I purchased the Rowetel IP04 IP-PBX in 2009 I have experienced issues with UK caller ID not always coming through reliably, and lately seemingly getting worse. Contacting my supplier I was told it was a known issue but there was not yet a fix available – the same thing I was told on a number of subsequent queries.

I finally decided to do something about it a few weeks ago in the form of purchasing an external caller ID unit, and using that to forward caller ID back to Asterisk.

I purchased the Crucible Technologies CTI Comet for £115.20 (inc VAT/postage).

CID Forwarder ScreenshotNext I used the example code provided to code a C# app that allows configuring of the Comet serial port, Asterisk server, and when a call comes in connecting to Asterisk via the Asterisk Manager (AMI) interface, and setting two variables containing the name/number received. In terms of Asterisk I configured it as follows:

exten => s,1,Dial(SIP/phone101,3,tH)
exten => s,n,Set(CALLERID(num)=${CIDNUMREMOTE})
;exten => s,n,Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})})
exten => s,n,Set(CALLERID(name)=${IF($[${LEN(${CIDNUMREMOTE})} = 0] ? ${CIDNAMEREMOTE} : ${DB(cidname/${CALLERID(num)})})})
exten => s,n,Dial(SIP/phone101,,tH)

This causes Asterisk to ring the phone for 3 seconds (giving the Comet time to receive/forward the caller ID), set the caller ID (that will show up on the phone display) via the variable sent from the C# app, and then ring again. It has the advantage that the phone starts ringing immediately (with standard Asterisk caller ID support the phone does not start to ring until the caller ID is received which seemes to be around 2 rings), it means that the caller ID does not come up immediately but usually you need time to get to a phone anyway so it is not too much of an issue, and means you pickup more promptly overall.

Being in the UK without caller ID name support I am using the internal Asterisk database (set from another app) to resolve the number to a name, and if the number is blank using the name passed through from Comet (which is generally only set to “WITHHELD” or “INTERNATIONAL”), but I find it useful to know the difference between a withheld or international call.

[Download: Caller ID Asterisk Forwarder Application | Visual C# 2010 Source Code]

Note: Application has so far proven reliable for me but I did not implement any error checking on configuration inputs. It also has an extra option to instead/alongside Asterisk forwarding launch an external program passing in the caller ID name/number as argument. .NET runtime required.