IBM / nodejs-itoolkit

A JavaScript (Node.js) library for communicating with IBM i
MIT License
43 stars 37 forks source link

ProgramCall - Function that returns a packed variable #391

Open tomcphr opened 5 months ago

tomcphr commented 5 months ago

I'm trying to call a function on a service program that returns a packed variable but I can't seem to get it working.

I get this error message:

image

Would someone be able to let me know what I'm doing wrong here? I believe it's something to do with my return method call as if I remove this the call goes through successfully.

const conn = new Connection({
    transport: 'odbc',
    transportOptions: {
        host: 'box-hostname',
        username: 'username',
        password: 'password',
    },
});
conn.debug(true);
let pgm = new ProgramCall('PROGRAMNAME', { lib: 'LIBRARY', func: 'FUNCTIONNAME', error: 'ON'});
pgm.addParam({type: '30a', value: 'TYPE', by: 'ref'});
pgm.addParam({type: '30a', value: 'REF', by: 'ref'});
pgm.addReturn({type: '20p0', value: 0});
conn.add(pgm);

conn.run((error: any, xmlOutput: any) => {
    if (error) {
        throw error;
    }
    console.log(xmlOutput);
});

Node: v20.12.2 XML Toolkit 2.0.2-dev

abmusse commented 5 months ago

Hi there!

pgm.addReturn({type: '20p0', value: 0});

This might be a long shot but could you try adding a decimal point?

pgm.addReturn({type: '20p0', value: '0.'});

from the screenshot it seems like the value is being interperted as hex for some reason where it should default to not interpreting the value as hex.

See: https://nodejs-itoolkit.readthedocs.io/en/latest/ProgramCall.html#returnConfig

Another suggestion would be to explicitly set hex to off

pgm.addReturn({type: '20p0', value: '0', hex: 'off' });
tomcphr commented 5 months ago

Hi @abmusse

Thanks for the suggestions but unfortunately no luck.

I get the same error on both suggestions. Do you know how I could debug this on IBM I?

abmusse commented 5 months ago

Thanks for the suggestions but unfortunately no luck.

ah I see

Do you know how I could debug this on IBM I?

This may be bug with xml-service not returning packed decimal types properly from service program calls.

I think we need to debug by determining whether this an issue returning packed decimal from ILE call or xml-service having issues handling returning the packed decimal.

Some ideas for debugging:

1) Write a service program function that returns a packed decimal

2) Write a C program / python with c-types program that uses ILE Call to call the function.

3) Confirm that xml-service can return the packed decimal properly

tomcphr commented 5 months ago

Hi @abmusse

Thanks for the suggestions, it looks like this isn't a bug with this but with the service module I was calling is doing something somewhere that it causing it to fall over.

I've managed to get a working packed variable back by creating a basic service program that just returns the packed var.

# Test

h nomain

dcl-proc getPacked export;

  dcl-pi packed(5:0);
    #var char(2) const;
  end-pi;

  return %dec('000001': 5: 0);
end-proc;
<pgm name='SERVICETRC' lib='library' func='GETPACKED' error='ON'>
<parm by='ref'>
<data type='2a'>AA</data>
</parm>
<return>
<data type='5p0'>1</data>
</return>
 <success><![CDATA[+++ success library SERVICETRC GETPACKED ]]></success>
</pgm>
tomcphr commented 5 months ago

I just re-opened as it looks like it's actually an issue with the length of the packed type field.

Doing that service program with a packed variable of anything over 15p0 doesn't work.

For example:

This works fine and returns:

dcl-proc getPacked export;

  dcl-pi packed(15:0);
    #var char(2) const;
  end-pi;

  return %dec('000000000000001': 15: 0);
end-proc;

But this doesn't:

dcl-proc getPacked export;

  dcl-pi packed(16:0);
    #var char(2) const;
  end-pi;

  return %dec('0000000000000001': 16: 0);
end-proc;

Does the XMLSERVICE store the return value in a field that has a maximum character limit or something of that sort?

kadler commented 5 months ago

I was gonna say when reading your comment where you closed the issue, might want to try with an even sized packed decimal. Size of a packed(N) in bytes is (N + 1)/2, which has the effect of packed decimals with an even number of digits being rounded up. So a packed(15) fits exactly in 8 bytes (15 nibbles plus sign nibble = 16 nibbles = 8 bytes), while packed(16) would be rounded up to 9 (16 nibbles plus sign nibble = 17 nibbles = 8.5 bytes -> 9 bytes).

It's likely that XMLSERVICE is calculating the space for even-sized packed decimal values incorrectly. We'll probably need to do some debugging with XMLSERVICE here to investigate further.

tomcphr commented 5 months ago

Hi @kadler

I've just tried that same code with both 10p0 and 14p0 and both return without errors as expected.

kadler commented 5 months ago

Huh. Definitely think we'll need to debug in to XMLSERVICE to figure out what's going on.