Saturday, December 05, 2009

Qt 4.6.0 on AVR32 and it’s bugs: Error: symbol `.L987' is already defined

Qt 4.6.0 is out – there is only one source archive now, “-everywhere-“, which includes the linux embedded version also. I tried to build it for the avr32 embedded system; but, a nice compiler error prohibited it.

Error: Symbol `.L987' is already defined

compiling painting/qbrush.cpp
{standard input}: Assembler messages:
{standard input}:5426: Error: symbol `.L987' is already defined
{standard input}:5544: Error: symbol `.L1012' is already defined
{standard input}:6236: Error: symbol `.L1129' is already defined
{standard input}:6353: Error: symbol `.L1154' is already defined
make: *** [.obj/release-shared-emb-avr32/qbrush.o] Fehler 1

Googling it

This error is usually based on using “inline” and “asm” statements in combination – see http://archives.devshed.com/forums/development-94/new-assembler-message-symbol-is-already-defined-1269938.html, e.g. It looks like an internal compiler error, but is usually a coding error.

“This is not a gcc bug, you cannot declare a label in an inline-asm that is going to be exposed.”

“Is there a reference of some sort? I was unable to find one with google.”
”No, just a general rule as inline-asms will be copied when inlined or cloned. What is happening here is clon(n)ing is happening so we generate two copies of that function.”

So, there is some inline method that contains assembler code – the code is duplicated b/c of the inline interpretation – and thus, the assembler labels are duplicated.

Different Compiler?

I do not think that Nokia explicitly inserted the inline+asm-combination. It is probably some gcc optimization. Unfortunately, it is not possibly to use a different compiler than the one provided by atmel in “buildroot-avr32-2.3.0” (http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4401)

Using built-in specs. Target: avr32-linux-uclibc Configured with: /avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gcc-4.2.2/configure --prefix=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=avr32-linux-uclibc --enable-languages=c,c++ --enable-__cxa_atexit --enable-target-optspace --with-gnu-ld --with-gmp=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gmp --with-mpfr=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/mpfr --enable-shared --disable-nls --enable-threads --disable-multilib --enable-sjlj-exceptions --disable-libmudflap --disable-libssp --with-build-time-tools=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir//bin Thread model: posix gcc version 4.2.2-atmel.1.1.3.buildroot.1

Change Optimisation Level

So, we have to find a way to avoid the above error. If it is an optimization problem, let’s just use some other one.

goto src/gui, patch Makefile, add –O to the end of CXXFLAGS, call make .obj/release-shared-emb-avr32/qbrush.o, and it runs through – now, you can remove the –O again, and compile the rest of it.

Alternatively, remove the @ in the beginning of CXX = …, call make, get the avr32-linux-uclibc-g++ statement, and add –O there.

Using –O3 does not work – then, the inlining is done even more often, resulting in triple definitions (or rather duplicate errors about duplicate defintions).

No idea where the error stems from, but at least, Qt 4.6.0 now compiles.

package/qtopia4/qtopia4.mk

Btw … to get that far, a few more changes are necessary. Those are, in short, in package/qtopia/qtopia4.mk:

QTOPIA4_VERSION:=4.6.0
QTOPIA4_CAT:=zcat
QTOPIA4_SOURCE:=qt-everywhere-opensource-src-$(QTOPIA4_VERSION).tar.gz
QTOPIA4_TARGET_DIR:=$(BUILD_DIR)/qt-everywhere-opensource-src-$(QTOPIA4_VERSION)
and you have to remove all the mouse driver statements – I have no idea how those are configured, now … most of them compile automatically, I may still be missing the tslib driver
### Mouse drivers
# remove all of them for Qt460
ifeq ($(BR2_PACKAGE_QTOPIA4_MOUSE_PC),y)
[...]
QTOPIA4_CONFIGURE += -no-mouse-qvfb
endif

Fixing 4.5.x Colour Depths

