Read response from HTTP POST request in PICOC

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Gast

    #1

    Read response from HTTP POST request in PICOC

    Hi,

    I am trying to read the response from a HTTP post request into a PICOC program. So far the tcpstream posts the appropriate JSON data from the miniserver to the remote server. I can see the remote server returning the json data. How do I read this response into the PICOC program?

    Thanks in advance.

    PICOC Code (IP addresses removed):
    Code:
    #define BUFF_SIZE 40000
    #define RD_BLOCK_SIZE 128
    
    char* ReadTemperatures()
    {
        STREAM* pTcpStream = stream_create("/dev/tcp/x.x.x.x/4242",0,0);   // create tcp stream
        char* pTcpCmd = "POST /GetStat HTTP/1.1\r\nHost: x.x.x.x\r\nContent-Length: 11\r\nAccept: '*/*\r\nUser-Agent: LoxLIVE [en]\r\nContent-Type: application/json; charset=utf-8\r\n\r\n{\"INFO\":0}";
    
        char* res;
    
        printf("S: %d", strlen(pTcpCmd));
        stream_write(pTcpStream,pTcpCmd,strlen(pTcpCmd));   // write to output buffer
        stream_flush(pTcpStream);                           // flush output buffer
        char szBuffer[BUFF_SIZE];
        char szTmpBuffer[RD_BLOCK_SIZE];
        int nCnt;
        int nBytesReceived = 0;
        int i = 0;
    
        printf("Stream Opened");
        do
        {
            nCnt = stream_read(pTcpStream,szTmpBuffer,RD_BLOCK_SIZE,4000);
            nCnt = stream_read(pTcpStream,szTmpBuffer,RD_BLOCK_SIZE,4000);
            printf("Received: %s", szTmpBuffer);
            if(nCnt > 0)
                strncpy((char*)szBuffer+i*RD_BLOCK_SIZE,szTmpBuffer,nCnt);
            nBytesReceived += nCnt;
            i++;
        } while (nCnt > 0);
        szBuffer[nBytesReceived] = 0;
        stream_close(pTcpStream);
        printf("Data received: %s", szBuffer);
        return szBuffer;
    }
    
    void ProcessInput(char* data)
    {
        //[{"device": "kitchen", "CURRENT_TEMPERATURE": 16.5}, {"device": "office", "CURRENT_TEMPERATURE": 19.0}]
        char device[30];
        float temp;
        char* pS = data;
        int pos = 0;
        while(*pS)
        {
            p = strstrskip(pS,"\"device:\" ");
    
            if (p != NULL)
            {
                //get device name
                pos = strfind(p,",", pos);
                strncpy(device,p+1,pos-1);
    
                //get temp reading
                p = strstrskip(p,"\"CURRENT_TEMPERATURE\": ");
    
                if (p != NULL)
                {
                    pos = strfind(p,",", pos);
                    temp = batof(p + (pos - 1));
    
                    setio(device,temp);
                }
    
                ps += pos;
            }
    
            else
            {
                pos = (strlen(pS) + 1);
            }
            pS += pos;
        }
    }
    
    while(TRUE)
    {
        printf("Reading Temperatures");
        char* res = ReadTemperatures();
        //ProcessInput(res);
    
        sleeps(10);
    }
  • Jan W.
    Lox Guru
    • 30.08.2015
    • 1366

    #2
    Hi Mars21,

    I'm a bit confused, because you are actually reading the response from the remote server. The two "stream_read" statements look a bit strange, because you read the first chunk, forget the content you have read and do the next stream_read. The second stream_read is processed properly and szBuffer contains the information that was sent from the remote server. If the content is readable text, then you should see it with printf statement at the end of the function. Of course only every second block, so I suggest to delete one of the two "stream_read" lines. I also recommend modify your code regarding the local variable szBuffer. You are returning a pointer to the memory of szBuffer, but the memory was only allocated within the function "processinput".

    What output do you get from the code above? Why is the processInput marked as a remark?

    Cheers,
    Jan
    Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
    Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
    Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
    Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
    Node-RED: IKEA Tradfri

    Kommentar

    • Gast

      #3
      Hi Jan.

      Thanks for the reply. The second read was me trying to get it to work. I will remove it. I had tried with just one and the result was the same. I do not get anything back from the read. I should be getting json data back (like what is in the comment at the start of the processinput function).

      The processinput is commented out until I can get the input.

      The current output is just the printf statements with no variable data.

      Mary

      Kommentar

      • Dils
        Azubi
        • 05.01.2016
        • 1

        #4
        Hi mars21

        Looks like I am trying to integrate with the same device as you.

        Only just started looking in to this.

        Kommentar

        • Jan W.
          Lox Guru
          • 30.08.2015
          • 1366

          #5
          Hi Mary,

          are you able to use Wireshark on the server side or do a port mirroring (available on some higher end switches)? This might help to identify if there is a typo in the HTTP POST command and to see if there is anything sent back from the server. You may also add some debug code to the "stream_read" function, e.g.

          printf( "DEBUG Amount of bytes read from the stream: %d ", nBytesReceived );
          printf( "DEBUG Stream as decimal values: " );
          for ( j=0; j<nBytesReceived; j++ ) {
          printf( "%d, ",(int)szBuffer[j] );
          }

          If nothing is received, I would check the HTTP POST input, e.g. content length=11 ?. A tool like wfetch.exe from Microsoft or curl/wget for Linux in addition to Wireshark may help to do this.

          Jan
          Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
          Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
          Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
          Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
          Node-RED: IKEA Tradfri

          Kommentar

          • Gast

            #6
            Hi Jan,

            Thanks for the reply. Printing nBytesReceived shows 0. On the the remote server side I can see the post request coming in and response being returned. (I have also tested the post request with a bit of python code and can see the response coming back from the server).

            I will give wireshark a go tomorrow. Thanks for all the suggestions so far.

            Mary

            Kommentar

            Lädt...