Bug in function call?

Hi,
Hope this is posted in the right place for a Photon problem - apologies if not :-O.

I have been having some great fun with calling a function from a C# app - NOT !!!.

Basically my problem comes down (I think) to trying to post more that 63 bytes :-((.

It gives some VERY strange results :-O.

Sometimes the ‘command’ string passed in is empty (or so it seems from a Sarial.println(command):wink: - BUT then at other times is seems to pass in the last GOOD command which came into the photon - despite what function it was passed into :-O.

So I have a getdata function and pass in blk=1. Then I call my setdata and pass in too much - but setdata also sees blk=1 :-O.

I suspect that you are using a common buffer and failing to wipe it if the incoming string is too big :-O.

NB using 0.4.7

BR

Graham

Ping @mdma

Hi @GrahamS

Normally this occurs when you try to do a cloud action like publish from within a cloud function or subscription. Is that what you are trying to do?

A better way is to set a flag in the cloud function to be handled and cleared later in loop() or to copy all strings that are passed to your code by the cloud to avoid this problem.

1 Like

Hi,
Oh wait a minute… yes this is indeed what I am doing - as I publish the results back to the cloud (from getdata) :-O. BUT I don’t see why this should result in the following weird behaviour though :-O.

I actually have two functions exposed in my photon, both expecting a string - called getdata and setdata.
I have a windows Form app (in C#)…
I call getdata with (lets say) ‘blk=3’. It works perfectly as expected and returns the published data as requested. Call it again and again (blk=4, blk=5 etc.) and it works as expected.

If I call setdata (separate function) with less than 63 chars data - it now works, gets the command string and does its thing ;-)) - it does NOT publish data back.

BUT lets say I call getdata blk=4 and get the result. THEN call setdata with > 63 chars of data, the string passed in to setdata is ‘blk=4’ - ie the previous string sent to my photon :-O.

I have checked (and double-checked) the C#, right up to sending the call and my postdata definitely does NOT contain blk=4 :-O.

The photon functions are separate and don’t share the data

        	Spark.function("getdata",&FRAM::readData, this);
        	Spark.function("setdata",&FRAM::writeData, this);
        
        int FRAM::readData(String command)
        {
          int resp = 1;
          char inputStr[100];
          char txt[10];
          int blk = 0;
          int i;
        
        	Serial.print(command);
          Serial.printf("\r\nreadData: %s\r\n", command.c_str());
          command.toCharArray(inputStr, 100);
        etc.....
DOES end in a publish !!!!
    
    int FRAM::writeData(String wrcommand)
    {
      int resp = 1;
      char inputStr[100];
      char txt[10];
      int blk = 0;
      int i;
    
    	Serial.println(wrcommand);
      Serial.printf("\r\nwriteData: %s", wrcommand.c_str());
    
    etc...

Its not a major problem - as I now ensure that I send in less than 63 chars. All that means is that to write a 32 byte block of data - I need to send two separate setdata function calls.

It just confused the HE*L out of me to start with - when I was trying to send too many chars ;-)).

NB I think that if I called twice consecutively with too much data - it passed nothing in the second time (which is not unreasonable ;-)). I only noticed the anomalous behaviour by sending a GOOD (getdata) command in between (which of course DOES do a publish ;-)).

Please accept my apologies if this is NOT a bug and that I am doing something stupid ;-)) - not unheard of !!! :wink:
I suspect it IS a bug though - that something is not being cleared when bad data is received ;-)).

BR
Graham

Hi @GrahamS

If what you are doing now is working for you, that’s great!

When you get data from the cloud functions on your Particle, the code is trying to be efficient and so it often hands you a pointer to its own internal data structure where it stored the incoming cloud data. But this internal data structure is also where your outgoing cloud data is temporarily stored before it is transmitted.

This is most often a problem with publish and subscribe, especial when you try to re-publish something you just got from a subscription. A solution is to copy the data you subscribe to before trying to re-publish it. That way you don’t hand the cloud function a pointer back to it own internal data structure that it is trying to manage itself.

The safe way to do this would be for your FRAM::readData function to store the result of the read into a class variable and set a flag. Then have a new function like FRAM::processData() that gets called in loop() and looks at the flag and publishes the read data when needed.

This way the cloud functions all get to return normally without another cloud function being called during their call.

Another thing you might be running into is that publish works with printable ASCII data, not with binary data, so certain characters are going to be problematic. I don’t know enough about the rest of your code to see if that is a problem or not.

1 Like

Hi,
Thanks for the ongoing feedback but I think you are missing the point :wink:
Basically I would not expect when calling a function for that function to be passed something ‘hanging over’ from a prior call :open_mouth: (ie left in an ‘internal structure’) - which really should be wiped (when bad data is sent) if its not overwritten with good data. Hence why IMO it is a bug :wink:
Yup I get that it has to be ascii - which is why I went over the limit when trying to write a block of 32 bytes of data = 64 chars when converted to hex ascii - plus controls.
I am actually writing the passed in data into an (I2C) FRAM chip - as I can’t trust the EEPROM store - see previous posts - it seems to be ‘volatile!!’…and the I2C uses an internal 32 byte buffer - hence I chose 32 bytes as my block length :wink:

Thanks again
BR
Graham