The previous version(s), 4.5.x, had a bug concerning a code optimisation that relied on non-aligned access – OK for i386 and followers, not OK for many other systems. Some were explicitly excluded, avr32 was not. The bug triggered when converting bitmaps between 24 and 16 bit colour depth, e.g., when connecting via vnc, or when using certain display depths directly.
See http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=79740 about fixing qt_blend_argb24_on_rgb16() in qblendfunctions.cpp.
Seems that fix is in 4.6.0, at least.

PS: QtScript

I get a compile error in QtScript – some problem with pthread_getattr_np:

compiling ../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp: In function 'void* QTJSC::currentThreadStackBase()':
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp:682: error: 'pthread_getattr_np' was not declared in this scope


Interestingly, the code does take care of uclibc 0.9.xx:

#if defined(__UCLIBC__)
// versions of uClibc 0.9.28 and below do not have
// pthread_getattr_np or pthread_attr_getstack.
#if __UCLIBC_MAJOR__ == 0 && \
(__UCLIBC_MINOR__ < 9 || \
(__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 30))
#define UCLIBC_USE_PROC_SELF_MAPS 1
#include <stdio_ext.h>
extern int *__libc_stack_end;
#endif
#endif

Oops, there are two different Collector.cpp:
3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp

One does define UCLIBC_USE_PROC_SELF_MAPS etc. as a workaround for uclibc 0.9.30, the other doesn’t – another bugreport to Nokia.

Just add -no-script to the configure options, for the moment.

Just a short note - I published both problems as Qt bug reports: QTBUG-6550 and QTBUG-6551

Have fun with it …
Sebastian

Friday, September 18, 2009

Single to Dual/Multi Core with Windows XP (ACPI HAL)

Introduction

Sometimes, people have the problem that their Windows XP is running as a “single core” system, only, although there are two or more cores installed. This can usually be seen in the task manager, where performance shows only a single graph, although “one diagram per CPU” is selected.
I talk about cores here, the same applies to multiple processors. Those are usually used on servers, though, where few people would start “fixing” the HAL.

Hardware Abstraction Layer – HAL

The reason is usually, that the normal ACPI HAL (Hardware Abstraction Layer) has been installed which does not support more than one core. In theory, XP recognises when a new CPU is installed, re-checks, and installs the correct hal. This does not always work, though.
The usual HALs are
  • Standard PC
  • ACPI PC
  • ACPI Uni-Processor (UP)
  • ACPI Multi-Processor (MP)
  • MPS Multi-Processor (APIC)
(http://support.microsoft.com/?scid=kb%3Ben-us%3B309283&x=10&y=9)
Especially in the context of virtual machines running under SUN VirtualBox, this does not work. When a windows XP system is installed with only one core active, and more core(s) is/are added later on, the CPU “id” does not change … no redetection is done, the other cores are not recognised. Another reason may be that the “ACPI PC” is not the same as “ACPI UP”, and only ACPI UP is able to support, and thus detect, more than one CPU. In the case of VirtualBox, the situation may also be caused on the IO-APIC not being enabled on install. According to SUN, XP Uniprocessor with IO-APIC is slower than without.
Officially, there is no way to upgrade the HAL. You can downgrade it, though, which is not a good idea … there is no way back.

Using devcon.exe: Forced HAL Upgrade

I found a very interesting post about the “devcon.exe”, a tool provided by MS as “the command line version of the device manager”, and its application to the HAL switch problem.
The important stuff:
Just execute the following commands in a cmd.exe shell …
devcon sethwid @ROOT\ACPI_HAL\0000 := +acpiapic_mp !acpiapic_up
devcon update c:\windows\inf\hal.inf acpiapic_mp

Of course, this may completely break your system. Make backups, find out beforehand how to restore, etc. Using a virtual box system, this is easy, just make a snapshot and restore if the upgrade does not work.
After running devcon, you reboot the system; after the reboot, XP re-detects all hardware, and the requests another reboot. This may change some of the hardware names, especially the LAN connection may get the number 2.

Hidden Devices

You can use the show-hidden trick of the device manager to display the old devices and remove them: http://support.microsoft.com/?scid=kb%3Ben-us%3B315539&x=14&y=11
set devmgr_show_nonpresent_devices=1
start devmgmt.msc

Switching the HAL

Once you get a ACPI MP hal, you can switch it to whatever you like using the device manager. Just select “new driver” for the “Computer” device.

Doing it manually

Before I found the post by “hedrums” above, I tried to do it manually. Interestingly, none of the files is locked by windows. They are loaded so early and completely in the boot process that they are no longer “needed” (used) in a running system, and can just be replaced.Yet, I never managed to copy and rename the files correctly.
Afterwards, by comparing the file sizes between the used versions (in system32) and the restore/backup versions (in ServicePackFiles\i386), I recognised the following:
• ntoskrnl.exe == ntkrnlmp.exe (2,04MB)
• ntkrnlpa.exe == ntkrpamp.exe (1,93MB)
• hal.dll == halmacpi.dll (131kB)
So, by copying the three files ntkrnlmp.exe, ntkrnlmp.exe and halmacpi.dll to system32 and renaming them to ntoskrnl.exe, ntkrnlpa.exe and hal.dll, respectively, you may be running an ACPI MP hal. I have not tried this, though.
Alternatively, using the correct ACPI UP files (whichever they are), you may get a UP system that, in turn, is automatically able to detect the multicore and again, install the correct drivers …
ACPI

Hardware.Info

I now found a tool that does the same stuff, a bit more comfortable:
http://www.hardware.info/en-US/news/ym2cmZqYwp2a/Problems_updating_to_a_dualcore_CPU_Not_anymore/

Saturday, September 12, 2009

Ubuntu Display Manager


Just some notes about the display manager(s) on Ubuntu I found out over time, and about their startup settings.
The display manager – that’s usually gdm, the gnome d.m.; alternatively kdm on kubuntu/kde, or even the good old xdm when using a lightweight desktop. In any case, it’s usually started to show a user login screen ;)

