nova proba

TcpServerToFlash.cpp

Committer:
bosko001
Date:
2020-04-22
Revision:
9:893843262a1f
Parent:
7:7ea932eb31f6
Child:
10:15f7fea18a2f

File content as of revision 9:893843262a1f:

#include "mbed.h"
#include "string.h"

#include "EthernetSetup.h"
#include "dxml.h"
#include "TcpServerToFlash.h"
#include "doHTML.h"
#include "dataFlash.h"

#define SOCKET_PORT 11000

Semaphore s(1); /* semafor da ne dozvoli vise of 1 server thred-a, upravlja delet-ovanjem threda*/


extern EthernetInterface *gp_eth;

/* globalni pointer na tcpServer RX Thread za parametarizaciju  */
Thread *gp_tcpServerThread = new Thread;
void tcpServerRx_fun( void );


TCPSocket *gp_tcpSocket=NULL;   /* socket za prijem zahteva za konekciju */
volatile Thread *gp_thr = NULL; /* soket za komunikaciju sa klijentom */


const char sendHTTPheader[]= "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE html>";

typedef void(*PF_PSTP)(struct SThreadParam *);

// parametri thread-a za uspostavljenje konekcije
struct SThreadParam
{
  Thread *p_Thread; // sopstveni pointer
  void * p_param;  // pointer za parametre thread-a, u ovom slucaju na socket koji je accept-van
  PF_PSTP pf_pstp;  // pointer na funkciju koju thread callback-uje
};

/******************  inicijalizacija u mainu  ************************/

void inic_TcpServerToFlash( void )
{
    gp_tcpServerThread->start(tcpServerRx_fun);

}

/*****************  periodicna prozivka u mainu *************************/
// zatvaranje thread-a nakon http razmene 

void cleanTcpServerToFlashThread( void )
{
        if(gp_thr) 
        { 
            printf("brisanje thread-a %d\n\r", gp_thr); 
            delete gp_thr; gp_thr = NULL; 
            s.release(); 
        } 
}


/**************  Trajni TCPServer thread *********************************/

extern void rcpServerInstance_fun( SThreadParam *ps_thr );
void tcpServerRx_fun( void )
{
   printf("Otvoren tcp server rx thread \n\r");   

   if( gp_tcpSocket == NULL )
   {
      gp_tcpSocket = new TCPSocket;
      gp_tcpSocket->open( gp_eth );
      if(gp_tcpSocket->bind(SOCKET_PORT) !=0) printf("greska bindovanja socketa\n\r");
    }
    if(gp_tcpSocket->listen(1) != 0 )  printf("greska listenovanja na socketu\n\r");;
 
    TCPSocket *p_soc;
    nsapi_error_t err=NULL;      
 
    while(   (p_soc = gp_tcpSocket->accept( &err)) || (err == NSAPI_ERROR_NO_SOCKET)  )
    {
        s.wait();     // semafor sprecava novu konekciju dok se stara ne zavrsi 

        Thread *p_thr = new Thread;
         struct SThreadParam *ps_thp = new struct SThreadParam;  // alokacija ps_thp
         ps_thp->p_param = (void*)p_soc;
         ps_thp->p_Thread = p_thr;
         ps_thp->pf_pstp = rcpServerInstance_fun;
       
        printf("TCPThread: NOVA KONEKCIJA!  thread %d   socket  %d   struct Sst %d\n\r", ps_thp->p_Thread, p_soc, ps_thp);
        p_thr->start( callback( ps_thp->pf_pstp, ps_thp ));

    }

    if( gp_tcpSocket ) {delete gp_tcpSocket; gp_tcpSocket = NULL; } /* ima smisla ako se thread nasilno zatvara  */
}




/***************** privremeni TCPServer thread za klijenta  ******************/
// thread je jednokratan - primi http telegram i odgovori - ako je GET ili POST upit

void rcpServerInstance_fun( struct SThreadParam *ps_thp )
{
     TCPSocket *p_soc = (TCPSocket *)ps_thp->p_param;
     char inbuff[1500];

      int n, nr, nt;
      printf("thread:  Otvoren socket %d\n\r",(int)p_soc);   
    
        while(true)
       {        
         extern C_HTMLparse *gpc_html;
 
            printf("\n\rcekam prijem od klijenta \n\r");
            SocketAddress sockAddr;
            p_soc->getpeername( &sockAddr );
            
            p_soc->set_timeout(10); // non-blocking pruzimanje bajtova na 10ms
            n=0;
            do
            {
               nr = p_soc->recv( &(inbuff[n]), sizeof(inbuff)-n);
               if(nr > 0) n += nr;
               if(n>= sizeof(inbuff)) break;
            }
            while( (n==0) || (nr > 0) );
            if( (nr < 0) && (nr != NSAPI_ERROR_WOULD_BLOCK) )   break;
            
            if(n>0)
            {

             //u inbuff-u je http paket
              printf("PRIJEM tcpSOCKET: primljeno = %d bajtova \n\r",n);
              
//              {   int i; for(i=0;i<n;i++)  printf("%c", inbuff[i] );}
//                printf("KRAJ PRIJEMA\n\r");
//                      fflush(stdout);
                inbuff[n]=0;
                //raspakivanje sadrzaja, a ako je POST preuzimanje parametara
                char * str = gpc_html->doHTTP( inbuff);
                if( !strcmp( str, "GET_HTML") || !strcmp( str, "POST") )
                {

                    //    putHTMLintoFLASH( gpc_html );
                    //putFLASHintoHTML( gpc_html );

                    if(!strcmp( str, "POST") ) 
                    { 
                        gpc_html->htmlPOST_fun( );   // setovanje parametara u HTML format
                         
                        putHTMLintoFLASH( gpc_html );   // upis parametara iz HTMLa u FLASH
                        extern void ethRestart( void );
                            ethRestart( );
                        extern void scomRxThreadRestart( void );
                         scomRxThreadRestart( );
                        extern void udpRxThreadRestart( void );
                         udpRxThreadRestart( );

                     }
    
    // ODGOVOR - slanje odgovora klijentu
    
                    p_soc->set_timeout(-1);  // blocking
                    // slanje HTTP headera
                    n = p_soc->send(sendHTTPheader, strlen(sendHTTPheader));
                    printf("PREDAJA HTTPheader: posato bajtova = %d, %d \n\r", n, strlen(sendHTTPheader));
                    
            //        putFLASHintoHTML( gpc_html );   // preuzimanje podataka iz flasha u html
                    auto c = gpc_html->getHTML_free( );  // konvertovanje HTMLa u niz
                    n = p_soc->send(c, strlen(c));  // slanje HTML-a
                   
                   // test - slanje HTMLa na serial com 
                   //     extern UARTSerial *gp_scom;
//                        extern void sendScom( struct UARTSerial *p_scom, char *buffer, int val);
//                        sendScom( gp_scom, c, strlen(c));
     
                    free(c); // oslobadjanje memorije HTML niza


                    printf("PREDAJA dataBuffer: posato bajtova = %d, %d \n\r", n, strlen(c));
                    
                }
             }
            
            p_soc->close();    // zatvaranje socketa
           /* if(n<0)*/ {printf("BREAK posle predaje\n\r"); break;}
        }
      // zatvaranje thread-a
      gp_thr = ps_thp->p_Thread;//   poslati pointer da se delete-uje
      
      delete ps_thp; // relokacija ps_thp
      
}