Archive

Author Archive

Installing xtrkcad on Fedora 18

December 29th, 2012 Comments off

Install Dependancies

yum groupinstall "Development Tools"
yum install gtk2-devel
wget http://www.mirrorservice.org/sites/sources.redhat.com/pub/cygwin/release-legacy/GNOME/libgtkhtml2/libgtkhtml2-2.6.3-2.tar.bz2
tar xjvf libgtkhtml-2.0.3.tar.bz2
cd libgtkhtml-2.0.3
./configure
make
make install
wget http://www.mirrorservice.org/sites/sources.redhat.com/pub/cygwin/release-legacy/GNOME/libgtkhtml2/libgtkhtml2-devel/libgtkhtml2-devel-2.6.3-2.tar.bz2
tar vxjf libgtkhtml2-devel-2.6.3-2.tar.bz2
cd usr
cp -R * /usr
yum install webkitgtk-devel

Get Xtrkcad

cd ~
mkdir src
mkdir build
mkdir build/xtrkcad
cd src
wget http://sourceforge.net/projects/xtrkcad-fork/files/XTrackCad/Version%204.2.0-beta1/xtrkcad-source-4.2.0-beta1.tar.bz2/download
tar xvjf xtrkcad-source-4.2.0-beta1.tar.bz2
mv xtrkcad-source-4.2.0 xtrkcad
cd ../build

Setup ccmake and build

ccmake /home/jamesarbrown/src/xtrkcad/
CMAKE_BUILD_TYPE=debug
CMAKE_INSTALL_PREFIX=~/xtrkcad
GETTEXT = OFF
GTK=ON
CAIRO = OFF
LAYOUT = OFF
press c configure
press t advanced options
goto CMAKE_EXE_LINKER_FLAGS
enter "-lm"
press c configure
g to generate and exit

Install

make 
make install
Categories: Uncategorized Tags:

Building Handbrake on Fedora 18

December 26th, 2012 4 comments
yum groupinstall "Development Tools"
yum install yasm zlib-devel bzip2-devel fribidi-devel \
dbus-glib-devel libgudev1-devel webkitgtk-devel libnotify-devel \
gstreamer-devel gstreamer-plugins-base-devel libsamplerate-devel \
libtheora-devel libass-devel libvorbis-devel 
svn checkout svn://svn.handbrake.fr/HandBrake/trunk hb-trunk
cd hb-trunk
./configure
cd build
gmake
make install
Categories: Uncategorized Tags:

Running Logitech Media Server (LMS SqueezeServer) in a closed Environment (Perl 5.14) – Fedora 18 x86_64 Tested

December 25th, 2012 8 comments

Having updated my Mythtv Box to Fedora 18 it came bundled with Perl 5.16. Having never had an issue with LMS I never thought twice. Alas it would not run.

No problem.. there will soon be an update….WHAT? Logitech have discontinued the Squeezebox lineup… now that had me ranting, a product that would be a good market to a small company not fitting in with the huge volumes someone like Logitech needs.

Ok… so how on earth to get it running.

Firstly we need to create a version of Perl 5.14 on the system we can use (no package in Fedora below 5.16)

yum install expat-devel
cd /opt
mkdir Perl5.14
cd Perl5.14
wget http://www.cpan.org/src/5.0/perl-5.14.3.tar.gz
gunzip *.gz
tar -xvf *.tar
cd perl-5.14.3
./Configure -des -Dprefix=/opt/Perl5.14
make
make install
cd /opt/Perl5.14/bin
./perl -v

Note the /opt/Perl5.14 is important as it fits in with my mod to buildme.sh, so if you change, edit buildme.sh

So now we need to grab the CPAN files needed from Logitech. This is in their SVN, but I have replicated here to include the edits to buildme.sh.

cd /opt
git clone https://github.com/jamesarbrown/slimserver-vendor.git
cd slimserver-vendor/CPAN
./buildme.sh

Now we need the slimserver itself

cd /opt
git clone https://github.com/jamesarbrown/slimserver.git

Finally running Slimserver is done by

chown -R myuser.myuser slimserver
su myuser
/opt/Perl5.14/bin/perl -I /opt/slimserver-vendor/CPAN/build/arch/5.14 /opt/slimserver/slimserver.pl

For BBC Iplayer plugin on x86_64 it needed the 32 bit libraries for faad

yum install glibc.i686
Categories: Fedora Linux Tags:

