nova proba

TcpServerToFlash.cpp

Committer:
Bosko Lekovic
Date:
2020-05-17
Revision:
18:5ee53205451a
Parent:
17:74c41e3f10b8
Child:
19:7bdb1a10043f

File content as of revision 18:5ee53205451a:

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

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

#include "UdpClients.h"
#include "TcpClients.h"
#include "SerialCom.h"


#define SOCKET_PORT 80

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

//Mutex m;

volatile int tcpServerBlock=0;  // Blokira serijsku komunikaciju tokom upisa u data flash 

extern EthernetInterface *gp_eth;

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


static TCPSocket *gp_tcpSocket=NULL;   /* socket za prijem zahteva za konekciju */
static Thread *gp_thr = NULL; /* pointer gde se smesta thread za brisanje */


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  ************************/
char* html_string;

void inic_TcpServerToFlash( void )
{
//   extern C_HTMLparse *gpc_html;
//  html_string = gpc_html->getHTML_free( );  // konvertovanje HTMLa u niz
   
    if( gp_tcpServerThread )  delete gp_tcpServerThread;
    gp_tcpServerThread = new Thread();    
    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); fflush(stdout);
            gp_thr->join(); 
            
            delete gp_thr; 
            gp_thr = NULL; 
            printf("Obrisan thread %d\n\r", gp_thr); 
//            s.release(); 
        } 
}

void _semafor_release(void ) {/* s.release();*/}
/**************  Trajni TCPServer thread *********************************/

volatile int bws=0;  //block web server

extern void rcpServerInstance_fun( SThreadParam *ps_thr );
void tcpServerRx_fun( void )
{
  while( true )
  {  
    printf("____Otvoren TCP server rx thread____ \n\r");   
    if( gp_tcpSocket ) {delete gp_tcpSocket; gp_tcpSocket = NULL; } /* ima smisla ako se thread nasilno zatvara  */

      gp_tcpSocket = new TCPSocket;
      if(gp_tcpSocket->open( gp_eth ) != 0) break;
      gp_tcpSocket->bind(SOCKET_PORT);

        if(gp_tcpSocket->listen(2) != 0 )  
        {   printf("greska listenovanja na socketu\n\r");  break;}
    
        TCPSocket *p_soc;
        nsapi_error_t err=NULL;      
    int nos = 0;

    while(   (p_soc = gp_tcpSocket->accept( &err))  )
    {
    printf("\n\rTCP WEB SERVER: zahtev za konekciju - socket = %d  err = %d\n\r", p_soc, err);fflush(stdout);
    //     s.wait();     // semafor sprecava novu konekciju dok se stara ne zavrsi 
    printf("TCP WEB SERVER: Broj %d\n\r", ++nos); fflush(stdout);

bws = 1;

            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);fflush(stdout);
            p_thr->start( callback( ps_thp->pf_pstp, ps_thp ));

while(bws);

    }
    printf("TCP WEB SERVER: Ispad iz accept while!!! socket = %d  err = %d\n\r", p_soc, err);fflush(stdout);
   }

}