Text mode

It is often practical to boot into text only mode – at least, when you know a bit about linux. I’m not talking about removing gdm forever (apt-get remove gdm or update-rc.d -f gdm remove do this), but to use text mode in certain situations – including when you know your Xorg or gdm setup to be broken. Or, when you really want to save battery power ;)
The gdm startup allows this by putting text into the kernel command line. If this parameter is found, /etc/init.d/gdm just exits again. This can be achieved by:
  • stop the bootup in the grub menu, then

    • press “e” to edit the wanted entry
    • use the cursor keys to select the “kernel” line
    • press “e” again to edit the line
    • go to the end of the line and add “text”
    • press return to leave the line editing
    • press “b” to boot the edited entry
  • create a grub entry for text mode

    • sudo gedit /boot/grub/menu.lst
    • copy the first real boot entry (that starts with “title”) into another one below
    • change the title – append “text mode” or such
    • add “text” to the end of the “kernel” line
    • next time you boot the system, you can select the text mode and have tun.
This also disallows to start the gdm via the init script later on, because the entry is part of the kernel command line that cannot be changed. Yet, starting gdm directly achieves the same result.
By the way: I have not hardly anything about this on the web. Of course, you just need to look into /etc/init.d/gdm … the only post I found referring to this is https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/294980

gdm, kdm and xdm

Ever wondered how the various display managers that can be installed on (k)ubuntu stay out of each others hair?
  • each of them may be added to the runlevels
  • when starting, they each check whether they are the “preferred display manager” via /etc/defaults
  • if no, they exit; if yes, the one that should starts.
This way, it should not be possible to start more than one display manager – which you usually don’t want to. Opensuse, on the other hand, uses just one rc-script which decides which dm to start.

sysv-rc-conf

As a side note – I never know how to edit the /etc/rc.d?/scripts. This changed over time, mainly because of the linux standard base (LSB), I believe. The current command-line tool is update-rc.d which is not really nice to use.
But, the package sysv-rc-conf contains a textmode ui tool of the same name which seems to be usable, at least.

There is also chkconfig and insserv as I know from opensuse; yet, their packages refuse to install on Jaunty due to some sysv-init package conflicts. Probably because ubuntu migrated from sysvutils to sysvinit-utils. Or rather to upstart, where sysvinit-utils only contains some utilities.

Webservices with Axis2/Java - the simple POJO way