Getting a Java Object from Server to CodeNameOne Phone App

September 17th, 2012 Comments off

Codenameone is a framework allowing users to code in Java and then port it to iPhone, Android, Blackberry and J2me devices, however there are some caveats.

Firstly it runs on a lightweight Java library, so not all methods are available, for instance ObjectOutputStream is one of them, so serializing an object is out of the question. My problem was I wanted to get a java.util.List from one to the other, as to break the list into multiple GET requests of String would be a headache (each list item contained a class with 30 String entries)

Secondly, you can not add binary libraries so that rules out JAX-WS and so on.

Codenameone however does have an Externalization function, so what we can do is externalize an object server side, make it available in a standard Http Servlet and then use the phone to get it via a standard Http request.

Below I am going to break down the major points of my approach. To start with we need an externalizable class. This class will be used in BOTH the phone app and on the server, below is a typical example :-

Cars.java

package com.enrogen.genesys.webservices;

import com.codename1.io.Externalizable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class Cars implements Externalizable {

    private String registration;
    private int stockno;
    private String manufacturer;
    
    public Cars() {
    }

    @Override
    public int getVersion() {
        return 1;
    };

    @Override
    public void externalize(DataOutputStream out) throws IOException {
        out.writeUTF(getRegistration());
        out.writeInt(getStockno());
        out.writeUTF(getManufacturer());
    };

    @Override
    public void internalize(int version, DataInputStream in) throws IOException {
        setRegistration(in.readUTF());
        setStockno(in.readInt());
        setManufacturer(in.readUTF());
    };
    
    @Override
    public String getObjectId() {
        return "Cars";
    };
    
    //Getters and Setters
    public String getRegistration() {
        return registration;
    }

    public void setRegistration(String registration) {
        this.registration = registration;
    }

    public int getStockno() {
        return stockno;
    }

    public void setStockno(int stockno) {
        this.stockno = stockno;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }
    
}

Although the externalizable class is available in the codename1 jar, it will not work server side with object[] as it does some checks to the phone type. Therefore we need to use a stripped version of the class. Downloadable below is a JAR you can drop in your project to provide the necessary Externalization imports.

http://www.jamesarbrown.com/wp-content/plugins/downloads-manager/img/icons/default.gif download: CodeName1Externalization.jar (10.04KB)
added: 17/09/2012
clicks: 152
description: Adds externalization function for use by servlet on web server

http://www.jamesarbrown.com/wp-content/plugins/downloads-manager/img/icons/default.gif download: CodeName1Externalization.zip (28.71KB)
added: 17/09/2012
clicks: 513
description: Netbeans Project Source

Ok, we now need a servlet to generate a response to the HTTP GET. Assuming you know how to create a JSF web project and put a servlet in there.

Servlet CarsListService.java

package com.enrogen.genesys.webservices;