/***************** 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;
     
//     m.lock();
//     tcpServerBlock++;

     char inbuff[1500];
int restart = 0;

      int n, nr, nt;
      printf("tcpServThread:  Otvoren socket %d\n\r",(int)p_soc);   
    
        while(true)
       {        
         extern C_HTMLparse *gpc_html;

            printf("tcpServThread: cekam prijem od klijenta \n\r");
            SocketAddress sockAddr;
            p_soc->getpeername( &sockAddr );
            
            p_soc->set_timeout(10); // non-blocking pruzimanje bajtova na 10ms
            n=0;
            int k=10, t=0;
            do
            {
                t++;
               nr = p_soc->recv( &(inbuff[n]), sizeof(inbuff)-n);  // razmotriti obradu nr=0 !!!
               if(nr > 0) n += nr;
               else k--;
               if(n>= sizeof(inbuff)) break;
            }
            while( ((n==0) || (nr > 0) ) && k );
            printf( "tcpServThread: broj  prolaza t=%d   k=%d  n=%d nr=%d\n\r ", t, k, n, nr);
            if( (nr < 0) && (nr != NSAPI_ERROR_WOULD_BLOCK) )   break;
            if( !k ) break;
            
            if(n>0)
            {

             //u inbuff-u je http paket
              printf("tcpServThread: primljeno = %d bajtova \n\r",n);
              fflush(stdout);
              
                inbuff[n]=0;
                //raspakivanje sadrzaja, a ako je POST preuzimanje parametara
                char ** strniz = gpc_html->doHTTP_freereturn( inbuff);
                char *type = strniz[0];
                char *description = strniz[1];
                if( (!strcmp( type, "GET") && !strcmp( description, "HTTP")) || !strcmp( type, "POST") )
                {



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

                    if(!strcmp( type, "POST") ) 
                    { 

     tcpServerBlock++;
       printf("tcpServThread: ___stop komunikacije\n\r");
            
//                        scomRxThreadCancel();
                         tcpRxThreadsCancel();
                printf(" STACK: size=%d free=%d used=%d max used=%d\n\r", ps_thp->p_Thread->stack_size(),ps_thp->p_Thread->free_stack(),ps_thp->p_Thread->used_stack(),ps_thp->p_Thread->max_stack());
          //              udpRxThreadsCancel();
           //         wait(0.1);
                         gpc_html->htmlPOST_fun( );   // setovanje parametara u HTML format                         
                         putHTMLintoFLASH( gpc_html );   // upis parametara iz HTMLa u FLASH
            // vratiti podatke iz Flasha u HTML !!!!!!
//         ethRestart( );
       //     udpRxThreadsRiseUp( );
         //   scomRxThreadRiseUp( );
            tcpRxThreadsRiseUp( );
            
 restart = 1;
                      }
  
    // ODGOVOR - slanje odgovora klijentu
    
                    p_soc->set_timeout(-1);  // blocking
                    // slanje HTTP headera
// if(strcmp( type, "POST") ) 
                    { 
                    n = p_soc->send(sendHTTPheader, strlen(sendHTTPheader));
                    printf("tcpServThread: predaja HTTPheader: posato bajtova = %d, %d \n\r", n, strlen(sendHTTPheader));
                    
            //        putFLASHintoHTML( gpc_html );   // preuzimanje podataka iz flasha u html

                    auto html_string = gpc_html->getHTML_free( );  // konvertovanje HTMLa u niz
                    n = p_soc->send(html_string, strlen(html_string));  // slanje HTML-a
                    printf("tcpServThread: PREDAJA dataBuffer: posato bajtova = %d, %d \n\r", n, strlen(html_string));
                    free(html_string); // oslobadjanje memorije HTML niza
                    }                
                }
                free(type);
                free( description);
                free(strniz);
             }
            
        
           //!!! p_soc->close();    // zatvaranje socketa
           // if(n<0) 
               {printf("tcpServThread: BREAK posle predaje\n\r"); break;}
           
        } // end while
               
        {printf("tcpServThread: zatvaranje socketa\n\r"); fflush(stdout);}      
        
        p_soc->close();    // zatvaranje socketa      

        printf("tcpServThread: restart = %d\n\r",restart);
        if( restart )
        {
            printf("tcpServThread:___restart komunikacije\n\r");
    //         ethRestart( );
    //    //     udpRxThreadsRiseUp( );
    //         tcpRxThreadsRiseUp( );
    //     //    scomRxThreadRestart( );
            restart = 0;
        }

        printf(" STACK: size=%d free=%d used=%d max used=%d\n\r", ps_thp->p_Thread->stack_size(),ps_thp->p_Thread->free_stack(),ps_thp->p_Thread->used_stack(),ps_thp->p_Thread->max_stack());

        {printf("tcpServThread: zatvaranje thread-a\n\r"); fflush(stdout);}          
        // zatvaranje thread-a
        gp_thr = ps_thp->p_Thread;//   poslati pointer da se delete-uje
 
        {printf("tcpServThread: brisanje parametara\n\r"); fflush(stdout);}         
        delete ps_thp; // relokacija ps_thp

bws = 0;
//m.unlock();
   if( tcpServerBlock)  {tcpServerBlock--;printf("tcpServThread: tcpServerBlock=%d\n\r", tcpServerBlock);}

}