There are many ways to create web services in Java; the most common implementation, nowadays, is using Apache Axis2/Java and a servlet container such as Apache Tomcat or Jetty.
On the Axis2 web site, there are a number of tutorials and explanations of the various concepts; yet, somehow, I'm missing a description of the "most easy way" of creating a web service. That's why I write it here. The tutorials are based on using the provided build.xml files instead of explaining how to do it. This makes it very hard to work in a different context.

A POJO in an .aar

Axis2 is able to "interpret" any Plain Old Java Object (POJO) as a web service, given the right hints. A Pojo is just a java class with some public method(s).

A POJO

package tecbites.ws;
public class Echo {
public String echo(String input) {
return input;
}
}

To tell Axis2 that this is a web service, you need additionally

  • a services.xml that defines this class as a POJO RPC web service
  • an echo.aar that contains (at least) the services.xml in the META-INF directory, and usually, the web service code (.class file(s)).

services.xml

<service name="Echo" scope="application" >
<description>
Tecbites Echo POJO web service
</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">tecbits.ws.Echo</parameter>
</service>

Put this file into META-INF. 

creating an .aar - jar

One way to create an .aar is just using the jar-tool that is part of the JDK. Using the following folder structure:
tecbites/ws/
Echo.class
META-INF/
services.xml

, a jar can just be created that is named echo.aar. Check that the jar/aar does not contain the files in a subdirectory named echo!.
javac tecbites/ws/Echo.java
jar cf echo.aar .


creating an .aar - build.xml

Another way of creating an .aar is using build.xml, the same as creating any other .jar. See the following example:

<?xml version="1.0" encoding="UTF-8"?>
<project name="tecbites.echo" default="aar" basedir="."> <target name="build">
<javac debug="true" srcdir="." destdir="." failonerror="true" />
</target> <target name="aar" depends="build">
<property name="aar" value="echo.aar"/>
<delete file="${aar}" failonerror="false"/>
<jar destfile="${aar}">
<manifest>
<attribute name="Built-By" value="Tecbites http://tecbites.blogspot.com/"/>
</manifest>
<fileset dir="." >
<include name="**/*.class" />
<include name="META-INF/**" />
</fileset>
</jar>
</target>
</project>

Just run ant. You have got ant installed, have you?

Deployment

The installation of an Axis2 webapp and the deployment of an .aar is explained quite well on the site. Just a short version here, based on Tomcat6:

  • download the Axis2 webapp
  • deploy (copy) the axis2.war into webapps/ of a servlet container (tomcat, jetty, jboss, glassfish, ...)