import com.codename1.serverExternalization.io.Util;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CarsListService extends HttpServlet {

    public CarsListService() {
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            try {
                //Get the list of cars
                List<Cars> CarsList = getCars();
                Object[] objects = new Object[CarsList.size()];

                //Write the Cars externalizable objects to the objects[]
                for (int i = 0; i < CarsList.size(); i++) {
                    objects[i] = CarsList.get(i);
                }

                //Reference the servlet stream
                ServletOutputStream out = response.getOutputStream();
                DataOutputStream dos = new DataOutputStream(out);

                //Write to that Stream
                //Note the phone application must call Util.register
                //to be able to receive the Cars class
                //Util.register("Cars", Cars.class);
                Util.writeObject(objects, dos);
                
                //Close Servlet Stream
                out.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
    }

    public List<Cars> getCars() {
        List<Cars> CarsList = new LinkedList();
        
        //Car1
        Cars c1 = new Cars();
        c1.setManufacturer("Ford");
        c1.setRegistration("YX05 ABB");
        c1.setStockno(1);
        
        //Car2
        Cars c2 = new Cars();
        c2.setManufacturer("Volvo");
        c2.setRegistration("YB62 UXV");
        c2.setStockno(1);

        //Add them to our list
        CarsList.add(c1);
        CarsList.add(c2);
        
        return CarsList;
    }


    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     */
    @Override
    public String getServletInfo() {
        return "Returns a Externalized Cars Array (Object[])";
    }

    @Override
    public void destroy() {
    }

}

Ok thats it server side, put the necessary servlet information in web.xml and publish the server.

So onto the codename1 application to access the information. This is my code snippet to get from the servlet. You can then save with Codename1 Storage IO, leave in memory etc.

    public void readCarsList() {
        ConnectionRequest request = new ConnectionRequest() {
            @Override
            protected void readResponse(InputStream input) {
                try {
                    //Convert the stream into a DataInputStream
                    DataInputStream dis = new DataInputStream(input);
                    
                    //Register out custom class and then read all objects
                    Util.register("Cars", Cars.class);
                    Object[] objects = (Object[]) Util.readObject(dis);

                    //Write them to a list
                    List<Cars> l = new LinkedList();
                    for (int i = 0; i < objects.length; i++) {
                        l.add((Cars) objects[i]);
                    }

                    //Save it
                    //Display it
                    //Assign to a final, singleton etc thats accessible from here
                    //Do what you want with it
                  
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        request.setUrl("http://URL_to_the servlet);
        NetworkManager.getInstance().addToQueue(request);
        NetworkManager.getInstance().start();

Finally that left me with one problem. For our application I also wanted to get a byte[] array (which was a PNG image) from our SQL server and push it through.

In the cars class you would end up with this in the externalize function

        //public byte[] thumbnail from SQL
        //Do it byte by byte, first though, send the
        //length so we know how many bytes to receive.
        if (thumbnail != null) {
            out.writeInt(thumbnail.length);
            for (int i=0; i<thumbnail.length; i++) {
                out.writeByte(thumbnail[i]);
            }
        } else {
            out.writeUTF("");
        }

And this in the internalize

        //Find how many bytes, get them and glue them
        //back as a byte[] Array.
        int byteLength = in.readInt();
        byte[] bytes = new byte[byteLength];
        for (int i=0; i<byteLength; i++) {
            bytes[i] = in.readByte();
        }
        thumbnail = bytes;

Lastly to display in codeName1 I did this

//Image = import com.codename1.ui.Image
public Image getImageFromBytes(byte[] bytes) {
        try {
            InputStream is = new ByteArrayInputStream(bytes);
            Image i = EncodedImage.create(is);
            return i;
        } catch (Exception e) {
            return null;
        }
    }  

private Label imageLbl = new Label();
Image pic1 = getImageFromBytes(um.getThumbnail());
if (pic1 != null) {
    imageLbl.setIcon(pic1.scaledWidth(100));
}

//Add imageLbl to form
Categories: Java Tags:

Linux Security – Ban an Entire Country

June 10th, 2012 No comments

Yes at somepoint you will become fed up of spam, attacks and so on, and hey presto… it seems to me to always be ru and cn domains. That brazen they dont even bother with proxies.

So here is a script that will autofill the hosts.deny file with countries of your choosing. After all we don’t expect business from China anyway… too busy copying our industry?!

#!/bin/bash
# Copyright 2007 Michael Pagano
# Distributed under the terms of the GNU General Public License v2
# $Header$
#
# Modified by James A R Brown 2012 so countries added are the ones we
# want to ban.
#
# This script will download the country files from ipdeny.com, extract
# the ranges, backup the hosts.deny file, add the new ip's
#
# Special shout out to the folks at IPdeny who provide complete IP 
# block downloads as a free and public service. Check them out at
# http://www.ipdeny.com 
#
# If you use this script, please follow the usage rules of IPdeny 
# located at http://www.ipdeny.com/usagelimits.php

version=0.2jarb

# full name and path to hosts.deny
denyFile=/etc/hosts.deny

#backup directory for hosts.deny
backupDir=/tmp/

# array of countries to ban e.g. badCountries=( cn ru )
badCountries=( cn ru )

# url of ipdeny.com's MD5SUM to retrieve list of countries
downloadUrl=http://www.ipdeny.com/ipblocks/data/countries/
md5sumUrl=$downloadUrl/MD5SUM

usage() {
	echo "countryblock.sh [-h | -v]"
	echo "where"
	echo "	-v - print version information"
	echo "	-h - print usage"
	exit
}

for arg in $* ; do
    case "${arg}" in
    -v)
        echo "countryblock.sh version: $version"
		exit
        ;;
    -h)
        usage
		exit
        ;;
    esac
done

wget -m -nd $md5sumUrl

# did file download?
if [ ! -e MD5SUM ]; then
	echo "Could not locate ipdeny file: MD5SUM. Is the URL still valid?"
	echo "Url used: $md5sumUrl"
	exit 1
fi

# extract the country codes into an array
countryCodeList=$(awk < MD5SUM -F" " '{ split($2, a, ".");print a[1]}')
countryCodes=($countryCodeList)

# backup the old hosts.deny file
if [ ! -e $denyFile ]; then
	echo "Could not find file: $denyFile specified in the variable \$denyFile"
	exit
else
	#Create tar to backup first
	tar -cPzf $backupDir"hosts.deny."$(date +%Y%m%d%H%M%S).tgz $denyFile
fi

# delete the hosts.deny file
rm $denyFile

#iterate through the array skipping anything in the array safeCountries
for country in ${countryCodes[@]}
do
	country_is_bad="false"
	for badCountry in ${badCountries[@]}
	do
		if [ $badCountry = $country ]; then
			country_is_bad="true"
		fi
		if [ $country_is_bad = "true" ]; then
			# download the each country zone file
			zoneFile="$country.zone"
			wget -m -nd  $downloadUrl$zoneFile

			# make sure the file dowmloaded
			if [ ! -e $zoneFile ]; then
				echo "Problem downloading $downloadUrl$zoneFile"
			else
				# add the IP addresses to the new file
				awk < $zoneFile  '{ print "ALL: ",$0,"# ""'"$country"'"}' >> $denyFile
			fi
		fi
	done
done

#cleanup
rm MD5SUM

for country in ${countryCodes[@]}
do
	rm $country.zone 2>/dev/null
done

Categories: Fedora Linux Tags:

Garmin Forerunner 405 (ANT USB2) in Linux

April 14th, 2012 5 comments

RE-PUBLISHED FOR FEDORA 16

Today is my birthday… wahey!

Having reached that point in life where you either have to “get fat or get fit”, a few months ago I started running again… on sunny days where I feel vitalised.

My wife kindly has bought me a Garmin Forerunner 405, which comes with a Garmin “ANT+” dongle and per normal no Linux support. After pouring over much of google, I finally got it working in Linux Fedora and here is how.

Making the device be recognised to the system

My device reported (via lsusb) as follows

Bus 003 Device 005: ID 0fcf:1008 Dynastream Innovations, Inc.

Which apparently is a Version 2 Garmin device, and on plugging did not get a /dev/ttyUSB0 as most articles expected. A bit more digging in posts found this valuable snippet

< Fedora 15

sudo modprobe usbserial vendor=0x0fcf product=0x1008

This finally gave me a device in the form of /dev/ttyUSB0

Fedora 16 Onwards

It seems from Fedora 15 the usbserial module is compliled within the Kernel. Then from Fedora 16 we migrated from grub to grub2.

Find the file /etc/default/grub It will probably look like this

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Fedora"
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX="rd.md=0 rd.dm=0 rd.lvm.lv=vg_office/lv_root quiet SYSFONT=latarcyrheb-sun16 rhgb  KEYTABLE=uk rd.luks=0 rd.lvm.lv=vg_office/lv_swap LANG=en_US.UTF-8"

On the GRUB_CMDLINE_LINUX add the following to the end “usbserial.vendor=0x0fcf usbserial.product=0×1008″ so that we have something like this

GRUB_DISTRIBUTOR="Fedora"
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX="rd.md=0 rd.dm=0 rd.lvm.lv=vg_office/lv_root quiet SYSFONT=latarcyrheb-sun16 rhgb  KEYTABLE=uk rd.luks=0 rd.lvm.lv=vg_office/lv_swap LANG=en_US.UTF-8 usbserial.vendor=0x0fcf usbserial.product=0x1008"

Update the grub config by issuing

grub2-mkconfig > /boot/grub2/grub.cfg

Reboot!

 

 

Connecting and Downloading Software

To do this you need a piece of software called gant and be warned there are two pieces of software out there with the same name, both as of 15 Apr 2012 unable to locate on the internet, so I have put the working one up at https://github.com/jamesarbrown/Gant

So download it,

git clone git://github.com/jamesarbrown/Gant.git
cd Gant
make clean
make

You can now pair the device. On the Forerunner ensure under settings > computer that pairing is on, force send is on and enabled is on. Issue the following command. This will pair the device

./gant -f mydevname -a auth405

Once done you can either use the command line as follows

./gant -nza auth405 > output

Which will create a tcx v2 file which can be imported for instance into Garmin Connect or as follows something more Linux native.

I much prefered the program

./GantMonitor.py

Which Gave a nice icon on my Gnome taskbar

pytrainer

I will skip howto install pytrainer. There is enough out there, but to concentrate on how to import your file.

In pytrainer select File > Import. Select the plugins tab. It will appear as follows

Click the “Garmin Training Center File (v2)” configure button. Select Enabled. Once done you can click run and pick the file you want to import.

References

http://groups.google.com/group/golden-cheetah-users/browse_thread/thread/341ff35f231ee7b2

https://forums.garmin.com/showthread.php?t=9799

Categories: Fedora Linux Tags:

Automatically Opening an Info Window On Google Map (JSF2 Bean)

February 18th, 2012 Comments off

Currently I am working on a project with Primefaces and started out utilising the gmap component, but could not find a way to automatically open a marker info window. Basically I wanted it to be a company contact page, get a google map and open a box with the company info. Like this :-

To do this, firstly I created the JSF page in which it grabs values from a ManagedBean and inserts them to javascript variables (var). Once done it then loads the gmap.js javascript file detailed below. Finally as part of the h:body tag I have triggered an onload event.



mypage.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
    <f:view       xmlns:h="http://java.sun.com/jsf/html"
                  xmlns:f="http://java.sun.com/jsf/core"
                  xmlns:p="http://primefaces.org/ui"
                  xmlns:ez="http://java.sun.com/jsf/composite/ezcomp">
        <h:head>
            <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
            <script type="text/javascript">
                //Define the company details here before calling the gMap//
                var companyName = '#{ApplicationBean.companyName}'; 
                var companyAddress = '#{ApplicationBean.companyAddressHTML}';
                var companyLat = #{ApplicationBean.companyLat};
                var companyLong = #{ApplicationBean.companyLong};
                var companyFax = '#{ApplicationBean.companyFax}';
                var companyTel = '#{ApplicationBean.companyFax}';
                var companyEmail = '#{ApplicationBean.companyEmail}';
            </script>
            <script src="#{facesContext.externalContext.context.contextPath}/resources/javascript/gmap.js" type="text/javascript"></script>
        </h:head>

        <h:body onload="gMapInitialize()">
                    <div id="map" style="width:100%; height:100%"></div>
        </h:body>
    </f:view>
</html>

Finally we have the gmap.js that deals with the googleMaps API v3. “The infowindow.open(map,marker);” triggers the opening of the window without a user click.


gmap.js

function gMapInitialize() {
    var gMapLatlng = new google.maps.LatLng(companyLat, companyLong);
                    
    var gMapOptions = {
        center: new google.maps.LatLng(54.145921, -0.799813),
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
                    
    var map = new google.maps.Map(document.getElementById("map"), gMapOptions);
                    
    var marker = new google.maps.Marker({
        position: gMapLatlng,
        map: map,
        title: companyName
    });    
                
    var contentString = '<div id="content">'+
    '<h2>' + companyName + '</h2>'+
    '<div id="bodyContent">'+ companyAddress + '<BR/>' + 
    '<b>TEL : ' + companyTel + ' FAX : ' + companyFax + '<BR/>' +
    'EMAIL : <a href="mailto:' + companyEmail +'">' + companyEmail + '</a></b>' +
    '</div></div>';
                  
    var infowindow = new google.maps.InfoWindow({
        content: contentString
    });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
                    
    infowindow.open(map,marker);
}
Categories: Java Tags:

Custom IR for Logitech Harmony 300i (Mix 2 remotes into 1)

November 11th, 2011 Comments off

The Logitech Harmony 300i is towards the bottom end of the Harmony range but for most offers control of nearly everything they want. (TV, Cable/Sat, DVD and Aux)

I wanted the remote to use with my MythTV server, but in doing this I want the remote to emulate a Hauppauge A-415 remote, but for the following buttons :-

Vol Up
Vol down
Power

I want it to emulate the TVs remote buttons so the Tv deals with these directly, giving a seemless experience.

To programme this remote it uses the Logitech myHarmony.com web site.

    Unable to Connect Remote to myharmony.com

My first issue having dusted of the win 7 machine was to find out of the box the Logitech software would not recognise the remote. A bit of digging, found it utilised Microsoft Silverlight.

Install the Silverlight RC5 Runtime from here, reboot and go back to myHarmony.http://www.silverlight.net/learn/overview/what%27s-new-in-silverlight-5

That fixed for me.

    Unable to Sync

Then I got ahead of myself trying to be custom from the start, forget it, the combination of remote buttons I sent to the remote, broke the sync. Had to create a new account and restart.

Go for a standard known remote from the outset. In my case a Hauppage A-415.

    Overriding the buttons

Once myharmony is up and running you should something like this.

 

 

 

 

 

 

 

Click the “button” link. You will now have something like this.

 

 

 

 

 

 

 

 

The remote has default values, so now we need to change its setup and config via the “Teach Commands”. Click that and then select “Add A Missing Command”. You will be asked for a name, suggest something like MyMakeTVPower.

Then follow instructions to teach from your TV remote to the harmony.

You will then be returned to the graphic of the remote. Your new command will appear on the right hand side.

Simply drag your command off onto the button you want. Repeat the exercise for all the buttons you need to override, save and synchronise it.

On my remote I mixed NEC and RC5 remotes, no problems

Job done.

 

Making a MCE Reciever work with Generic RC5 Remote (Kernel 2.6.35+)

November 6th, 2011 Comments off

LIRC (Linux Infra-Red Remote Control) has recently undergone some major upheavals for the better as they are now part of the main stream kernel. So for some a kernel upgrade is breaking the remote controls, especially for custom setups.

This left me without a working remote, as I utilise a standard USB Microsoft Receiver (MCE Receiver), but not necessarily with the remote that belongs to it.

There a number of IR protocols that are all in the same Hz bandwidth the receiver is capable of receiving. Basically anything except B&O thats 400Hz. So there is no reason why it should not work with *nearly all* remotes.

Firstly, install some software. Namely Lirc0.9.1 and v4l-utils (which gives ir-keytable)

Then we can go and see if the kernel is accepting the RC. Plug in the device and it should report in /var/log/messages something on these lines

Nov  6 18:57:58 jblaptop kernel: [10199.956078] usb 8-2: new full speed USB device number 9 using uhci_hcd
Nov  6 18:57:58 jblaptop kernel: [10200.113069] usb 8-2: New USB device found, idVendor=0471, idProduct=0815
Nov  6 18:57:58 jblaptop kernel: [10200.113076] usb 8-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Nov  6 18:57:58 jblaptop kernel: [10200.113081] usb 8-2: Product: eHome Infrared Transceiver
Nov  6 18:57:58 jblaptop kernel: [10200.113085] usb 8-2: Manufacturer: Philips
Nov  6 18:57:58 jblaptop kernel: [10200.113089] usb 8-2: SerialNumber: PH00SUJT
Nov  6 18:57:58 jblaptop kernel: [10200.120051] Registered IR keymap rc-rc6-mce
Nov  6 18:57:58 jblaptop kernel: [10200.120232] input: Media Center Ed. eHome Infrared Remote Transceiver (0471:0815) as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.0/rc/rc7/input18
Nov  6 18:57:58 jblaptop kernel: [10200.120340] rc7: Media Center Ed. eHome Infrared Remote Transceiver (0471:0815) as /devices/pci0000:00/0000:00:1d.2/usb8/8-2/8-2:1.0/rc/rc7
Nov  6 18:57:58 jblaptop kernel: [10200.121188] rc rc7: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0
Nov  6 18:57:58 jblaptop kernel: [10200.121217] mceusb 8-2:1.0: Registered Philips eHome Infrared Transceiver on usb8:9
Nov  6 18:57:58 jblaptop mtp-probe: checking bus 8, device 9: "/sys/devices/pci0000:00/0000:00:1d.2/usb8/8-2"
Nov  6 18:57:59 jblaptop mtp-probe: bus: 8, device: 9 was not an MTP device

Now if we run ir-keytable, we get the following information

[root@jblaptop log]# ir-keytable
Found /sys/class/rc/rc7/ (/dev/input/event11) with:
Driver mceusb, table rc-rc6-mce
Supported protocols: NEC RC-5 RC-6 JVC SONY LIRC
Enabled protocols: RC-6
Repeat delay = 500 ms, repeat period = 125 ms

So there was my first issue, it was only receiving RC6 protocol. So to start with I enabled RC5 (Hauppauge A415 remote) as follows

[root@jblaptop log]# ir-keytable -p RC5 -s rc7
Protocols changed to RC-5

Now we have the receiver working on RC5, we can identify the keycodes the remote generates by running the command

evtest /dev/input/event11

Which will generate an unrecognised keymap as follows (this example is OK button)

Event: time 1320606374.418311, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e25

Go through them all writing down the values and then generate a file, lets call it /etc/rc_keymaps/custom

0x1e17 KEY_RIGHT
0x1e25 KEY_OK
0x1e1f KEY_EXIT

Note in my case I was lucky, there already was an /etc/rc_keymaps/hauppauge for my remote… so check through first before major work.

As we now have a keymap file, we want to override the one the kernel uses by default. Luckily for us, there is a new file called /etc/rc_maps.cfg which takes what the kernel is asking for and provides a filename accordingly. I backed up the file and created the following rc_maps.cfg. The kernel requested table can be identified from running ir-keytables

#Driver         Kernel Requested Table   File Provided (from /etc/rc_keymaps)
*               rc-rc6-mce               custom

For me it changes the protocol from RC6 to RC5 automatically.

This now gets a kernel key event from your remote, but we need to convert that kernel key event to a lirc key event. To do this a standard file is available from lirc. Put it into /etc/lirc

cd /etc/lirc
wget http://lirc.sourceforge.net/remotes/devinput/lircd.conf.devinput
mv lircd.conf.devinput lircd.conf

We can now startup lircd. I recommend to look in /dev/input/by-id so that your device name remains persistent across reboots. My lircd startup looks like this.

/usr/sbin/lircd --driver=devinput --device=/dev/input/by-id/usb-Philips_eHome_Infrared_Transceiver_PH00SUJT-event-if00

Try it, run irw and see that the key presses are being received from devinput by lircd and being translated correctly. Once done killall lirc and move on below.

So now for getting that into MythTV? Well presumably you have a lircrc file from before, it will look something like this, with entries for mapping a RC Key to a real Key(board). Watch out for KEY1_NUMERIC which now via devinput are KEY_1

begin
prog = mythtv
button = KEY_OK
config = Enter
end

Ensure mythtv is looking at the lircd stream on /var/run/lircd/lircd and ensure Myth starts AFTER lirc is running.

Nearly there…. but you will want lirc to start automatically. First edit /etc/sysconfig/lirc and add the driver and device (Fedora)

systemctl enable lirc
systemctl start lirc

One more thing… to prevent Xorg Display grabbing the events and causing double events, my xorg.conf needed the following adding

Section "InputClass"
     Identifier    "Remote"
     MatchProduct  "Media Center Ed. eHome Infrared Remote Transceiver"
     Option        "Ignore" "True"
EndSection

Good Luck.

Is Apple trying to Destroy customer choice? Yes….

October 30th, 2011 1 comment

When you go into a shop, online or otherwise, its nice to look at the products, compare them and make your choice.

Now I admit I have never liked Apple, its commercialisation in your face, must use Itunes, strict rules for their devices and when my wifes Ipad official Apple camera connection kit failed to work after Apple upgrade deemed it a security risk to hacking the ipad…. well….

No printing, no file sharing on a file server, no way to import photos without the Ipads app (ie you can not just copy and paste) and especially due to politics Apple/Adobe… no flash Player….. makes my blood boil. How do people tollerate these limitations?

Having said that the product quality and functionality is high. Infact incredibly high.

So I always, look for the alternatives, offering same functionality, yet more.. whats the word…. open. I dont want to hack the devices, I just want apps that I expect. The device should not hinder my daily activities.

But, it seems Apple, don’t think that competition should even exist, and are filing and enforcing patents all over the world, not about the hardware, not about the software, but how it interacts with the user.

Take for example their latest patent…. the sliding unlock bar no the ipad/phone by flicking left to right unlocks the device.

This article explains more http://www.patentlyapple.com/patently-apple/2011/10/apples-slide-to-unlock-patent-stirs-up-a-hornets-nest-in-taiwan.html

These patents if enforced are threatening to destroy what I feel is fair game. My view is this… if you create a device and the way it interacts with the user, changes the users culture so significantly, then that interaction does not become property of Apple or anybody, but infact becomes the property of the user world.

Imagine, if the car was just invented, and someone patented Accelerator, Brake and Clutch pedal order so that no other car manufacturer could use that order? Thats what Apple are trying to do.

Imagine if Microsoft could have patented things like Alt+F4, Ctrl+Alt+Del… or even Ctrl+P for printing.

And getting extreme, imagine if someone patented a digital clock on the desktop?!

Categories: Miscellanious Tags: , , ,