<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Runtux Blog &#187; howto</title>
	<atom:link href="http://blog.runtux.com/category/howto/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.runtux.com</link>
	<description>Neues, Interessantes, Skurriles</description>
	<lastBuildDate>Wed, 25 Aug 2010 16:55:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Skypes Flux Capacitor has been released</title>
		<link>http://blog.runtux.com/2010/08/25/167/</link>
		<comments>http://blog.runtux.com/2010/08/25/167/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 16:55:38 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=167</guid>
		<description><![CDATA[Skype uses an obfuscation layer for making it harder for others to analyze the Skype network traffic. This obfuscation layer has been called &#8220;Flux Capacitor&#8221; by the authors of the 2006 publications &#8220;Silver Needle in the Skype&#8221; and &#8220;Vanilla Skype&#8221;, Philippe Biondi, Fabrice Desclaux, and Kostya Kortchinsky, see the Wikipedia article on Skype for references [...]]]></description>
			<content:encoded><![CDATA[<p>Skype uses an obfuscation layer for making it harder for others to analyze the Skype network traffic. This <a href="http://en.wikipedia.org/wiki/Skype_protocol#Obfuscation_Layer">obfuscation layer</a> has been called &#8220;Flux Capacitor&#8221; by the authors of the 2006 publications &#8220;Silver Needle in the Skype&#8221; and &#8220;Vanilla Skype&#8221;, Philippe Biondi, Fabrice Desclaux, and Kostya Kortchinsky, see the <a href="http://en.wikipedia.org/wiki/Skype_protocol">Wikipedia article</a> on Skype for references about their publications. They discovered this flux capacitor code when reverse engineering the Skype binary program but didn&#8217;t dare to publish it for fear of others attacking the Skype network. They hinted at all sorts of bad things that were possible when knowing the Skype prototocol, the least of which is scanning networks behind firewalls (Skype is well known to be able to connect to the internet even in the presence of firewalls).<br />
Now this <a href="http://cryptolib.com/ciphers/skype/">Flux Capacitor code</a> has been released by a group called &#8220;Skype Reverse Engineering Team&#8221; in a blog post <a href="http://www.enrupt.com/index.php/2010/07/07/skype-biggest-secret-revealed">Skype&#8217;s Biggest Secret Revealed</a> by Sean O&#8217;Neil claiming that the code was already leaked and used by spammers. But they didn&#8217;t tell us how to use that code and defer further information to the next <a href="http://events.ccc.de/2010/07/30/27c3-we-come-in-peace-call-for-participation/">Chaos Communication Congress 27C3</a>.<br />
I certainly hope that the security holes in Skype are not that bad as feared by others. Some good can come out of it: maybe we&#8217;ll see a free Skype client in the not-too-far future. A good plan now would be to write a <a href="http://www.wireshark.org/">Wireshark</a> dissector for Skype so that we can analyze the network traffic. Unfortunately the authors didn&#8217;t tell us yet how to call that code to de-obfuscate Skype traffic. But there is plenty of information in the aforementioned publications. So I&#8217;ve written a <a href="http://project.runtux.com/skype/Makefile">Makefile</a> to create a shared library from the now released code and a <a href="http://project.runtux.com/skype/skype_deobfuscate.py">Python wrapper</a> that decrypts a single packet from a Skype network dump called <a href="http://wiki.wireshark.org/SampleCaptures?action=AttachFile&amp;do=view&amp;target=SkypeIRC.cap">SkypeIRC.cap</a> published on the <a href="http://www.wireshark.org/">Wireshark</a> page. This at least proves that the code works &#8212; the first several bytes of a Skype TCP stream decrypt to a known value.<br />
Maybe others want to use this as a starting point before more is released by the authors at the <a href="http://events.ccc.de/2010/07/30/27c3-we-come-in-peace-call-for-participation/">Chaos Communication Congress 27C3</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2010/08/25/167/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to get smartcards or crypto-tokens running on Debian Linux and Windows</title>
		<link>http://blog.runtux.com/2009/12/05/150/</link>
		<comments>http://blog.runtux.com/2009/12/05/150/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 16:16:23 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[documentation]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=150</guid>
		<description><![CDATA[This is a step-by-step Howto on installation and usage of the necessary commands to get smartcards or crypto-tokens working on Linux &#8212; and on Windows.
Smart card software on Linux consists of a driver for the card reader also called card terminal and a driver for the smartcard or token. There are two projects, OpenSC and [...]]]></description>
			<content:encoded><![CDATA[<p>This is a step-by-step Howto on installation and usage of the necessary commands to get smartcards or crypto-tokens working on Linux &#8212; and on Windows.<br />
Smart card software on Linux consists of a driver for the <em>card reader</em> also called <em>card terminal</em> and a driver for the <em>smartcard or token</em>. There are two projects, <a href="http://www.opensc-project.org/">OpenSC</a> and <a href="http://www.linuxnet.com/">MUSCLE</a>. Both projects produce drivers for card terminals (for OpenSC this sub-project is called <a href="http://www.opensc-project.org/openct/">OpenCT</a>) and for various cards. There are configuration options to make one project see the drivers of the other and vice versa.<br />
I&#8217;m using OpenCT (card terminal) and OpenSC (smart card) software because these have worked better for me &#8212; except for the pcscd daemon from the MUSCLE project that might be needed for some applications. If you&#8217;re using software that depends on a <a href="http://en.wikipedia.org/wiki/PC/SC">PC/SC</a> interface, you&#8217;ll also need to install the pcscd daemon (comes as a debian package).<br />
Manufacturers are continuously improving their smartcards and the applications that run on the card. Up to now this has created an ever-changing pile of middleware to talk to these cards. An idea to improve the situation was a programmable card: Put a Java interpreter on the card and provide applets (so-called &#8220;cardlets&#8221;) for applications. The idea claims this would improve the situation for middleware on the host. Unfortunately this isn&#8217;t quite true: The Java virtual machine on smartcards is subject to change. So we have cards with a recent JVM and old cards with an ancient (1.1 from 2001) JVM. This means the applet needed to make the card work has to be cross-compiled to an older JVM depending on the card used. And there are still a number of host configuration issues.<br />
The situation is worsened by the fact that many manufacturers of smartcards provide cards with their proprietary cardlet in the ROM of the card. This means these cards cannot be used with the applet that matches your middleware. And we&#8217;re back to the start and have to write a driver for the proprietary (this time java) middleware as before.<br />
If you&#8217;re using Java-based smartcards you need to get a card that can accept a new applet and has the necessary developer keys published. Usually these cards are called &#8220;developer version&#8221; or similar. You then can use the MCardApplet from the <a href="http://muscleplugins.alioth.debian.org/">MUSCLE plugins</a> project. I recommend to build the applet yourself &#8212; after all this is a security application where your security depends on the software running on the card. There is a section below for preparing a java card with the appropriate applet.<br />
I got the eToken PRO 32k (4.2B) working with OpenSC but not the eToken PRO 72k (Java). The first uses Siemens CardOS, the number in parentheses denotes the version number. Unfortunately these old CardOS based tokens will be discontinued, and Siemens seems to have announced end of life status for its CardOS.<br />
The 72k eToken from Aladdin uses Java and needs a Java applet. The OpenSC project claims that the Java token works with OpenSC, but it didn&#8217;t for me. Maybe the token wasn&#8217;t a developer version that can accept an applet. The token also didn&#8217;t work under windows (although it worked with the Aladdin software there, i.e., I could initialize it) and I had a recent OpenSC binary release for windows from October 2009.<br />
From the <a href="http://www.opensc-project.org/opensc/">OpenSC documentation</a>: &#8220;For programmable java cards: the support is for the card with the specific applet &#8211; if you have a different applet on your card, it might not be supported.&#8221;<br />
First steps for non-Java cards or Java-cards with MCardApplet installed (for installation of the applet, see below):<br />
Install smartcard software and card terminal framework:
<pre>

apt-get install pcscd opensc libengine-pkcs11-openssl
</pre>
<pre>
The following NEW packages will be installed:
  libengine-pkcs11-openssl libp11-0
</pre>
<p>If your smartcard reader is <em>not</em> supported by <code>pcscd</code>, you should install the <code>openct</code> package in addition to the packages above. You can then run <code>pcscd</code> on top of <code>openct</code>.<br />
After installing these programs, we need to configure pcscd to correctly use our reader. Configure <code>/etc/opensc/opensc.conf</code> to use the pcscd method, search for <code>reader_drivers</code> inside the <code>app default</code> stanza of the config file and modify this to:</p>
<pre>
reader_drivers = pcsc;
</pre>
<p>For CCID compatible readers without <code>openct</code> installed, the reader should be visible after plugging in the reader into the USB port:</p>
<pre>
Readers known about:
Nr.    Driver     Name
0      pcsc       Gemplus GemPC Key 00 00
</pre>
<p>If the card reader is not directly supported by pcscd (but is supported by openct) we need to configure <code>/etc/reader.conf.d/openct</code>, a config file of pcscd, to use OpenCT as the input method, for this the file should contain:</p>
<pre>
FRIENDLYNAME     "OpenCT"
DEVICENAME       /dev/null
LIBPATH          /usr/lib/openct-ifd.so
CHANNELID        0
</pre>
<p>after modifying this file on Debian (on non-Debian systems you&#8217;ll probably have to modify <code>/etc/reader.conf</code> directly) we have to run:</p>
<pre>
update-reader.conf
</pre>
<p>which creates a new <code>/etc/reader.conf</code>. Now stop and restart openct and pcscd in the following order:</p>
<pre>
/etc/init.d/pcscd stop
/etc/init.d/openct restart
/etc/init.d/pcscd start
</pre>
<p>When everything went OK, you should see a pcscd based reader using <code>opensc-tool</code>:</p>
<pre>
opensc-tool -l
</pre>
<pre>
Readers known about:
Nr.    Driver     Name
0      pcsc       OpenCT 00 00
</pre>
<p>Add user to &#8220;scard&#8221; group in /etc/group and log in again to have the permissions to access the card. This is necessary if you want to use a reader provided by openct without going through <code>pcscd</code>.<br />
If all else fails, you can still use <code>openct</code> without <code>pcscd</code> and set <code>reader_drivers</code> in <code>/etc/opensc/opensc.conf</code> to:</p>
<pre>
reader_drivers = openct;
</pre>
<p>Then a reader should be visible like this:
<pre>

opensc-tool -l
</pre>
<pre>
Readers known about:
Nr.    Driver     Name
0      openct     Aladdin eToken PRO 64k
1      openct     OpenCT reader (detached)
2      openct     OpenCT reader (detached)
3      openct     OpenCT reader (detached)
4      openct     OpenCT reader (detached)
</pre>
<p>Now we should be able to read the card, if there is only one token in the USB port and no other smartcard readers are installed, we can leave out the -r option (for specifying the reader to use):
<pre>

cardos-info
</pre>
<pre>
3b:f2:18:00:02:c1:0a:31:fe:58:c8:09:75
Info : CardOS V4.2B (C) Siemens AG 1994-2005
Chip type: 123
Serial number: 27 37 c0 09 2b 18
Full prom dump:
33 66 00 45 CB CB CB CB 7B FF 27 37 C0 09 2B 18 3f.E....{.'7..+.
00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
OS Version: 200.9 (that's CardOS M4.2b)
Current life cycle: 32 (administration)
Security Status of current DF:
Free memory : 1024
ATR Status: 0x0 ROM-ATR
Packages installed:
Ram size: 4, Eeprom size: 32, cpu type: 66, chip config: 63
Free eeprom memory: 27686
System keys: PackageLoadKey (version 0xfe, retries 10)
System keys: StartKey (version 0xff, retries 10)
Path to current DF:
</pre>
<p><b>1.&#160;&#160;&#160;Using Java-based Smartcards</b><br />
Java-based smartcards need some preparation to work with OpenSC. First you should make sure that you have a card that permits you to upload your own applet (cardlet) to the card. This usually means you need a so-called developer version. Avoid cards that have a proprietary manufacturer applet in read-only memory! You also usually need some development keys to upload a cardlet to the card.<br />
For the following instructions I&#8217;ve used the Gemalto TOP IM FIPS CY2 (Cyberflex Access 64k v2) which is an old card that has a Java virtual machine version 1.1 from 2001 (!) but the card is well established and will probably be available for some time.<br />
For the card reader I&#8217;ve used the Gemalto USB Shell V2 (GemPC Key), a CCID compatible reader. When buying a new reader, you should use one that follows the CCID specification from the <a href="www.pcscworkgroup.com">PC/SC Workgroup</a>, this ensures that OpenCT will support it. The card reader I&#8217;m using can read <a href="http://en.wikipedia.org/wiki/ID-000#ID-000">ID-000</a> format cards, also called SIM cards. These are small form-factor cards that are nice for authentication purposes. The Cyberflex card I&#8217;m using is available in ID-000. If a card isn&#8217;t available in ID-000, chances are you can make it fit using a service similar to this <a href="http://www.smartcardfocus.com/shop/ilp/id~82/p/index.shtml">SIM cutting service</a>.<br />
Preparing the card for use with OpenSC is a two-step process. The first step is to obtain the necessary applet for the card. The second is to upload the applet to the card and initialize the card with a default PIN. Note that 2048 bit keys may not work with MCardApplet with the current software versions, see <a href="#some-notes-on-key-sizes">Some notes on key sizes</a>.</p>
<p><b>1.1.&#160;&#160;&#160;Obtaining the MCardApplet for your card</b><br />
I recommend building your own version of the applet from source. Get the source code from svn://svn.debian.org/muscleplugins/trunk/MCardApplet using the source code control tool subversion:
<pre>

svn co svn://svn.debian.org/muscleplugins/trunk/MCardApplet
</pre>
<p>I had to make several changes to use Java 1.6 for cross-building for the ancient Java VM that runs on the card. My <code>Cflex.properties</code> looks like this:</p>
<pre>
CARD_NAME=Cflex
JAVA_BUILD_HOME=/usr
JC_HOME=${basedir}/depends/jc212
API_JAR=${JC_HOME}/lib/api21.jar
API_EXPORT_FILES=${JC_HOME}/api21_export_files
CAPTRANS=${basedir}/depends/jc212/bin/captransf.jar
VM_SOURCE_VERSION=1.2
VM_TARGET_VERSION=1.1
BOOTCLASSPATH=${basedir}/depends/jdk1.2.2/depends/jdk1.2.2/lib
</pre>
<p>In particular, I&#8217;m using the native java environment installed on debian lenny. This lives in /usr. Otherwise you should follow the excellent building instructions in the file <code>INSTALL</code>. Then I&#8217;ve modified the <code>javac</code> in the target named <code>compile</code> in the common.xml ant build file as follows:</p>
<pre>
&lt;target depends="precompile" name="compile"&gt;
    &lt;mkdir dir="${OUTPUT_DIR}"/&gt;
    &lt;javac debug="on"
        verbose="on"
        fork="true"
        executable="${JAVA_BUILD_HOME}/bin/javac"
        srcdir="${APPLET_SRC}"
        destdir="${OUTPUT_DIR}"
        target="${VM_TARGET_VERSION}"
        source="${VM_SOURCE_VERSION}"&gt;
        &lt;bootclasspath&gt;
            &lt;pathelement location="${BOOTCLASSPATH}"/&gt;
        &lt;/bootclasspath&gt;
        &lt;classpath&gt;
            &lt;pathelement location="${API_JAR}"/&gt;
            &lt;pathelement location="."/&gt;
            &lt;pathelement path="${java.class.path}"/&gt;
        &lt;/classpath&gt;
    &lt;/javac&gt;
&lt;/target&gt;
</pre>
<p>I&#8217;ve added the target and source options. These refer to the specific java virtual machine version we&#8217;re cross-building for. I&#8217;ve also added the bootclasspath to get the classes that are VM specific from the old java development package.<br />
This allows me to cross-build the applet for an old version of the java virtual machine without running the old java development environment which does no longer run on recent versions of Linux due to library incompatibilities.<br />
I also had to change all the backslashes in <code>common.xml</code> to forward slashes. It looks like the java compiler can handle the backslashes in path names, but the other tools cannot.<br />
Before building you should also look through <code>CflexCapabilities.properties</code> for any capabilities you want to enable which are not enabled in the default configuration. I had to enable <code>-DWITH_RSA_2048</code> and <code>-DWITH_SIGN</code> for example.<br />
For the impatiant I&#8217;m offering a <a href="http://project.runtux.com/download/CardEdgeCflex.ijc">pre-compiled version</a> of the applet. I&#8217;ll update this text with the build instructions soon.</p>
<p><b>1.2.&#160;&#160;&#160;Uploading the applet to the card</b><br />
As a preparation for this step, you should install the pcsc daemon and the pcsclite development packages on debian:
<pre>

apt-get install pcscd libpcsclite-dev
</pre>
<p>For uploading the applet to the card, I recommend using <a href="http://downloads.sourceforge.net/project/globalplatform/GPShell/GPShell-1.4.2/gpshell-1.4.2.tar.gz">gpshell</a>, a tool from the <a href="http://sourceforge.net/projects/globalplatform/">globalplatform project</a> which depends on the <a href="http://downloads.sourceforge.net/project/globalplatform/GlobalPlatform%20Library/GlobalPlatform%20Library%205.0.0/globalplatform-5.0.0.tar.gz">globalplatform library</a>. Unfortunately these are not yet packaged as Debian packages, so obtain the sourcecode to both, <a href="http://downloads.sourceforge.net/project/globalplatform/GPShell/GPShell-1.4.2/gpshell-1.4.2.tar.gz">gpshell</a> and the <a href="http://downloads.sourceforge.net/project/globalplatform/GlobalPlatform%20Library/GlobalPlatform%20Library%205.0.0/globalplatform-5.0.0.tar.gz">globalplatform library</a> . Unpack these packages and build using the normal process:</p>
<pre>
./configure
make
make install
</pre>
<p>For the <a href="http://downloads.sourceforge.net/project/globalplatform/GlobalPlatform%20Library/GlobalPlatform%20Library%205.0.0/globalplatform-5.0.0.tar.gz">globalplatform library</a> you need the development libraries for libpcsclite, available as the Debian package <code>libpcsclite-dev</code> which should be installed before the <code>./configure</code> step above.<br />
If you installed the globalplatform library without root privileges, you have to run <code>ldconfig</code> as root to make the new library available in the shared library cache.<br />
Check that your smartcard services are running (see above for how to do that) and verify that you see your card reader (or token) using:
<pre>

opensc-tool -l
</pre>
<p>The <code>gpshell</code> tool interfaces to the card via pcscd, so you should see something similar to the following:</p>
<pre>
Readers known about:
Nr.    Driver     Name
0      pcsc       Gemplus GemPC Key 00 00
</pre>
<p>Now we can proceed to upload the applet using <code>gpshell</code>. We need the following <a href="http://project.runtux.com/download/applet_install.gpshell">applet upload gpshell script</a>, put this into the file <code>applet_install.gpshell</code>, note that lines terminated with &#8220;\&#8221; need to be concatenated, gpshell currently doesn&#8217;t understand continuation lines:</p>
<pre>
enable_trace
establish_context
card_connect
select -AID a000000003000000
open_sc -security 1 -keyind 0 -keyver 0 \
   -mac_key 404142434445464748494a4b4c4d4e4f \
   -enc_key 404142434445464748494a4b4c4d4e4f
delete -AID a00000000101
delete -AID a000000001
delete -AID a0000003230101
delete -AID a00000032301
install_for_load -pkgAID a000000001 -nvCodeLimit 16000 \
   -sdAID a000000003000000
load -file CardEdgeCflex.ijc
install_for_install -instParam 00 -priv 02 -AID a00000000101 \
   -pkgAID a000000001 -instAID a00000000101 -nvDataLimit 32000
card_disconnect
release_context
</pre>
<p>and run the script with <code>gpshell</code>:</p>
<pre>
gpshell applet_install.gpshell
</pre>
<p>Finally we will have to set a default PIN for the card using <code>opensc-tool</code>:</p>
<pre>
opensc-tool -s 00:A4:04:00:06:A0:00:00:00:01:01 -s \
B0:2A:00:00:38:08:4D:75:73:63:6C:65:30:30:04:01:08:\
30:30:30:30:30:30:30:30:08:30:30:30:30:30:30:30:30:\
05:02:08:30:30:30:30:30:30:30:30:08:30:30:30:30:30:\
30:30:30:00:00:17:70:00:02:01
</pre>
<p>This sets the PIN to eight zeros, &#8220;00000000&#8243;. After this procedure the card can be used like a normal <a href="http://en.wikipedia.org/wiki/PKCS">PKCS#15</a> based card with OpenSC.</p>
<p><b>1.2.1.&#160;&#160;&#160;Some notes on using the gpshell script with other cards</b><br />
Many of the magic numbers in the gpshell script depend on the card in use and on the applet that is uploaded. An <code>AID</code> is an applet-ID. The <code>open_sc</code> command has nothing to do with OpenSC, but opens a secure channel to the card. The parameters are the developer keys of the card. In our example, the key is used twice and the hex-bytes denote the string:</p>
<pre>
@ABCDEFGHIJKLMNO
</pre>
<p>The AID used for the secure channel is different for other brands of cards. I was able to find out this AID using the following <a href="http://project.runtux.com/download/aid.gpshell">AID gpshell script</a>:</p>
<pre>
enable_trace
establish_context
card_connect
open_sc -security 1 -keyind 0 -keyver 0 \
   -mac_key 404142434445464748494a4b4c4d4e4f \
   -enc_key 404142434445464748494a4b4c4d4e4f
get_status -element 80
card_disconnect
release_context
</pre>
<p>This displays for the Gemalto TOP IM FIPS CY2:
<pre>

List of applets (AID state privileges)
a000000003000000        7       0
</pre>
<p>The delete commands remove older versions of the applet &#8212; there also was a version that had another applet ID &#8212; from the card before uploading the new version. Think of the applet living in a package named a000000001 and the applet named a00000000101. The <code>install_for_load</code> command establishes the package inside the a000000003000000 package. Then the <code>install_for_install</code> command installs the applet into non volatile memory after upload.<br />
Note that these numbers are hard-coded into the applet that is being uploaded. This is defined during compile-time and for the MCardApplet this can be configured in the <code>common.xml</code> ant-file. When packaging the compiled java classes, the build process generates <code>.cap</code> files which contain the applet ID in binary format, notably the <code>Applet.cap</code> file contains the AID of the applet.<br />
So if these numbers are changed when building a custom applet, be sure to adapt the upload commands, too. A warning here: All tools that depend on the MCardApplet expect the given AID, so changing the AID would incur a change of all tools or at least their configuration.</p>
<p><b>2.&#160;&#160;&#160;OpenVPN Preparation: Step by step process with high-level tool</b><br />
This section describes how to initialize a token, create a user key and certificate using tools that come with OpenVPN. This was only tested on Linux since the certificate handling scripts for OpenVPN are more advanced on Linux.<br />
I had to patch the <code>pkitool</code> of OpenVPN to use the <code>pkcs15-init</code> command instead of the <code>pkcs11-tool</code> command for initializing the token and creating keys. The reason is that Aladdin limits their tokens to use one key for only one purpose (encryption or signing). The <code>pkcs15-init</code> command allows the specification of the key purpose while the <code>pkcs11-tool</code> command does not.<br />
In the following we assume you are in the easy-rsa directory of OpenVPN, and you have initialized the configuration by reading the configuration in <code>vars</code>. It&#8217;s also always a good idea to have a backup of all the OpenVPN keys before starting.<br />
Initializing the token for first use (or re-using an already formatted token) THIS DESTROYS ALL DATA ON THE TOKEN:
<pre>

./pkitool --pkcs15-init 0 "Thomas Mustermann"
</pre>
<pre>
New User PIN.
Please enter User PIN:
Please type again to verify:
Unblock Code for New User PIN (Optional - press return for no PIN).
Please enter User unblocking PIN (PUK):
Please type again to verify:
</pre>
<p>If the token was already initialized, the procedure would also ask for the old password.<br />
Now we can check that everything worked, by looking at the PINs:
<pre>

pkcs15-tool --list-pins
</pre>
<p>Now we can proceed to generate a key pair and a certificate, this takes a long time:
<pre>

./pkitool --pkcs15 /usr/lib/opensc-pkcs11.so 0 45 "user cert" client27
</pre>
<p>When everything went OK, we should be able to display keys, public keys, and certificates on the token:
<pre>

pkcs15-tool --list-keys
pkcs15-tool --list-public-keys
pkcs15-tool --list-certificates
</pre>
<p><b>3.&#160;&#160;&#160;What is needed for Windows</b><br />
I&#8217;ve first installed the latest <a href="http://openvpn.net/release/openvpn-2.1_rc21-install.exe">OpenVPN installer</a>, only this package has the necessary <code>TAP</code> network driver for Linux. Only the TAP driver needs to be installed.<br />
I&#8217;ve used a compiled version of OpenVPN that comes bundled with OpenSC from the binary <a href="http://www.opensc-project.org/files/build/">windows repository</a>, I&#8217;ve used the latest</p>
<pre>
opensc-i686-w32-mingw32-007-*.*
</pre>
<p>files (from Oct 2009). For 64bit Windows (AMD64) the
<pre>

opensc-x86_64-pc-mingw32-003*.*
</pre>
<p>files should be used. Everything unpacked from these files should be installed to
<pre>

C:\Programs\OpenVPN
</pre>
<p>I&#8217;ve also created a configuration directory under that directory called <code>config</code>. In config there are the necessary certificates (root ca) and hash keys and the <code>client.ovpn</code> configuration file.<br />
When using my OpenVPN admin script, Python for windows from <a href="http://www.python.org">python.org</a> and the <code>Python WIN32</code> package are needed. In addition my <a href="http://rsclib.sourceforge.net">rsclib</a> library needs to be installed. For installing rsclib, unpack the <code>.zip</code> file and run:</p>
<pre>
setup.py install
</pre>
<p>from a command prompt. The admin script in <code>pyovpn.zip</code> has the same installation procedure.<br />
After installing everything, basic working of the smart card can be verified with the OpenSC tools:
<pre>

opensc-tool -l
cardos-info
pkcs15-tool --list-certificates
</pre>
<p><b>3.1.&#160;&#160;&#160;Aladdin Token</b><br />
For using the Aladdin eToken with Windows, the smart card tools of the manufacturer have to be installed &#8212; these include the driver for accessing the tokens. I&#8217;ve used:
<pre>

PKIClient-x32-5.00.msi
</pre>
<p>from
<pre>

eToken PKI Client 5.0 SP1 Windowsx32.zip
</pre>
<p><b>3.2.&#160;&#160;&#160;Gemalto USB Shell Token V2</b><br />
The driver for the Gemalto USB Shell Token reader can be downloaded free of charge from the <a href="http://support.gemalto.com/index.php?id=61">Gemalto website</a>.</p>
<p><b>4.&#160;&#160;&#160;Using OpenVPN with SmartCard</b><br />
OpenVPN uses a PKCS#11 provider library, on Debian this is <code>/usr/lib/opensc-pkcs11.so</code>, to access the smart card. We can show which certificates are on the card by issuing:</p>
<pre>
openvpn --show-pkcs11-ids /usr/lib/opensc-pkcs11.so
</pre>
<pre>
The following objects are available for use.
Each object shown below may be used as parameter to
--pkcs11-id option please remember to use single quote mark.

Certificate
      DN:             /C=AT/ST=AT/L=Weidling/ ...
      Serial:         03
      Serialized id:  OpenSC\x20Project/PKCS\x20 ...
</pre>
<p>Now OpenVPN can be started with the smartcard. I&#8217;m using the following additional config entries for OpenVPN &#8212; <code>pkcs11-providers</code> is set to the path of the PKCS#11 provider library:</p>
<pre>
pkcs11-providers "/usr/lib/opensc-pkcs11.so"
pkcs11-id-management
management 127.0.0.1 4711
management-query-passwords
management-hold
</pre>
<p>For Windows the provider library becomes (assuming the OpenSC tools where installed to C:ProgramsOpenVPNbin):
<pre>

pkcs11-providers "C:\\Programs\\OpenVPN\\bin\\opensc-pkcs11.dll"
</pre>
<p>The other parameters are the same as for other operating systems.<br />
Note also that the <code>askpass</code> option of OpenVPN does <em>not</em> work for querying the token password. In my experiment I had to give the token password to OpenVPN via the management interface using the config option <code>management-query-passwords</code>.<br />
This configuration tells OpenVPN to open the management interface on Port 4711 of localhost. It will ask for the passphrase of the Aladdin token on that port. Additionally we wait (<code>management-hold</code>) until a management program has opened the management interface and told OpenVPN to proceed.<br />
The <code>pkcs11-id-management</code> tells OpenVPN to accept the <code>pkcs11-id</code> to use via the management interface. With a little intelligence in the management interface we can avoid having the pkcs11-id in the configuration file (which would then be different for each user).<br />
OpenVPN can be asked via the management interface about a listing of all <code>pkcs11-ids</code>. If there is only one certificate on the card, we feed the id of the only certificate back to OpenVPN when it asks about the pkcs11-id. This can be done without user intervention.<br />
Unfortunately the feature that OpenVPN can ask the smartcard for all the certificates depends on the Token being present when OpenVPN is started. An alternative is to specify the <cite>pkcs11-id`</cite> directly in the configuration file. If this is specified, the management interface will ask for the token if it isn&#8217;t present when starting OpenVPN. The parameter to the <code>pkcs11-id</code> config parameter is the <code>Serialized id</code> from the command output above.<br />
Since I have not found any graphical user interface programs for OpenVPN that can deal with asking the user for the token passphrase, I&#8217;ve written a little command-line python script which can be run on both, Windows and Linux, and will ask the user to insert the token and specify the token passphrase.<br />
OpenVPN can be started with the script by issuing the command:
<pre>

pyovpn
</pre>
<p>in a command prompt window. The command will start openvpn and proceed to ask for necessary token passwords.<b></p>
<p>4.1.&#160;&#160;&#160;Low-level usage of the management interface</b><br />
With the <code>management-query-passwords</code> option, OpenVPN will ask the password from the management interface. After starting the OpenVPN daemon and connnecting to the managment interface on the defined port (e.g., using telnet) we see the following message:</p>
<pre>
&gt;INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info
&gt;PASSWORD:Need 'OpenSC Card (New User) token' password
</pre>
<p>The password can then be entered using the password command of the managment interface:
<pre>

password 'OpenSC Card (New User) token' sehrgeheimespasswort
</pre>
<p>OpenVPN answers with:
<pre>

SUCCESS: 'OpenSC Card (New User) token' password entered, but not yet verified
</pre>
<p><b>5.&#160;&#160;&#160;Key Revocation</b><br />
Revoke a certificate:
<pre>

openssl ca  -config $KEY_CONFIG -revoke keys/02.pem
</pre>
<p>(re-) generate key revocation list (CRL):
<pre>

openssl ca  -config $KEY_CONFIG -gencrl -out keys/crl.pem
</pre>
<p><b>6.&#160;&#160;&#160;OpenVPN Preparation: Step by step process with low-level tools</b><br />
This section describes the low-level tools as used by the patched <code>pkitool</code> from OpenVPN. It does not create a certificate with OpenSSL. This is for documentation purposes only (to understand what goes on behind the scenes) and was my first approach to getting started with OpenSC.</p>
<ul>
<li>
Erase the card &#8212; if you already have a Security Officer PIN installed, you need this for erasing the card:
<pre>

pkcs15-init -E
</pre>
</li>
<li>
Create PKCS#15 structure (option &#8211;no-so-pin specified not to create security officer PIN and user PUK) on the card &#8212; note that the keys need to be between 6 and 8 characters long and should be numeric if you intend to use a keypad for key-entry (which applies mostly to smartcards not to USB tokens). Also note that if you omit &#8211;no-so-pin you should keep the Security Officer PIN secure &#8212; only with it can the token be re-formatted:
<pre>

pkcs15-init --create-pkcs15 --no-so-pin
</pre>
<pre>
New Security Officer PIN (Optional - press return for no PIN).
Please enter Security Officer PIN:
Please type again to verify:
Unblock Code for New User PIN (Optional - press return for no PIN).
Please enter User unblocking PIN (PUK):
Please type again to verify:
</pre>
</li>
<li>
The steps above can be rolled into one command:
<pre>

pkcs15-init -E --create-pkcs15 --no-so-pin
</pre>
</li>
<li>
Add an authentication (user) ID to the token with corresponding PIN and PUK:
<pre>

pkcs15-init --store-pin --auth-id 01 --label "User Name"
</pre>
<pre>
New User PIN.
Please enter User PIN:
Please type again to verify:
Unblock Code for New User PIN (Optional - press return for no PIN).
Please enter User unblocking PIN (PUK):
Please type again to verify:
</pre>
</li>
<li>
Check that everything worked, by looking at the PINs:
<pre>

pkcs15-tool --list-pins
</pre>
<pre>
PIN [Security Officer PIN]
    Com. Flags: 0x3
    ID        : ff
    Flags     : [0xB2], local, initialized, needs-padding, soPin
    Length    : min_len:6, max_len:8, stored_len:8
    Pad char  : 0x00
    Reference : 1
    Type      : ascii-numeric
    Path      : 3f005015

PIN [User Name]
    Com. Flags: 0x3
    ID        : 01
    Flags     : [0x32], local, initialized, needs-padding
    Length    : min_len:4, max_len:8, stored_len:8
    Pad char  : 0x00
    Reference : 3
    Type      : ascii-numeric
    Path      : 3f005015
</pre>
</li>
<li>
Now we can generate an RSA key on the card. Note that we could also import a PKCS-12 key onto the card, but the more secure option is to let the card generate the key (so the key will never be available outside the card). The split-key option actually generates two key-pairs, one for encryption and one for signing. There are some labelling options to attach names to the generated keys but these aren&#8217;t needed if you want only one key. You could specify an application profile with the &#8211;id option, if this isn&#8217;t given the default ID 45 (authentication purposes) is used. The command will ask for the Security officer PIN, then for the User PIN, then again for the Security officer PIN (!):
<pre>

pkcs15-init --generate-key rsa/2048 --auth-id 01 --split-key
</pre>
<p>Note that with Java smartcards the keysize 2048 might not work with the current version of the tools, see <a href="#some-notes-on-key-sizes">Some notes on key sizes</a>.
</li>
<li>
Now we can verify that the key was actually stored on the card:
<pre>

pkcs15-tool --list-keys
</pre>
<pre>
Private RSA Key [Private Key]
    Com. Flags  : 3
    Usage       : [0x4], sign
    Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local
    ModLength   : 2048
    Key ref     : 16
    Native      : yes
    Path        : 3f005015
    Auth ID     : 01
    ID          : 45
</pre>
</li>
<li>
List public keys:
<pre>

pkcs15-tool --list-public-keys
</pre>
<pre>
Public RSA Key [Public Key]
    Com. Flags  : 2
    Usage       : [0x4], sign
    Access Flags: [0x0]
    ModLength   : 2048
    Key ref     : 0
    Native      : no
    Path        : 3f0050153048
    Auth ID     :
    ID          : 45
</pre>
</li>
<li>
For the following steps we will need a minimum openssl config file:
<pre>

openssl_conf            = openssl_init

[ openssl_init ]
engines                 = engine_section

[ req ]
default_bits            = 2048
default_keyfile         = privkey.pem
distinguished_name      = req_distinguished_name

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = AT
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Austria
localityName                    = Locality Name (eg, city)
localityName_default            = Vienna
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = example.com
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = IT-Department
commonName                      = Common Name (eg, server\'s hostname)
commonName_max                  = 64
emailAddress                    = Email Address
emailAddress_max                = 40

[ engine_section ]
pkcs11 = pkcs11_section

[ pkcs11_section ]
engine_id = pkcs11
dynamic_path = /usr/lib/engines/engine_pkcs11.so
MODULE_PATH = /usr/lib/opensc-pkcs11.so
init = 0
</pre>
</li>
<li>
Generate a certificate request (CSR) from this key using openssl:
<pre>

CLIENT=newclient
openssl req -days 3650 -new -out $CLIENT.csr -config openssl.cnf \
  -engine pkcs11 -keyform engine -key 0:45 -sha1
</pre>
<p>This will ask for all the certificate parameters. Alternatively these can be specified using the <code>-subj</code> option of openssl (this is broken into several lines but should be assembled into one line) with the following parameter:</p>
<pre>
/C=AT/ST=Austria/L=Vienna/O=example.com/OU=IT-Department
/CN=$CLIENT/emailAddress=user@example.com
</pre>
</li>
<li>
You can view the contents of the CSR using:
<pre>

openssl req -in $CLIENT.csr -noout -text
</pre>
</li>
<li>
Now sign the certificate request with whatever tools you are using. With the pkitool of OpenVPN this would become (after having copied the certificate request newclient.csr to the keys directory):
<pre>

pkitool --sign newclient
</pre>
<p>The message about not being able to access <code>newclient.key</code> can be ignored.
</li>
<li>
You may want to delete old certificates from the token:
<pre>

pkcs15-init --delete-objects cert --id=45
</pre>
</li>
<li>
Then import the new certificate onto the token:
<pre>

pkcs15-init --store-certificate newclient.crt --id=45
</pre>
</li>
<li>
Reading a certificate from the token and output with openssl:
<pre>

pkcs15-tool --read-certificate 45 | openssl x509 -noout -text
</pre>
</li>
</ul>
<p><a name="some-notes-on-key-sizes"> </a><br />
<b>6.1.&#160;&#160;&#160;Some notes on key sizes</b><br />
Using 2048 bit keys should generally be possible with newer cards. I had some problems with these key sizes using my Java smartcard, though.<br />
After uploading the applet to the card, it is possible to create a key with either 1024 or 2048 bit. This indicates that the card <em>is</em> able to handle the large keysize. When trying to generate a CSR using openssl the command failed with:</p>
<pre>
[opensc-pkcs11] iso7816.c:99:iso7816_check_sw: No precise diagnosis
[opensc-pkcs11] muscle.c:745:msc_compute_crypt_process: returning with:
                Card command failed
[opensc-pkcs11] muscle.c:840:msc_compute_crypt: returning with:
                Card command failed
[opensc-pkcs11] card-muscle.c:749:muscle_compute_signature:
                Card signature failed: Card command failed
[opensc-pkcs11] sec.c:53:sc_compute_signature: returning with:
                Card command failed
[opensc-pkcs11] pkcs15-sec.c:273:sc_pkcs15_compute_signature:
                sc_compute_signature() failed: Card command failed
20808:error:0E06D06C:configuration file routines:NCONF_get_string:no value:
conf_lib.c:329:group=req_attributes name=unstructuredName_min
20808:error:0E06D06C:configuration file routines:NCONF_get_string:no value:
conf_lib.c:329:group=req_attributes name=unstructuredName_max
20808:error:8000A005:Vendor defined:PKCS11_rsa_sign:General Error:
p11_ops.c:97:
20808:error:0D0C3006:asn1 encoding routines:ASN1_item_sign:EVP lib:
a_sign.c:276:
</pre>
<p>Worse, after reinitializing the card in this state with:
<pre>

pkcs15-init -E --create-pkcs15 --no-so-pin
pkcs15-init --store-pin --auth-id 01 --label "User Name"
</pre>
<p>and trying to generate a smaller key, this fails with:
<pre>

pkcs15-init --generate-key rsa/1024 --auth-id 01 --split-key
</pre>
<pre>
[pkcs15-init] iso7816.c:102:iso7816_check_sw: Unknown SWs; SW1=9C, SW2=03
[pkcs15-init] muscle.c:557:msc_generate_keypair: returning with:
              Card command failed
[pkcs15-init] card.c:678:sc_card_ctl: returning with:
              Card command failed
[pkcs15-init] pkcs15-muscle.c:272:muscle_generate_key:
              Unable to generate key
[pkcs15-init] pkcs15-muscle.c:273:muscle_generate_key: returning with:
              Card command failed
Failed to generate key: Card command failed
</pre>
<p>I was able to fix this by re-downloading the applet onto the card. This also happens the other way round, when generating a 1024 bit key first and trying &#8212; after reinitializing the card with <code>pkcs15-init</code> &#8212; to generate a 2048 bit key.<br />
So I recommend to stick with 1024 bit keys with the current software versions (debian lenny).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/12/05/150/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PGAPy: Genetische Algorithmen mit Python</title>
		<link>http://blog.runtux.com/2009/10/25/138/</link>
		<comments>http://blog.runtux.com/2009/10/25/138/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 07:57:22 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[deutsch]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=138</guid>
		<description><![CDATA[[Dies ist der Abstract meines Vortrags am Linuxwochenende im Metalab, die alte Version des Abstracts ist inzwischen von der Linuxwochen Homepage verschwunden...]
PGAPy ist ein Python-Wrapper f&#252;r PGAPack, eine der vollst&#228;ndigsten Bibliotheken f&#252;r genetischen Algorithmen. Die Python-Bibliothek eignet sich f&#252;r eigene Experimente mit genetischen Algorithmen, aber auch f&#252;r die Implementierung von kompletten Anwendungen.
Der Vortrag gibt eine [...]]]></description>
			<content:encoded><![CDATA[<p>[Dies ist der Abstract meines Vortrags am Linuxwochenende im Metalab, die alte Version des Abstracts ist inzwischen von der Linuxwochen Homepage verschwunden...]</p>
<p><a href="http://pgapy.sourceforge.net/">PGAPy</a> ist ein Python-Wrapper f&#252;r <a href="ftp://info.mcs.anl.gov/pub/pgapack/README">PGAPack</a>, eine der vollst&#228;ndigsten Bibliotheken f&#252;r genetischen Algorithmen. Die Python-Bibliothek eignet sich f&#252;r eigene Experimente mit genetischen Algorithmen, aber auch f&#252;r die Implementierung von kompletten Anwendungen.</p>
<p>Der Vortrag gibt eine kurze Einf&#252;hrung in genetischen Algorithmen mit Beispielen in Python. Vorgestellt wird u.a. ein Programm zum automatischen Erzeugen der bekannten Sudoku Zahlenr&#228;tsel. Dabei wird schrittweise die Bewertungsfunktion f&#252;r ein Sudoku entwickelt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/10/25/138/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring Asterisk to log CDR records via ODBC to a remote MS-SQL</title>
		<link>http://blog.runtux.com/2009/08/18/112/</link>
		<comments>http://blog.runtux.com/2009/08/18/112/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 12:23:58 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[asterisk]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=112</guid>
		<description><![CDATA[In the following I&#8217;ll describe how to setup asterisk to log via ODBC to a remote Microsoft SQL server &#8212; I needed this for a client. I&#8217;m using a Debian server, file location may differ for your brand of linux distribution.
The following packages exist for debian, the ones needed are marked with &#8220;NEEDED&#8221;
A good introduction [...]]]></description>
			<content:encoded><![CDATA[<p>In the following I&#8217;ll describe how to setup asterisk to log via ODBC to a remote Microsoft SQL server &#8212; I needed this for a client. I&#8217;m using a Debian server, file location may differ for your brand of linux distribution.<br />
The following packages exist for debian, the ones needed are marked with &#8220;NEEDED&#8221;<br />
A good introduction to the Free TDS implementation of ODBC is the <a href="http://www.freetds.org/userguide/">userguide of FreeTDS</a></p>
<p><b>Debian FreeTDS packages</b></p>
<ul class="simple">
<li>freetds-common &#8211; configuration files for FreeTDS SQL client libraries: NEEDED</li>
<li>freetds-dev &#8211; MS SQL and Sybase client library (static libs and headers)</li>
<li>gda2-sybase &#8211; FreeTDS backend plugin for GNOME Data Access library for GNOME2</li>
<li>libct4 &#8211; libraries for connecting to MS SQL and Sybase SQL servers, needed only for sqsh for testing, gets automatically installed with sqsh.</li>
<li>libdbd-freetds &#8211; Freetds database server driver for libdbi</li>
<li>libsybdb5 &#8211; libraries for connecting to MS SQL and Sybase SQL servers</li>
<li>sqlrelay-freetds &#8211; SQL Relay FreeTDS (Sybase and MS SQL Server) connection daemon</li>
<li>sqsh &#8211; commandline SQL client for MS SQL and Sybase servers depends on libct4: Good for testing</li>
<li>tdsodbc &#8211; ODBC driver for connecting to MS SQL and Sybase SQL servers &#8220;This package includes the ODBC driver for FreeTDS, for use with UnixODBC or iODBC.&#8221;: NEEDED</li>
</ul>
<p>FreeTDS Needs either unixodbc or iodbc, both are ODBC implementations for Linux/Unix. Asterisk is built against unixodbc.<br />
iodbc packages:
<ul class="simple">
<li>iodbc &#8211; GTK+ config frontend for the iODBC Driver Manager</li>
<li>libiodbc2 &#8211; iODBC Driver Manager</li>
<li>libiodbc2-dev &#8211; iODBC Driver Manager (development files)</li>
</ul>
<p>unixodbc packages:
<ul class="simple">
<li>unixodbc &#8211; ODBC tools libraries depends on odbcinst1debian1: NEEDED</li>
<li>unixodbc-bin &#8211; Graphical tools for ODBC management and browsing</li>
<li>unixodbc-dev &#8211; ODBC libraries for UNIX (development files)</li>
</ul>
<p>common packages for debian:
<ul class="simple">
<li>odbcinst1debian1 &#8211; Support library and helper program for accessing odbc ini files: NEEDED</li>
</ul>
<p>Asterisk depends on unixodbc which should be already installed, so we install the following packages (ignoring any warnings about already-installed packages):
<pre>

apt-get install unixodbc sqsh tdsodbc
</pre>
<p><b>Other Software using ODBC</b></p>
<ul>
<li>
<p>Python seems to have its own access module for MS-SQL:<br />
python-pymssql &#8211; Python database access for MS SQL server and Sybase</li>
</ul>
<p><b>Configuraton for Asterisk Logging</b></p>
<ul>
<li>
/etc/freetds/freetds.conf
<pre>

[global]
        # TDS protocol version
;       tds version = 4.2

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug flags = 0xffff

        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 64512

[logserver]
        host = 172.23.23.4
        port = 1433
        tds version = 8.0
</pre>
</li>
<li>
/etc/odbcinst.ini
<pre>

[FreeTDS]
Description = FreeTDS ODBC driver for MSSQL
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
</pre>
</li>
<li>
/etc/odbc.ini
<pre>

[ODBC Data Sources]
logserver = MSSQL Log-Server for Asterisk

[logserver]
description = MSSQL Log-Server for Asterisk
driver      = /usr/lib/odbc/libtdsodbc.so
servername  = logserver
language = us_english
trace = no
tracefile = /root/mssql.trace
</pre>
</li>
<li>
/etc/asterisk/cdr_odbc.conf
<pre>

[global]
dsn=logserver
username=asterisk
password=VERYSECRET
loguniqueid=yes
dispositionstring=yes
table=cdr              ;"cdr" is default table name
usegmtime=no             ; set to "yes" to log in GMT
</pre>
</li>
<li>
Test using <code>isql</code></p>
<pre>
# isql logserver asterisk "VERYSECRET" -v
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL&gt; select * from cdr;
[output of current cdr table]
</pre>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/08/18/112/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Verletzung der Netzneutralität durch Inode/UPC</title>
		<link>http://blog.runtux.com/2009/06/15/103/</link>
		<comments>http://blog.runtux.com/2009/06/15/103/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 09:17:03 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[deutsch]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[skurril]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=103</guid>
		<description><![CDATA[Seit einiger Zeit bekommt man von Inode/UPC einen automatischen Nameserver (DNS) zugeteilt der bei offensichtlichen Tippfehlern (wenn ein Benutzer sich beim Namen einer Webseite verschreibt) eine Werbe- und Suchmaschine von UPC zurückliefert &#8212; statt dem Benutzer mitzuteilen, dass es diese Domain nicht gibt.
Diese Verhalten eines der wichtigsten Services im Internet &#8212; der Namensauflösung &#8212; verletzt [...]]]></description>
			<content:encoded><![CDATA[<p>Seit einiger Zeit bekommt man von Inode/UPC einen automatischen Nameserver (DNS) zugeteilt der bei offensichtlichen Tippfehlern (wenn ein Benutzer sich beim Namen einer Webseite verschreibt) eine Werbe- und Suchmaschine von UPC zurückliefert &#8212; statt dem Benutzer mitzuteilen, dass es diese Domain nicht gibt.</p>
<p>Diese Verhalten eines der wichtigsten Services im Internet &#8212; der Namensauflösung &#8212; verletzt klar die <a href="http://de.wikipedia.org/wiki/Netzneutralit%C3%A4t">Netzneutralität</a> wie auch schon im Jahr 2007 von Ed Felten in seinem <a href="http://www.freedom-to-tinker.com/blog/felten/verizon-violates-net-neutrality-dns-deviations">Blog im Falle Verizon</a> festgestellt wurde. Verizon hat wohl seither auf diese Praxis &#8212; nach vielen Protesten &#8212; wieder verzichtet. Berechtigterweise wurde UPC für diese Praxis für den <a href="http://bigbrotherawards.at/2008/Nominierungen#UPC_-_Aus_.C3.B6sterreichischen_Tippfehlern_werden_US-Werbeprofile">Big Brother Award</a> nominiert &#8212; die gesammelten Daten gehen offensichtlich an einen ausländischen Werbeunternehmer. Zumindest in einem Fall kommt es bei diesem Verhalten zu Probleme bei Telefonie im Internet wie einem <a href="http://www.ip-phone-forum.de/showthread.php?t=191607">Forum Posting</a> zu entnehmen ist.</p>
<p>Schlimmer noch: UPC liefert falschen Information auch für Domains die ganz klar von jemand anderem reserviert sind. Wenn ich also nonexistent.source-forge.org ansurfe komme ich auch auf die Werbeseite von UPC &#8212; obwohl source-forge.org (ja mit Bindestrich) von dem grossen Open Source Projekthoster sourceforge reserviert ist. Hoffentlich lässt es da mal jemand auf ein Gerichtsverfahren wegen unlauterem Wettbewerb ankommen. Wäre vermutlich recht lukrativ, jedenfalls bei anderen Firmen als Sourceforge.</p>
<p>Mir war das bisher nicht aufgefallen, aber offensichtlich wurden ehemalige Inode-Kunden erst vor kurzem umgestellt, UPC-Telekabel Kunden offensichtlich schon früher.</p>
<p>Heute habe ich mich bei der UPC-Hotline beschwert. Man werde an dem Fall arbeiten und &#8220;den Fehler&#8221; beheben. Leider könne man mir keine Ticket-Nummer geben unter welcher ich meine Beschwerde nochmal urgieren kann &#8212; aber ich könne ja &#8220;in einigen Tagen&#8221; wieder anrufen. Ein Rückruf wurde mir versprochen, mal sehen ob da was kommt. Ich habe den Hotline-Bearbeiter freundlich darauf hingewiesen, dass es sich ja nicht um einen unbekannten Fehler handeln kann, wenn UPC dafür bereits für den Big Brother Award nominiert wurde.</p>
<p>Inzwischen habe ich einen Workaround gefunden: UPC hat die alten, funktionierenden Nameserver nicht abgeschaltet, in obigem Link des ip-phone-forums findet man funktionierende DNS-Server: 195.34.133.25 und 195.34.133.26 die man fix einstellen kann. Weitere Tips finden sich als Antwort auf mein <a href="http://www.luga.at/mailing-lists/luga/2009/06/msg00026.html">Posting an die LUGA-Mailingliste</a>. Die alternative ist, gleich einen eigenen Nameserver zu betreiben (unter Linux sehr einfach möglich) oder auf alternative Namenshierarchien umzusatteln wie z.B. <a href="http://www.opennicproject.org/">opennicproject</a> &#8212; auch wenn man bei Verwendung von Alternativen von einer <a href="http://www.golem.de/0904/66730.html">deutschen Ministerin gleich als pädophil</a> eingestuft wird. Es ist kaum zu glauben, was manche Politiker für einen Schwachsinn von sich geben.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/06/15/103/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>grml to the rescue</title>
		<link>http://blog.runtux.com/2009/06/05/101/</link>
		<comments>http://blog.runtux.com/2009/06/05/101/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 12:18:19 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[documentation]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=101</guid>
		<description><![CDATA[I recently needed to recover data from a &#8220;dead&#8221; notebook. The only hardware I had available that had a connector for an ATA notebook harddisk was my Soekris net4801. This device doesn&#8217;t have VGA on board, so we need to boot GRML with a serial console. First I was unable to get GRML to correctly [...]]]></description>
			<content:encoded><![CDATA[<p>I recently needed to recover data from a &#8220;dead&#8221; notebook. The only hardware I had available that had a connector for an ATA notebook harddisk was my <a href="http://soekris.com/net4801.htm">Soekris net4801</a>. This device doesn&#8217;t have VGA on board, so we need to boot <a href="http://grml.org/">GRML</a> with a serial console. First I was unable to get GRML to correctly start a getty process. Meanwhile I&#8217;ve found out that the recipe in <a href="http://bts.grml.org/grml/issue485">issue485</a> of the GRML-Bugtracker does the trick (I&#8217;ve modified the console speed to the speed I&#8217;m using in the Soekris bootloader):</p>
<p><code>grml console=tty 1console=ttyS1,38400n8</code></p>
<p>I had tried <code>console=ttyS1,38400n8</code> before which doesn&#8217;t work. So I added the ssh= boot-options found out via the <a href="http://wiki.grml.org/doku.php?id=cheatcodes">grml cheatsheet</a>. I could ping the machine but no SSH. Turns out it takes a loooong time until grml starts up the ssh-daemon for two reasons</p>
<ul>
<li>The net4801 is really slow</li>
<li>GRML creates new SSH Host-keys before starting up SSH. Thats good. But a newly-started box without a Keyboard has a really small random-number pool, so the box sits there waiting for randomness to happen for generating the keys. So it helps to run several parallel pings to the machine to create some network traffic the timing of which slowly fills the randomness pool &#8230;</li>
</ul>
<p>Turns out that process took several minutes on the Soekris net4801. After waiting I was finally able to log into grml and rescue the data using ddrescue. Thanks GRML!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/06/05/101/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Howto get Asterisk with mISDN V2 and Linux Call Router running on debian lenny</title>
		<link>http://blog.runtux.com/2009/03/09/61/</link>
		<comments>http://blog.runtux.com/2009/03/09/61/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 15:13:29 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[asterisk]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=61</guid>
		<description><![CDATA[Update 2009-03-31: provide signed archive with archive key, add udev rules, add /etc/modules entries, add amd64.
Update 2009-04-05: typos fixed
This is a short howto how I built the debian patches and how you can &#8212; as a user &#8212; install everything needed for mISDN version 2 and Linux Call Router (LCR) with asterisk chan_lcr running on [...]]]></description>
			<content:encoded><![CDATA[<p>Update 2009-03-31: provide signed archive with archive key, add udev rules, add <code>/etc/modules</code> entries, add amd64.<br />
Update 2009-04-05: typos fixed</p>
<p>This is a short howto how I built the debian patches and how you can &#8212; as a user &#8212; install everything needed for mISDN version 2 and Linux Call Router (LCR) with asterisk chan_lcr running on debian lenny.</p>
<p>I&#8217;m providing debian packages for Kernel (v 2.6.28.5), an updated zaptel (debian lenny zaptel doesn&#8217;t compile with newer kernels and zaptel wctdm uses some settings for analogue phones that don&#8217;t work with german and austrian phone like the &#8220;R&#8221;-key or optional pulse dialling), finally I&#8217;m providing a slightly patched asterisk for larger buffer sizes when playing long tones, LCR and misdnv2user packages originally built by Joerg Dorchain. My misdnv2user is the same as Joergs. The lcr package contains my bug-fix for DTMF digits A-F (also in Joergs packages now) which don&#8217;t work in upstream LCR version 1.3 and an updated <code>/etc/init.d/lcr</code> for querying the status of lcr.</p>
<p>I&#8217;m also providing source packages, except for the kernel &#8212; the kernel is stock kernel.org 2.6.28.5 configured for use of mISDN. The kernel was built using debians make-kpkg from the <code>kernel-package</code> debian package. And the config used for building the kernel is in the binary package.</p>
<p>I hope I can contribute something in order to get mISDN V2 and LCR into debian&#8230; in the meantime others may want to uses these on debian stable.</p>
<p><b>Installation</b></p>
<pre>
apt-get install vim less ssh ntp
apt-get install python-dev openbsd-inetd postfix madplay
</pre>
<p>Add following lines to /etc/apt/sources.list:</p>
<pre>
deb http://project.runtux.com/asterisk/debian/ lenny main
deb-src http://project.runtux.com/asterisk/debian/ lenny main
</pre>
<p>If you want to avoid warnings about an untrusted archive key from <code>apt</code>, you should import the following archive key. Save the key to a file and then issue the command<br />
<code>apt-key add file</code></p>
<pre>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.9 (GNU/Linux)

mQENBEnREAIBCADM8+KpoC/HJUCEsx8KZhGgsX/G3ouR4/xkgIuIPgz+t6JoTisj
9QmymDZKUXSy04WmbLjU/088xD5A9ukOEYxoFCGqwWf1tPOKqN1oKpVCkjJb8Dht
vvebqOCzJSV0nfqmIfkpbX+6dUssx+9u0BiFK3aj/GilkEloZl2g+vIT6fveJtKE
qmxz19vL516TDhsbsv3/AKfNKc7QRpsgvPmnNE2IL0CTgQYs26WtnJASlu1MQpwo
Qfb1PrO7ufq9eO58HjEBdfbSNjalQjVj7vLvE4GQglHULO500H9UlfOm2zpO0Vzs
5lGGbwLJdTpAS3HIRhQAW0pueRsQ8zagMn5lABEBAAG0OFJhbGYgU2NobGF0dGVy
YmVjayAoRGViaWFuLVBhY2thZ2UtS2V5KSA8cnNjQHJ1bnR1eC5jb20+iQE2BBMB
AgAgBQJJ0RACAhsDBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ5CizCR9G97ah
pAf/eLRYtPVs1apI3+AVi//8y1/r6uL+IxI/Tlt53jCtX/dy3Q3FeAEJt/7fbvcW
TBDnP5K8vWaYUlHHaz+6lbcQyV/KAH4LKJEKkyoINc9ytG1qEG6z8NPfDmKiEluy
HksgLpAqUBrdZy46iWQhcg7f3fpcUIsHHcXrOd2Ip5G9DL2q4/UoRrhBhHC3GNX7
ERaeAKZTF1JRaVN6KSWPC2+yaNmuGn1yoSChG0Q/bBTgzv2fm9Jzvok546f9LE0q
k2q5PvjlUSMGHHojTzzR6tGhnbw5mOfyMUDDs5LuAN1aWbDatepJgiC+dYasprQ5
pZygpoCASqIhWjjCZd3XI5mAEIhGBBARAgAGBQJJ0nZlAAoJEIO0FkDz/lcw0xYA
njBSGef/4KhZpuspIh6WnLM7ORKNAKCw28et9bUoaGu4ESRpIwtwj4asQoicBBAB
AgAGBQJJ0ncuAAoJEJWCQpSoBzk1hpcD/2KXiuvE2Nm0oOi0jBVEjT/Tu/GGkG5m
lf97/I6TMcJxlMpeBlv9SiJD+/BBQo0MGMxmkCwU4t+eBCBsCVcr/bJnrlrKa4Ab
9SR9WQ8PGrSQ+AwMePCDKngqFd5EERz8bxz4sZKGCxn9JVRQOGp03eKSGDG/Yh0v
FY3v7nV0BUaE
=mPtt
-----END PGP PUBLIC KEY BLOCK-----
</pre>
<p>Then install:</p>
<pre>
apt-get update
apt-get install linux-headers-2.6.28.5-i686 linux-image-2.6.28.5-i686 \
    asterisk zaptel lcr zaptel-modules-2.6.28.5-i686
</pre>
<p>If you&#8217;re on the amd64 architecture, you should replace i686 in the packages above with amd64.</p>
<p>and optionally (for <code>misdn_info</code>):</p>
<pre>
apt-get install misdnv2user
</pre>
<p>Edit <tt><span class="pre">/etc/default/asterisk</span></tt> and set <tt><span class="pre">RUNASTERISK=yes</span></tt>. Then make several directories (should be done by a future version of the lcr package):</p>
<pre>
mkdir /var/run/lcr
chown asterisk.asterisk /var/run/lcr
mkdir /var/log/lcr
chown asterisk.asterisk /var/log/lcr
</pre>
<p>I&#8217;ve also made a start-script for lcr (for use as <tt><span class="pre">/etc/init.d/lcr</span></tt>) ,<br />
downloadable at <a class="reference external" href="http://project.runtux.com/asterisk/init.d:lcr">http://project.runtux.com/asterisk/init.d:lcr</a><br />
this probably should also be part of the lcr package.</p>
<p>Config file examples used for lcr &#8212; these pass<br />
everything to asterisk. File <tt><span class="pre">/etc/lcr/interface.conf</span></tt>:</p>
<pre>
[Ext1]
portnum 0
ptp
nodtmf

[Ext2]
portnum 1
ptp
nodtmf

[Int1]
portnum 2
nt
ptp
nodtmf

[Int2]
portnum 3
nt
ptp
nodtmf
</pre>
<p>I&#8217;m using a Beronet 4 port ISDN card, your config will probably differ: This system only expects <em>incoming</em> calls and needs to check on which line a call comes in. So I distinguish all external interfaces as separate interfaces of LCR. I also need to check an interface by calling out via that interface, you probably would want to make all external ports a trunk by grouping them into one LCR interface.</p>
<p>And the routing config needs to match your interface definition. This config will pass all calls &#8212; if asterisk is running &#8212; to asterisk. If asterisk isn&#8217;t running, I&#8217;m calling a test application (untested). The context in asterisk will be the interface name. Again, if you&#8217;re using a trunk here, be sure to match the routing config with your interface config. <tt><span class="pre">/etc/lcr/routing.conf</span></tt>:</p>
<pre>
[main]
remote=asterisk interface=Ext1 : remote application=asterisk
remote=asterisk interface=Ext2 : remote application=asterisk
remote=asterisk interface=Int1 : remote application=asterisk
remote=asterisk interface=Int2 : remote application=asterisk
default                        : efi
</pre>
<p>Update <code>/etc/modules</code> to include the following lines (the command appends the lines between <code>cat</code> and <code>EOF</code>):</p>
<pre>
cat &gt;&gt; /etc/modules &lt;&lt; EOF
mISDN_core debug=0x0
mISDN_dsp debug=0x0 options=0x0
hfcmulti debug=0x0
EOF
</pre>
<p>Linux udev must be configured to correctly set the user for the isdn device(s):</p>
<pre>
cat &gt; /etc/udev/rules.d/91-isdn.rules &lt;&lt; EOF
ACTION!="add|change", GOTO="permissions_end"

KERNEL=="mISDN*",       GROUP="dialout"

LABEL="permissions_end"
EOF
</pre>
<p>After a reboot asterisk and lcr should be running.</p>
<p><b>Building</b></p>
<p>Getting kernel:</p>
<pre>
wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2
wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2.sign
wget http://kernel.org/pub/linux/kernel/v2.6/patch-2.6.28.5.gz
wget http://kernel.org/pub/linux/kernel/v2.6/patch-2.6.28.5.gz.sign
</pre>
<p>For compilation (zlib isn&#8217;t checked by make-kpkg!):</p>
<pre>
apt-get install kernel-package bzip2 libncurses5-dev zaptel-source \
    zlib1g-dev fakeroot
</pre>
<p>Compile Kernel:</p>
<pre>
tar xvf linux-2.6.28.tar.bz2
cd linux-2.6.28
zcat ../patch-2.6.28.5.gz | patch -N -p1 | less 2&gt;&amp;1
cp /boot/config-2.6.28.5-i686 .config
make oldconfig
make menuconfig # just to be sure
</pre>
<p>For amd64:</p>
<pre>
make-kpkg --append-to-version -amd64 --revision 2.6.28.5.1.rsc --us \
    --uc --initrd --rootcmd fakeroot binary &gt; m.out 2&gt; m.err
</pre>
<p>For i686:</p>
<pre>
make-kpkg --append-to-version -i686 --revision 2.6.28.5.1.rsc --us \
    --uc --initrd --rootcmd fakeroot binary &gt; m.out 2&gt; m.err
</pre>
<p>The following doesn&#8217;t seem to work although zaptel is installed:<br />
probably need to unpack <tt><span class="pre">/usr/src/zaptel.tar.bz2</span></tt> into<br />
<tt><span class="pre">/usr/src/modules/zaptel</span></tt> (tar file contains modules directory!)<br />
this would save us from the <tt><span class="pre">m-a</span> <span class="pre">a-i</span></tt> step below. amd64:</p>
<pre>
make-kpkg --append-to-version -amd64 --revision 2.6.28.5.1.rsc --us \
    --uc --initrd --rootcmd fakeroot modules &gt; mo.out 2&gt; mo.err
cd ..
</pre>
<p>For i686:</p>
<pre>
make-kpkg --append-to-version -i686 --revision 2.6.28.5.1.rsc --us \
    --uc --initrd --rootcmd fakeroot modules &gt; mo.out 2&gt; mo.err
cd ..
</pre>
<p>Make a debianized zaptel for new kernel:</p>
<pre>
apt-get install devscripts libnewt-dev quilt libusb-dev asciidoc
svn checkout http://svn.digium.com/svn/zaptel/branches/1.4 zaptel
apt-get source zaptel-source
cp zaptel/kernel/ztdummy.* zaptel-1.4.11~dfsg/kernel
cd zaptel-1.4.11~dfsg
# Add &quot;Fix compilation for newer kernels&quot;
dch -i
dpkg-buildpackage
cd ..
dpkg -i zaptel-source_1.4.11~dfsg-3.1_all.deb
m-a a-i zaptel
</pre>
<p>The following installs my patched asterisk, I&#8217;m modifying some buffer sizes because I want to play long tones (I&#8217;m generating a faked modem guard-tone that is needed in a project). You probably won&#8217;t need the patches asterisk, but it won&#8217;t hurt to install it. The <tt><span class="pre">create-patches</span></tt> script is available from<br />
<a class="reference external" href="http://project.runtux.com/asterisk/create-patches">http://project.runtux.com/asterisk/create-patches</a></p>
<pre>
apt-get install libreadline5-dev libgsm1-dev libssl-dev libtonezone-dev \
    libvpb-dev autotools-dev libsqlite-dev libspeex-dev libspeexdsp-dev \
    graphviz libcurl4-openssl-dev doxygen libpopt-dev libopenh323-dev   \
    libiksemel-dev libradiusclient-ng-dev freetds-dev libvorbis-dev     \
    libsnmp-dev libc-client2007b-dev libcap2-dev libpq-dev unixodbc-dev \
    libpri-dev
apt-get source asterisk
scp ralf&#64;bee:checkout/own/config/asterisk/create-patches .
cd asterisk-1.4.21.2~dfsg/
sh ../create-patches
# Hunk #1 succeeded at 25 (offset 3 lines).
# Add &quot;runtux.com local buffer-size patches&quot;
# and new version-number 1:1.4.21.2.1~dfsg-3
dch -i # add comment
dpkg-buildpackage -rfakeroot
cd ..
</pre>
<p>For mISDNuser and chan_lcr I&#8217;m using <a class="reference external" href="http://listserv.isdn4linux.de/pipermail/isdn4linux/2009-February/003846.html">Joerg Dorchains packages</a> with my added patches for DTMF codes A-F.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/03/09/61/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>sane snapscan and epson 3590 photo + rpm weirdness</title>
		<link>http://blog.runtux.com/2009/03/06/57/</link>
		<comments>http://blog.runtux.com/2009/03/06/57/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 19:21:14 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[skurril]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=57</guid>
		<description><![CDATA[I&#8217;ve recently upgraded to debian lenny. Unfortunately after this upgrade my epson 3590 scanner stopped working. After some googling around I managed to find an rpm package with the binary firmware image. But the package converter alien would not let me convert the file, the message was 
 Unpacking of 'iscan-firmware-2.8.0.1-48.1.noarch.rpm' failed at /usr/share/perl5/Alien/Package/Rpm.pm line [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently upgraded to debian lenny. Unfortunately after this upgrade my epson 3590 scanner stopped working. After some googling around I managed to find an <a href="http://rpm.pbone.net/index.php3/stat/4/idpl/7960575/com/iscan-firmware-2.8.0.1-48.1.noarch.rpm.html">rpm package</a> with the binary firmware image. But the package converter <a href="http://packages.debian.org/lenny/alien">alien</a> would not let me convert the file, the message was </p>
<p><code> Unpacking of 'iscan-firmware-2.8.0.1-48.1.noarch.rpm' failed at /usr/share/perl5/Alien/Package/Rpm.pm line 155.</code></p>
<p>After some more searching I found debian bugs <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=518348">518348</a> and <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=509444">509444</a> of which the latter contains a workaround: Seems that the rpm format changed to a compressed format that can be unpacked with <a href="http://http://packages.debian.org/lenny/lzma">lzma</a>. Now unpacking was possible &#8212; after all I was only interested in the firmware file &#8212; and now my scanner is working again&#8230; For the record, unpacking was done as follows: </p>
<p><code>mkdir iscan-firmware-2.8.0.1<br />
rpm2cpio iscan-firmware-2.8.0.1-48.1.noarch.rpm \<br />
  | lzma -d | (cd iscan-firmware-2.8.0.1; \<br />
  cpio --extract --make-directories \<br />
  --no-absolute-filenames --preserve-modification-time)</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/03/06/57/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dämmerungsgesteuerte Hühnerstalltür mit Arduino</title>
		<link>http://blog.runtux.com/2009/01/08/9/</link>
		<comments>http://blog.runtux.com/2009/01/08/9/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 19:40:59 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[deutsch]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[open hardware]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/?p=9</guid>
		<description><![CDATA[Seit einiger Zeit haben wir Hühner. Da wir öfter mal am Abend alle weg sind und dann niemand die Tür vom Hühnerstall zumacht &#8212; die Hühner gehen, im Gegensatz zu den Enten die wir früher hatten, von selber bei Dämmerung in den Stall &#8212; brauchten wir eine Lösung, die automatisch die Tür schließt. Es gibt [...]]]></description>
			<content:encoded><![CDATA[<p>Seit einiger Zeit haben wir Hühner. Da wir öfter mal am Abend alle weg sind und dann niemand die Tür vom Hühnerstall zumacht &#8212; die Hühner gehen, im Gegensatz zu den Enten die wir früher hatten, von selber bei Dämmerung in den Stall &#8212; brauchten wir eine Lösung, die automatisch die Tür schließt. Es gibt fertige Hühnerställe mit einer zeitgesteuerten Tür &#8212; aber weder mit Dämmerungsschalter noch eine Türelektronik einzeln.<br />
<div id="attachment_50" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.runtux.com/files/2009/01/dsc00158.jpg"><img src="http://blog.runtux.com/files/2009/01/dsc00158-300x225.jpg" alt="-)" width="300" height="225" class="size-medium wp-image-50" /></a><p class="wp-caption-text">v.l.n.r Kokoschka, Leuchtfeder, Gertrude <img src='http://blog.runtux.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p></div><br />
Mein Sohn Max und ich haben also gemeinsam die Tür mit Mechanik und Elektronik und Software selber gemacht.</p>
<p>Alle verwendeten Teile sind bei Conrad erhältlich, wo wir es noch rekonstruieren können geben wir die Bestellnummern und den Link zum Artikel an. Conrad ist zwar relativ teuer, dafür bekommt man für dieses Einmalprojekt alle Teile bei einem Händler und wer was nachbauen will kann im deutschsprachigen Raum über einheitliche Teilenummern auf die gleichen Teile zugreifen, sei es in Österreich, der Schweiz oder Deutschland.</p>
<p>Einige Teile unserer Lösung eignen sich sicher auch für andere Projekte, nicht viele Leute werden eine Hühnerstalltüre brauchen &#8230;</p>
<p>Die Hühnerstalltüre funktioniert jetzt schon ein paar Wochen. Anfängliche mechanische Probleme (Tür verklemmte sich einige Male beim Herunterfahren) sind wohl gelöst. Unsere Software hat einen Zeitcheck falls beim Runter- oder Rauffahren doch mal was schiefgeht.</p>
<p>In der Folge beschreiben wir den Aufbau, getrennt nach Mechanik, Elektronik und Software &#8212; die Aufteilung zwischen Mechanik und Elektronik ist etwas willkürlich, wir haben die ganze Elektromechanik<br />
(Motor, Schalter) zur Mechanik gerechnet.</p>
<p><strong>Die Mechanik</strong></p>
<p>Mit einem Getriebemotor wird eine Welle über einen Zahnriemen-Antrieb (Übersetzung nochmal 4:1) angetrieben. Der Getriebemotor ist schon 148:1 untersetzt. Die Welle läuft auf Kugellagern, die in einem Holzrahmen montiert sind. Die Lagerflansche sind einfach mit Heisskleber in den ausgestemmten Teil der Holzlatten geklebt. Vorsicht, keinen Heisskleber ins Lager bringen&#8230;</p>
<p>Die Übersetzung wurde so gewählt, dass wir eine bis zu 800g schwere Tür mit einer Welle mit Radius 5mm gut hochziehen können. Das Drehmoment des verwendeten Motors ist etwa 1,2 Ncm, mit der 4:1 Übersetzung mit dem Zahnriemen kommen wir auf 4.8 Ncm.</p>
<p>Die Welle wickelt dann eine Nylonschnur auf, die an der Tür angebunden ist. Die Nylonschnur hat einen Durchmesser von 2mm, die Welle wurde mit einem 2mm Titanbohrer gebohrt. Zum Bohren der Welle haben wir einen Stellring verwendet, einfach durch das Schraubenloch des Stellringes gebohrt, der Stellring war mit Klebeband fixiert.</p>
<p>Das Einfädeln der Nylonschnur kann man sich erleichtern, indem man die Nylonschnur mit einem Feuerzeug an einer Stelle erhitzt und auseinanderzieht, die entstehende Spitze eignet sich recht gut zum Einfädeln.</p>
<p>Motor: Eigentlich wollten wir ursprünglich einen kleineren Motor, da der jetzt verwendete Motor bis zu 2A Strom zieht (bei hoher Last &#8212; unsere Tür ist relativ leicht, dadurch ist die Last und damit der Strom recht niedrig). Das könnte mal zuviel für den verwendeten H-Bridge Motorcontroller werden.</p>
<p>Die Tür selbst hat einen Magneten, der in zwei Stellungen (Tür ganz oben bzw. ganz unten) jeweils einen Magnetschalter auslöst.</p>
<p>Für das Justieren (von Hand Türe rauf- bzw. runterfaheren) gibt es zwei Taster die an digitalen Inputs des Arduino angeschlossen sind.</p>
<div id="attachment_47" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.runtux.com/files/2009/01/dsc00031.jpg"><img src="http://blog.runtux.com/files/2009/01/dsc00031-300x225.jpg" alt="Mechanischer Aufbau" width="300" height="225" class="size-medium wp-image-47" /></a><p class="wp-caption-text">Mechanischer Aufbau</p></div>
<p>Teileliste Mechanik:</p>
<ul>
<li><a href="http://www.conrad.at/goto.php?artikel=222366">222366</a> Getriebemotor</li>
<li><a href="http://www.conrad.at/goto.php?artikel=222374">222374</a> Alternativ: kleinerer Motor</li>
<li><a href="http://www.conrad.at/goto.php?artikel=237205">237205</a> Welle 8mm</li>
<li><a href="http://www.conrad.at/goto.php?artikel=216011">216011</a> Lagerflansch für Kugellager</li>
<li><a href="http://www.conrad.at/goto.php?artikel=225550">225550</a> Stellringe 8mm</li>
<li><a href="http://www.conrad.at/goto.php?artikel=214493">214493</a> Kugellager</li>
<li><a href="http://www.conrad.at/goto.php?artikel=226043">226043</a> Zahnriemenscheibe 40 Zähne, für Welle 8mm</li>
<li><a href="http://www.conrad.at/goto.php?artikel=226106">226106</a> Zahnriemenscheibe 10 Zähne, für Welle 6mm (an Motor)</li>
<li><a href="http://www.conrad.at/goto.php?artikel=226084">226084</a> Zahnriemen</li>
<li><a href="http://www.conrad.at/goto.php?artikel=753360">753360</a> Magnetschalter</li>
<li>Taster ein (2X)</li>
</ul>
<p>Im folgenden Bild sieht man die Tür im Zustand &#8220;NACHT&#8221; (zu). Die Magnetschalter und der Magnet an der Tür sind gut zu erkennen. Oben im Bild ist ein Stück Sperrholz auf Abstandshaltern so montiert, dass die Schnur durchläuft und beim Hochfahren die Tür an die Hüttenwand gedrückt wird.</p>
<div id="attachment_53" class="wp-caption aligncenter" style="width: 235px"><a href="http://blog.runtux.com/files/2009/01/dsc00159-rot.jpg"><img src="http://blog.runtux.com/files/2009/01/dsc00159-rot-225x300.jpg" alt="Hühnerstalltür im geschlossenen Zustand mit Magnet und Magnetschaltern" width="225" height="300" class="size-medium wp-image-53" /></a><p class="wp-caption-text">Hühnerstalltür im geschlossenen Zustand mit Magnet und Magnetschaltern</p></div>
<p><strong>Die Elektronik</strong></p>
<p>Der Dämmerungsschalter ist mit einem einfachen Photowiderstand in einem Spannungsteiler mit einem 10k Widerstand realisiert. Der Photowiderstand ist über ein Lautsprecherkabel mit Heisskleber im Holzdach montiert. Oberhalb des Photowiderstands ist ein Acryl-Welldach. Die Magnetschalter sind an digitale Eingangspins des Arduino angeschlossen.</p>
<p>Die Motorsteuerung erfolgt über eine H-Bridge Schaltung in einem IC. Die Elektronik dazu findet auf einer Lochraster-Platine Platz. Die einfache H-Bridge benötigt keine externen Teile. Wie man das mit dem Arduino verdrahtet ist ganz gut auf der Seite der <a href="http://itp.nyu.edu/physcomp/Labs/DCMotorControl">Physical Computing Labs</a> der Tisch School of the Arts beschrieben &#8212; ist auch der erste Link auf den ich beim googlen nach &#8220;Arduino Motor Control&#8221; gestoßen bin.</p>
<p>Wir wollen aber &#8212; wegen des größeren Motors &#8212; auf eine größere H-Bridge, die braucht externe Schaltdioden (das <a href="http://www2.produktinfo.conrad.com/datenblaetter/150000-174999/156128-da-01-en-DUAL_BRIDGE_DRIV_L298N.pdf">Datenblatt</a> des L298N schlägt Dioden mit höchstens 200ns reverse recovery time (t<sub>rr</sub>) vor, wir werden die <a href="http://www2.produktinfo.conrad.com/datenblaetter/150000-174999/160005-da-01-en-BYV2100.pdf">BYV 2100</a> verwenden mit einer t<sub>rr</sub> von 12.5ns)</p>
<p>Teileliste Elektronik:</p>
<ul>
<li><a href="http://arduino.cc/en/Main/ArduinoBoardDuemilanove">Arduino Duemilanove</a></li>
<li><a href="http://www.conrad.at/goto.php?artikel=145475">145475</a> Photowiderstand</li>
<li>Widerstand 10k</li>
<li><a href="http://www.conrad.at/goto.php?artikel=174003">174003</a> L293D H-Bridge max 1A</li>
<li><a href="http://www.conrad.at/goto.php?artikel=510821">510821</a> Netzteil 9V passend für Arduino</li>
</ul>
<p>Alternative größere H-Bridge:</p>
<ul>
<li><a href="http://www.conrad.at/goto.php?artikel=156128">156128</a> L298N H-Bridge Dual 2A bzw parallelgeschaltet 3A</li>
<li><a href="http://www.conrad.at/goto.php?artikel=160005">160005</a> BYV 2100 Schnelle Dioden dazu</li>
</ul>
<p><strong>Die Software</strong></p>
<p>Der Dämmerungsschalter sollte laut Wikipedia <a href="http://en.wikipedia.org/wiki/Lux">bei ca. 100 lux</a> das Öffnen der Tür veranlassen und bei höchstens 3.4 lx (Dark limit of civil twilight under a clear sky) das Schließen. In dem Wikipedia-Artikel ist eine Tabelle, die einen sehr dunklen Tag mit 100lx angibt, die deutsche Version enthält leider keine ausführliche Tabelle. In unseren Experimenten war ein Meßwert des Arduino von 200 für &#8220;Jetzt ist es dunkel, Tür zu&#8221; und von 300 für &#8220;Jetzt ist es hell, Tür auf&#8221; gut &#8212; auch in den jetzt dunklen Wintertagen (auch bei einem Gewitter) bleibt die Tür tagsüber offen und schliesst zuverlässig bei Dunkelheit. In einer klaren Vollmondnacht blieb die Tür zu.</p>
<p>Die Steuerung ist als Zustandsautomat (State Machine) realisiert. Jenachdem welcher Magnetschalter beim Einschalten Kontakt hat, startet der Automat im Zustand &#8220;TAG&#8221; bzw. &#8220;NACHT&#8221;. Wird keiner der Magnetschalter gesehen, gehen wir in den Zustand &#8220;ERROR&#8221;. Dieser Zustand bildet auch alle anderen Fehlerzustände ab, die im Betrieb auftreten können. Dabei setzen wir eine Fehlermeldung, die dann über die serielle Schnittstelle des Arduino (USB Serial) ausgegeben wird.</p>
<p>Der Zustandsautomat verwendet Statusfunktionen: In einem bestimmten Zustand wird die zugehörige Zustandsfunktion ausgeführt. Wenn diese Funktion 0 zurückliefert, geht der Automat in den nächsten Zustand, sonst bleibt er im alten Zustand.</p>
<p>Durch die Verwendung von Statusfunktionen (und keiner speziellen Funktion beim Zustandsübergang) haben wir zwei zusätzliche Zustände um den Motor einzuschalten, dieser Zustand (START_RAUF bzw. START_RUNTER) schaltet den Motor ein und geht sofort in den nächsten Zustand über.</p>
<p>Die Verdrahtung mit dem Arduino, also an welchen Pins welche Peripherie angeschlossen ist, sind über define&#8217;s am Beginn des Programms festgelegt.</p>
<p>Die Logik für die digitalen Inputs verwendet die Arduino-internen Pull-Up Widerstände. Daher ist die Logik invertiert: Wenn der Taster (oder ein Magnetschalter) geschlossen ist, liefert der entsprechende digitale Input eine 0.</p>
<p>Beim Testen haben wir festgestellt, dass bei laufendem Motor gelegentlich eine gedrückte Taste &#8212; oder ein geschlossener Magnetschalter detektiert wird. Daher haben wir in Software alle digitalen Inputs entprellt (Funktion debounced_read). Vermutlich sollten wir vor der H-Bridge noch einen Entstörkondensator vorsehen.</p>
<p>Die beiden Taster zum manuellen Rauf- und Runterfahren setzen ein Flag das den Zustandsautomaten neu initialisiert &#8212; dadurch muss man nach dem manuellen Kalibrieren kein Reset ausführen: Einfaches Drücken der Rauf- bzw. Runter-Taste reicht, um ein neues Initialisieren durchzuführen.</p>
<p>Im Error-Status warten wir 100ms nach dem Ausgeben der Fehlermeldung. Durch dieses Delay merkt man bei Drücken des Rauf- bzw. Runter-Knopfes sofort, ob sich das Gerät im Error-Zustand befindet: Wenn ein Error-Zustand vorliegt, bewegt sich der Motor nicht sofort, sondern erst nach einem kurzen Delay. Wenn der Zustandsautomat korrekt initialisiert ist, bewegt sich der Motor sofort.</p>
<p>Während der Entwicklung habe ich mit etwas mit einem Bug der Arduino-Entwicklungsumgebung gekämpft: Um Function-Style casts (Typumwandlungen die wie eine Funktion aussehen) zu ermöglichen, macht die Entwicklungsumgebung Code-Rewriting und fügt insbesondere einige Preprozessor-Defines ein, die es verhindern, einen Funktionspointer in C zu deklarieren. Der Workaround ist ein &#8220;#undef int&#8221; vor der Funktionspointer-Deklaration einzufügen. Gleich am Anfang kann man das nicht machen, da das Code-Rewriting ein #include direkt vor dem ersten Statement (nach allen #include und #define Direktiven) einfügt. Dieses &#8220;Feature&#8221; hat durch obskure Fehlermeldungen einiges an Zeit gekostet, was mich veranlasst hat, einen <a href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1221741304/48#48">Beitrag im Arduino Forum</a> dazu zu schreiben.</p>
<p>Die verwendeten Timer-Routinen (#include &lt;timer.h&gt; und der Typ Arduino_Timer) dienen dazu, auf eine bestimmte Zeit nach dem Aufruf von millis() zu warten &#8212; auch wenn die von millis verwendete Variable inzwischen überläuft. Der Timer lässt sich fragen, ob der gewünschte Zeitpunkt schon erreicht ist. Ursprünglich habe ich diese Routinen geschrieben,  weil Version 0011 (und früher) der Arduino Entwicklungsumgebung einen Bug hatte, so dass der Timer zu früh überlief. Die entsprechenden Timer Routinen (für Version 0011 oder ab 0012) gebe ich gern auf Anfrage weiter.</p>
<pre>
#include &lt;timer.h&gt;
#include &lt;stdio.h&gt;

# define LED          13
# define MAGNET_OBEN   7
# define MAGNET_UNTEN  8
# define FOTO          0
# define MOTOR         9
# define MOTOR_DIR1    4
# define MOTOR_DIR2    3
# define MOTOR_MIN  0x7F
# define KNOPF_RAUF   12
# define KNOPF_RUNTER  2

# define HELL        300
# define FINSTER     200

# define STATUS_TAG          0
# define STATUS_ABEND        1
# define STATUS_NACHT        2
# define STATUS_MORGEN       3
# define STATUS_START_RAUF   4
# define STATUS_RAUFFAHREN   5
# define STATUS_START_RUNTER 6
# define STATUS_RUNTERFAHREN 7
# define STATUS_ERROR        8

int status   = STATUS_ERROR;
char errbuf [80];
char *errmsg = "";
int neuinitialisieren     = 1;
int debounce_magnet       = 0;
int debounce_knopf_runter = 0;
int debounce_knopf_rauf   = 0;

# define TIMER_MS       10000 // 10 seconds debounce 300000 // 5 minutes
# define FAHRZEIT_MS    75000 // max 75 seconds for up/down of door
Arduino_Timer timer (TIMER_MS);

int debounced_read (int iopin, int *counter)
{
    if (!digitalRead (iopin))
    {
        if ((*counter)++ &gt;= 10)
        {
            *counter = 0;
            return 0;
        }
    }
    else
    {
        *counter = 0;
    }
    return 1;
}

void motor_an ()
{
    digitalWrite (LED,   HIGH);
    digitalWrite (MOTOR, HIGH);
}

void motor_aus ()
{
    digitalWrite (LED,   LOW);
    digitalWrite (MOTOR, LOW);
}

void linksrum ()
{
    digitalWrite (MOTOR_DIR1, LOW);
    digitalWrite (MOTOR_DIR2, HIGH);
}

void rechtsrum ()
{
    digitalWrite (MOTOR_DIR1, HIGH);
    digitalWrite (MOTOR_DIR2, LOW);
}

// Wir benutzen Status-Funktionen fuer jeden Status unserer Maschine:
// Wenn die Funktion 0 zurueckliefert, geht die Maschine in den naechsten
// Zustand, sonst bleibt sie im gleichen Zustand.

int fahren (int magnet)
{
    if (!debounced_read (magnet, &amp;debounce_magnet))
    {
        return 1;
    }
    if (timer.is_reached (millis ()))
    {
        motor_aus  ();
        timer.stop ();
        errmsg = "Zeitueberschreitung fahren";
        status = STATUS_ERROR;
        return 0;
    }
    return 0;
}

int starte_rauffahren ()
{
    if (digitalRead (MAGNET_UNTEN))
    {
        errmsg = "Hochfahren: Tuere nicht unten";
        status = STATUS_ERROR;
        return 0;
    }
    timer.start (millis (), FAHRZEIT_MS);
    debounce_magnet = 0;
    rechtsrum ();
    motor_an  ();
    return 1;
}

int rauffahren ()
{
    return fahren (MAGNET_OBEN);
}

int starte_runterfahren ()
{
    if (digitalRead (MAGNET_OBEN))
    {
        errmsg = "Hochfahren: Tuere nicht oben";
        status = STATUS_ERROR;
        return 0;
    }
    timer.start (millis (), FAHRZEIT_MS);
    debounce_magnet = 0;
    linksrum  ();
    motor_an  ();
    return 1;
}

int runterfahren ()
{
    return fahren (MAGNET_UNTEN);
}

int nacht ()
{
    int val;
    motor_aus ();
    val = analogRead (FOTO);
    Serial.println (val);
    if (val &gt; HELL)
    {
        timer.start (millis ());
        return 1;
    }
    return 0;
}

int tag ()
{
    int val;
    motor_aus ();
    val = analogRead (FOTO);
    Serial.println (val);
    if (val &lt; FINSTER)
    {
        timer.start (millis ());
        return 1;
    }
    return 0;
}

int abend ()
{
    int val;
    motor_aus ();
    val = analogRead (FOTO);
    if (val &gt; FINSTER)
    {
        status = STATUS_TAG;
        return 0;
    }
    if (timer.is_reached (millis ()))
    {
        timer.stop ();
        return 1;
    }
    return 0;
}

int morgen ()
{
    int val;
    motor_aus ();
    val = analogRead (FOTO);
    if (val &lt; HELL)
    {
        status = STATUS_NACHT;
        return 0;
    }
    if (timer.is_reached (millis ()))
    {
        timer.stop ();
        return 1;
    }
    return 0;
}

int error ()
{
    motor_aus ();
    Serial.println (errmsg);
    delay (100);
    return 0;
}

# undef int
struct state {
    int status;
    int next_status;
    int (*statefun)();
};

// Stati muessen in der Reihenfolge der numerischen Zustandswerte sein
// Zustaende muessen lueckenlos nummeriert sein
struct state stati [] =
{ { STATUS_TAG,          STATUS_ABEND,        tag                 }
, { STATUS_ABEND,        STATUS_START_RUNTER, abend               }
, { STATUS_NACHT,        STATUS_MORGEN,       nacht               }
, { STATUS_MORGEN,       STATUS_START_RAUF,   morgen              }
, { STATUS_START_RAUF,   STATUS_RAUFFAHREN,   starte_rauffahren   }
, { STATUS_RAUFFAHREN,   STATUS_TAG,          rauffahren          }
, { STATUS_START_RUNTER, STATUS_RUNTERFAHREN, starte_runterfahren }
, { STATUS_RUNTERFAHREN, STATUS_NACHT,        runterfahren        }
, { STATUS_ERROR,        STATUS_ERROR,        error               }
};

void setup ()
{
    pinMode (LED,         OUTPUT);
    pinMode (MAGNET_OBEN,  INPUT);
    pinMode (MAGNET_UNTEN, INPUT);
    pinMode (MOTOR,       OUTPUT);
    pinMode (MOTOR_DIR1,  OUTPUT);
    pinMode (MOTOR_DIR2,  OUTPUT);
    pinMode (KNOPF_RUNTER, INPUT);
    pinMode (KNOPF_RAUF,   INPUT);

    digitalWrite (MOTOR,   LOW);
    linksrum ();
    digitalWrite (LED,     HIGH);

    digitalWrite (MAGNET_OBEN,  HIGH); // enable pull-up resistor
    digitalWrite (MAGNET_UNTEN, HIGH); // enable pull-up resistor
    digitalWrite (KNOPF_RUNTER, HIGH); // enable pull-up resistor
    digitalWrite (KNOPF_RAUF,   HIGH); // enable pull-up resistor
    Serial.begin (115200);
    if (FINSTER &gt;= HELL)
    {
        status = STATUS_ERROR;
        errmsg = "FINSTER &gt;= HELL";
    }
    Serial.print ("initial state: ");
    Serial.println (status);
}

void loop ()
{
    struct state *st = &amp;stati [status];
    if (!debounced_read (KNOPF_RUNTER, &amp;debounce_knopf_runter))
    {
        debounce_knopf_runter = 10;
        linksrum  ();
        motor_an  ();
        neuinitialisieren = 1;
        return;
    }
    else if (!debounced_read (KNOPF_RAUF, &amp;debounce_knopf_rauf))
    {
        debounce_knopf_rauf = 10;
        rechtsrum ();
        motor_an  ();
        neuinitialisieren = 1;
        return;
    }
    else if (neuinitialisieren)
    {
        motor_aus ();
        errmsg = "Unbekannte Tuerposition bei Start";
        status = STATUS_ERROR;
        if (!digitalRead (MAGNET_OBEN))
        {
            status = STATUS_TAG;
        }
        else if (!digitalRead (MAGNET_UNTEN))
        {
            status = STATUS_NACHT;
        }
        neuinitialisieren = 0;
        debounce_knopf_rauf = debounce_knopf_runter = 0;
        Serial.print ("Initialized to: ");
        Serial.println (status);
        return;
    }
    // Hard-coded error state must work if state-table is broken
    if (status &gt;= STATUS_ERROR)
    {
        error ();
        return;
    }
    if (st-&gt;status != status)
    {
        status = STATUS_ERROR;
        sprintf
            ( errbuf
            , "Error in state-table, expected %d got %d"
            , status
            , st-&gt;status
            );
        errmsg = errbuf;
        return;
    }
    if (st-&gt;statefun ())
    {
        status = st-&gt;next_status;
    }
    if (status != st-&gt;status)
    {
        sprintf (errbuf, "new state: %d-&gt;%d", st-&gt;status, status);
        Serial.println (errbuf);
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2009/01/08/9/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>OpenMoko 2008.9</title>
		<link>http://blog.runtux.com/2008/11/10/4/</link>
		<comments>http://blog.runtux.com/2008/11/10/4/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 20:19:21 +0000</pubDate>
		<dc:creator>Ralf Schlatterbeck</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[openmoko]]></category>

		<guid isPermaLink="false">http://blog.runtux.com/2008/11/10/4/</guid>
		<description><![CDATA[I&#8217;ve now had some time to look more closely into my OpenMoko Neo. The first thing I did was upgrade the device to the new Firmware 2008.9
The needed dfu-util is a Debian lenny package, on my lenny-laptop just one apt-get away. The upgrade steps are well documented on the &#8220;Flashing the Neo&#8221; page.
I&#8217;ve also upgraded [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve now had some time to look more closely into my OpenMoko Neo. The first thing I did was upgrade the device to the <a href="http://wiki.openmoko.org/wiki/Om_2008.9_Update">new Firmware 2008.9</a></p>
<p>The needed <code>dfu-util</code> is a Debian lenny package, on my lenny-laptop just one apt-get away. The upgrade steps are well documented on the <a href="http://wiki.openmoko.org/wiki/Flashing_the_Neo_FreeRunner">&#8220;Flashing the Neo&#8221;</a> page.</p>
<p>I&#8217;ve also upgraded the bootloader because I wanted to try to install Debian (on the SD card) and the instructions say to upgrade the bootloader.</p>
<p>After booting into the new version I discovered that the &#8220;Settings&#8221; icon did nothing. The device would auto-suspend after about 30 seconds when not in use <em>via the touch-screen</em>. Fortunately I had experimented earlier how to get a SSH-connection to the device &#8212; I wouldn&#8217;t have found out in 30 seconds: The device would suspend and kill a running SSH-session.</p>
<p>The openmoko device comes up as network interface <code>usb0</code> on the machine you connect the USB to. The IP is <code>192.168.0.202</code>, you should configure your <code>usb0</code> network interface to something like <code>192.168.0.200</code>.</p>
<p>I&#8217;m using the Debian package ipmasq on my laptop, so NAT to my internal network for the openmoko was working immediately, I could ping machines on my internal network.</p>
<p>So I held the touch-screen with the left-hand thumb and configured the network: The device comes up with an empty <code>/etc/resolv.conf</code>, you should insert a <code>nameserver</code> line with the IP of a reachable nameserver.</p>
<p>After having a running network (remember I&#8217;m still preventing the device from suspending and killing my ssh session with one finger on the display) I installed the package <code>illume-config</code> which adds a little toolbox-icon to the window-manager. With this I was able to finally disable the suspend via the config. After that I did an opkg upgrade of the device and the &#8220;Settings&#8221; program magically started working.</p>
<p>The first experiment with a phone-call failed, because the called party could not hear me. I had to install <code>alsamixer</code> and turn on the microphone and capture devices. Now calling and being called works fine.</p>
<p>I haven&#8217;t experimented too much until now &#8212; one of the major roadblocks is a broken input method. The on-screen keyboard is not really suitable for entering commands into an xterm. One of the next steps will be to install Debian on the device.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.runtux.com/2008/11/10/4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