And start the servlet container. Then, copy the echo.aar into the webapps/axis2/WEB-INF/services directory (the servlet container should automatically unpack axis2.war into axis2/
If you need additional jars or java code you don't want to pack into the .aar itself, there is space in axis2/WEB-INF/lib (for the jars) and axis2/WEB-INF/classes (for any package/name/Class.class files).
Usually, Axis2 is configured for "hot deployment". This means that any .aar copied newly into the services directory of a running server is directly deployed as a new web service. There is also "hot update" which is usually disabled, but can be enabled in axis2/WEB-INF/conf/axis2.xml. Then, the .aars are automagically reloaded when replaced. Of course, any code in lib/ or classes/ is not.
By the way - it should also be possible to deploy the web service by copying the unjared folder structure into a subdirectory of the services dir, thus creating webapps/axis2/WEB-INF/services/Echo/META-INF/services.xml etc.

Testing

The web service should then be visible on http://localhost:8080/axis2/services/listServices (replace port 8080 with the correct one of your servlet container installation). There, you can see all deployed services and list their methods.
The WSDL can be accessed via http://localhost:8080/axis2/services/EchoService?wsdl.
Axis2 supports a part of REST, named POX - Plain Old XML documents over http. This allows to call the web service via http://localhost:8080/axis2/services/EchoService/echo?input=Good%20Morning. A web page should be returned reading

<ns:echoResponse xmlns:ns="http://ws.tecbites">
<ns:return>Good Morning</ns:return>
</ns:echoResponse>

By the way - the following error message when accessing http://localhost:8080/axis2/services/EchoService means the service is working correctly: ;)

<soapenv:Reason>
<soapenv:Text xml:lang="en-US">
The endpoint reference (EPR) for the Operation not found
is /axis2/services/EchoService and the WSA Action = null
</soapenv:Text>
</soapenv:Reason>



Direct POJO deployment

There is also the description of deploying the POJO .class file directly into a specially configured axis2 directory. In the axis2/WEB-INF/conf/axis2.xml, there is usually a line reading

<!--POJO deployer , this will alow users to drop .class 
file and make that into a service-->
<deployer extension=".class" directory="pojo"
class="org.apache.axis2.deployment.POJODeployer"/>

This should allow to deploy the ws by copying tecbites/ws/Echo.class into the pojo directory. In the context of the jetty servlet container inside the Global Sensor Networks (GSN) project, I was unable to get this to run.

JAXWS @WebService annotations

The JAXWS standard allows to "create" web services by annotating the class with the @WebService tag. In the axis2+service.xml context, this is not necessary, but supported.
Yet, this is helpful when the web service class contains public methods that should not be accessible as web service methods.

package tecbites.ws;
import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class Echo {
public String echo(String input) {
return input;
}
@WebMethod(exclude=true)
public /*static*/ String helper(String input) { return input; }
}


Side note

You might think I'm working for the Apache project, the way I propose their products/projects here. No, I'm not, it's just a fact that "they" are developing open source Java projects for many purposes, from development support (log4j, ant, ...) over utilities (commons, ...) to enterprise technologies (tomcat, axis2).

Eclipse Galileo 3.5.0 as packages for Ubuntu Jaunty


~Yogarine

The eclipse packages delivered with ubuntu are usually very, very old (3.2.x on jaunty). This is mainly due to the rule of debian that everything(!) needs to be compiled by the maintainers. Also, they use a completely different Java compile setup than the eclipse developers - gcj (which is really open source) instead of Sun JDK.
I just found someone who maintains the eclipse-provided binaries as a set of packages for ubuntu jaunty.
https://edge.launchpad.net/~yogarine/+archive/eclipse
Quite easy to install and use - just note that the JEE tools are inside eclipse-wtp (web tools project).
It may be that there is stability problem ... I had one crash so far ... no idea whether this was related to the packages or the Java setup itself on my system (it was somewhere in the subversion->libsvnjavahl->libapr stuff).

Tuesday, July 14, 2009

Wisdoms of the day

  • Wenn du den Kaffee nicht aufschüttest, läuft er nicht durch
  • tar cf file.tar --- "cowardly refusing to create empty archive."
    Has saved a lot of archives when typing tar cf instead of tar xf ...
  • Ever found a good editor for this blog system?
  • Why am I the only person unable to create a debugging environment for the AVR32?

Monday, July 06, 2009

Using module_param_call for Linux kernel module parameters

My first foray into linux kernel programming – writing a module to drive an external buzzer, using the high resolution timer. Not my first action on the linux kernel, though: http://www.lm-sensors.org/changeset/3613/i2c/trunk

Found a nice feature that is not yet well documented.

ushort enabled =0;
module_param(enabled, ushort, 
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); MODULE_PARM_DESC(enabled, " Enabled or not");
  • Defines a module parameter that can be set on insmod
  • giving it rights (S_*** equals 0664 aka rw-rw-r-- in this case) allows to set the value via /sys/module/modulename/parameters/parameter for both reading and writing
  • Unfortunately, the module is not notified when the value is set.

http://lwn.net/Articles/85443/ only says: “It is worth noting, however, that there is no mechanism for notifying a module that one of its parameters has been changed”.

Well, there is a method. module_param_call. Or rather a macro. It’s hard to find anything about it on the web, the only(?) source currently are the linux kernel source files … especially include/linux/moduleparam.h and kernel/params.c.

static int param_set_buzzer_enabled(const char *val, 
  struct kernel_param *kp);
unsigned int buzzerenabled = 0;
module_param_call(buzzer_enabled, param_set_buzzer_enabled, param_get_int,
    &buzzer_enabled, 0664);
MODULE_PARM_DESC(buzzer_enabled, " Buzzer enabled? default: 1 (yY)");

When the value is queried, the pre-defined method param_get_int is called which directly accesses the (&)buzzer_enabled value. When the value is set, the spezial method param_set_buzzer_enabled is called. Of course, it is also possible to do it another way, e.g., to create a read-only parameter which does not have a variable backing.

The role of the param_set_buzzer_enabled method is best passed to one of the predefined methods – in this case, param_set_bool:

static int param_set_buzzer_enabled(const char *val, struct kernel_param *kp)
{
  int hr;

  // 1yY 0nN
  hr = param_set_bool(val, kp);
  if (hr!=0) {
    printk("Unable to set buzzer_enabled to value '%s'\n", val);
    return hr;
  }
  // do the job, here ;-)
  printk("New value: %d\n", buzzer_enabled);
  return 0;
}

val is char*, always – in some cases, special care needs to be taken of trailing newlines produced by "echo 0 > /sys/...". At least some implementations of the conversion routine (using simple_strtol) fail in this case – "echo –n 0" needs to be used, then.

I’d say, far easier to use than defining your own kobject instances, attributes and files, and place them in the appropriate /sys/-folders. By the way – the macro used above, module_param, does nothing else than calling the other one with the correct param_set_##type methods based on the given type (ok, I admin, module_param_named also participates).

Yours,
Sebastian

Sunday, March 15, 2009

UPnP via python

Controlling your DSL Router via UPnP

When I was looking for a commandline tool to create port mappings on my broadband/DSL router, I detected the miranda.py script on http://www.sourcesec.com/2008/11/07/miranda-upnp-administration-tool/. I needed some functionality not yet provided by the script, namely, the possibility of passing arguments to host send commands. Usually, the script asks nicely for all required arguments; this is hard to automate. Using the patch provided below, a command such as
host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32  1  22  80.80.80.80 tcp  22
is now possible. This also allows bash scripting:
cat <<EOF | miranda.py -s ~/.miranda/struct_data.mir
host get 0
host send 0 WANConnectionDevice WANIPConnection AddPortMapping ssh2 0 192.168.32.32  1  22  80.80.80.80 tcp  22
EOF
I also fixed a nondescript exception message when no host had yet been loaded/found. Have fun with it,
yours,
Sebastian
--- miranda.py.orig 2009-03-15 13:51:03.000000000 +0100
+++ miranda.py 2009-03-15 13:58:37.000000000 +0100
@@ -1065,11 +1065,15 @@
    #Send SOAP requests
    index = False
    inArgCounter = 0
-
-   if argc != 6:
+   
+   #sbr: allow to pass arguments to the call
+   numReqArgs = 6
+   if argc < numReqArgs:
     showHelp(argv[0])
     return
+   # number of arguments in addition to the send cmd
    else:
+    extraArgs = argc-numReqArgs
     try:
      index = int(argv[2])
     except:
@@ -1078,7 +1082,12 @@
     deviceName = argv[3]
     serviceName = argv[4]
     actionName = argv[5]
-    hostInfo = hp.ENUM_HOSTS[index]
+    try:
+     hostInfo = hp.ENUM_HOSTS[index]
+    except Exception, e:
+     print "You need to discover or load some hosts, first"
+     return
+   
     actionArgs = False
     sendArgs = {}
     retTags = []
@@ -1106,11 +1115,18 @@
      print "Are you sure you've specified the correct action?"
      return False
 
+    extraArgsUsed = 0
     for argName,argVals in actionArgs.iteritems():
      actionStateVar = argVals['relatedStateVariable']
      stateVar = hostInfo['deviceList'][deviceName]['services'][serviceName]['serviceStateVariables'][actionStateVar]
 
      if argVals['direction'].lower() == 'in':
+         if extraArgs-extraArgsUsed > 0:
+      arg = argv[numReqArgs+extraArgsUsed]
+      print "Using ", arg, " for ", argName
+      sendArgs[argName] = (arg,stateVar['dataType'])
+      extraArgsUsed += 1
+         else:
       print "Required argument:" 
       print "\tArgument Name: ",argName
       print "\tData Type:     ",stateVar['dataType']