StdPJ/Core/Src/APP/BSP/ug96/ug96.c
/**
  * @brief  Receive an amount data over C2C.
  * @param  Obj: pointer to module handle
  * @param  Socket: number of the socket
  * @param  pdata: pointer to data
  * @param  Requestedlen (IN) : in UG96_BUFFER_MODE the req len, in UG96_DIRECT_PUSH is the max leng available in pdata[] buffer
  * @param  Receivedlen (OUT) : pointer to return the length of the data received
  * @param  Timeout : timeout (ms) used by each internal exchange Mcu<-->modem; hence function could take much longer to return
  * @retval Operation Status.
  */
@brief  Receive an amount data over C2C.
@brief Receive an amount data over C2C .
UG96_ReceiveRet_t  UG96_ReceiveData(Ug96Object_t *Obj, uint8_t Socket, uint8_t *pdata, uint16_t Requestedlen, uint16_t *Receivedlen, uint32_t Timeout)
{
  UG96_ReceiveRet_t ret = UG96_RECEIVE_RET_COM_ERR;
  int32_t  urc_retval = 0, rcvlen = 0;
  uint8_t *ptr = pdata;
  uint16_t parsedlen = 0;
  uint8_t parse_count;
  int16_t  qird_retval = 0;
  *Receivedlen = 0;
  if (Obj->SocketInfo[Socket].Type != UG96_TCP_CONNECTION)
  {
      return UG96_RECEIVE_RET_PARAM_ERR; 
  }
  if(Requestedlen <= UG96_RX_DATABUF_SIZE )
  {
    switch (Obj->SocketInfo[Socket].AccessMode) {
      case UG96_BUFFER_MODE:
#ifdef UG96_DBG
        printf("                UG96_ReceiveData() Requestedlen: %d \n", Requestedlen);
        printf("                UG96_ReceiveData() UnreadLength: %d \n", Obj->SocketInfo[Socket].UnreadLength);
        printf("                UG96_ReceiveData() ComulatedQirdData: %d \n", Obj->SocketInfo[Socket].ComulatedQirdData);
#endif
        if(Obj->SocketInfo[Socket].UartRemaining > 0)  
        {
#ifdef UG96_DBG
            printf("       **** UG96_ReceiveData() UartRemaining %d \n", Obj->SocketInfo[Socket].UartRemaining);
#endif
            rcvlen = AT_RetrieveData(Obj, ptr, Obj->SocketInfo[Socket].UartRemaining, RET_NONE, Timeout);
            Obj->SocketInfo[Socket].UartRemaining -= rcvlen;
            *Receivedlen = rcvlen;
            if (Obj->SocketInfo[Socket].UartRemaining == 0)
            {
              snprintf(CmdString,24,"AT+QIRD=%d,0\r\n", Socket);
              AT_ExecuteCommand(Obj, UG96_TOUT_300, (uint8_t *) CmdString, RET_ERROR | RET_READ);
              AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, UG96_TOUT_300);
              ParseQIRD((char *) Obj->CmdResp, &Obj->SocketInfo[Socket].ComulatedQirdData);
              ret = UG96_RECEIVE_RET_OK;
            }
            else
            {
              ret = UG96_RECEIVE_RET_INCOMPLETE; 
            }
            break;
        }
        if(Obj->SocketInfo[Socket].UnreadLength > 0)          
        {
          if(Requestedlen > Obj->SocketInfo[Socket].UnreadLength)
          {
            Requestedlen = Obj->SocketInfo[Socket].UnreadLength;    
          }
        }
        else
        {
          urc_retval = AT_RetrieveUrc(Obj, Timeout, &parsedlen, UG96_BUFFER_MODE );
#ifdef UG96_DBG
          if (urc_retval < 0)
          {
            printf("                             UG96_ReceiveData() URC not received\n");
          }
          else
          {
            printf("                UG96_ReceiveData() URC OK\n");
          }
#endif
        }
        snprintf(CmdString,24,"AT+QIRD=%d,%u\r\n", Socket, Requestedlen);
        qird_retval = AT_ExecuteCommand(Obj, UG96_TOUT_300, (uint8_t *) CmdString, RET_ERROR | RET_READ);
        if ((qird_retval < 0) || (qird_retval == RET_ERROR))
        {
#ifdef UG96_DBG
          printf("                             UG96_ReceiveData() QIRD issue\n");
#endif
          return UG96_RECEIVE_RET_COM_ERR;
        }
        AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, UG96_TOUT_300);
        parsedlen = (uint16_t) ParseNumber((char *) Obj->CmdResp, &parse_count);
#ifdef UG96_DBG
        if ((Obj->SocketInfo[Socket].UnreadLength > 0) && (parsedlen != Requestedlen))
        {
          printf("                             UG96_ReceiveData() unexpected behaviour parsedlen != Requestedlen (%u)\n", Requestedlen);
        }
        printf("                UG96_ReceiveData() parsedlen is %u\n", parsedlen);
#endif
        rcvlen = AT_RetrieveData(Obj, ptr, parsedlen, RET_NONE, Timeout);
        if (rcvlen < 0)
        {
          *Receivedlen = 0;
           break; 
        }
        if(rcvlen != parsedlen) 
        {
#ifdef UG96_DBG
          printf("                             UG96_ReceiveData() Received length mismatch!!!\n");
#endif
          Obj->SocketInfo[Socket].UartRemaining = parsedlen - rcvlen;
          Obj->SocketInfo[Socket].UnreadLength -= rcvlen;
          *Receivedlen = rcvlen;
          ret =  UG96_RECEIVE_RET_INCOMPLETE; 
        }
        else
        {
#ifdef UG96_DBG
          printf("                UG96_ReceiveData() Received  OK %ld \n", rcvlen);
#endif
          *Receivedlen = rcvlen;
          Obj->SocketInfo[Socket].UartRemaining = 0;
          AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_OK, UG96_TOUT_SHORT);
          snprintf(CmdString,24,"AT+QIRD=%d,0\r\n", Socket);
          AT_ExecuteCommand(Obj, UG96_TOUT_300, (uint8_t *) CmdString, RET_ERROR | RET_READ);
          AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, UG96_TOUT_300);
          ParseQIRD((char *) Obj->CmdResp, &Obj->SocketInfo[Socket].ComulatedQirdData);
          AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_OK, UG96_TOUT_SHORT);
          ret =  UG96_RECEIVE_RET_OK;
        }
        break;
    case UG96_DIRECT_PUSH:   
        if(Obj->RemainRxData > 0)   
        {
          if(Requestedlen <= Obj->RemainRxData)       
          {
            Obj->RemainRxData -= Requestedlen;
            if(AT_RetrieveData(Obj, ptr, Requestedlen, RET_NONE, Timeout) != Requestedlen)
            {
              return UG96_RECEIVE_RET_COM_ERR;
            }
            else
            {
              return UG96_RECEIVE_RET_OK;
            }
          }
          else                              
          {
            Requestedlen -= Obj->RemainRxData;
            if( AT_RetrieveData(Obj, ptr, Obj->RemainRxData, RET_NONE, Timeout) == Obj->RemainRxData)
            {
              ptr += Obj->RemainRxData;
              Obj->RemainRxData = 0;
            }
            else
            {
              return UG96_RECEIVE_RET_COM_ERR;
            }
          }
        }
        urc_retval = AT_RetrieveUrc(Obj, Timeout, &parsedlen, UG96_DIRECT_PUSH );
        if( urc_retval == RET_URC_RECV)
        {
          if(parsedlen > 0)
          {
            if(Requestedlen > parsedlen)    
            {
              Obj->RemainRxData = 0;
              Requestedlen = parsedlen;
            }
            else                      
            {
              Obj->RemainRxData = parsedlen - Requestedlen;
            }
            *Receivedlen = AT_RetrieveData(Obj, ptr, Requestedlen, RET_NONE, Timeout);
            if(*Receivedlen == Requestedlen)
            {
              ret = UG96_RECEIVE_RET_OK;
            }
          }
        }
        break;
      case UG96_TRANSPARENT_MODE:
        ret = UG96_RECEIVE_RET_PARAM_ERR;
        break;
    } 
  }
  else
  {
    ret = UG96_RECEIVE_RET_PARAM_ERR;
  }
  return ret;
}
UG96_ReceiveRet_t UG96_ReceiveData ( Ug96Object_t * Obj , uint8_t Socket , uint8_t * pdata , uint16_t Requestedlen , uint16_t * Receivedlen , uint32_t Timeout ) { UG96_ReceiveRet_t ret = UG96_RECEIVE_RET_COM_ERR ; int32_t urc_retval = 0 , rcvlen = 0 ; uint8_t * ptr = pdata ; uint16_t parsedlen = 0 ; uint8_t parse_count ; int16_t qird_retval = 0 ; * Receivedlen = 0 ; if ( Obj -> SocketInfo [ Socket ] . Type != UG96_TCP_CONNECTION ) { return UG96_RECEIVE_RET_PARAM_ERR ; } if ( Requestedlen <= UG96_RX_DATABUF_SIZE ) { switch ( Obj -> SocketInfo [ Socket ] . AccessMode ) { case UG96_BUFFER_MODE : #ifdef UG96_DBG printf ( " \n " , Requestedlen ) ; printf ( " \n " , Obj -> SocketInfo [ Socket ] . UnreadLength ) ; printf ( " \n " , Obj -> SocketInfo [ Socket ] . ComulatedQirdData ) ; #endif if ( Obj -> SocketInfo [ Socket ] . UartRemaining > 0 ) { #ifdef UG96_DBG printf ( " \n " , Obj -> SocketInfo [ Socket ] . UartRemaining ) ; #endif rcvlen = AT_RetrieveData ( Obj , ptr , Obj -> SocketInfo [ Socket ] . UartRemaining , RET_NONE , Timeout ) ; Obj -> SocketInfo [ Socket ] . UartRemaining -= rcvlen ; * Receivedlen = rcvlen ; if ( Obj -> SocketInfo [ Socket ] . UartRemaining == 0 ) { snprintf ( CmdString , 24 , " \r \n " , Socket ) ; AT_ExecuteCommand ( Obj , UG96_TOUT_300 , ( uint8_t * ) CmdString , RET_ERROR | RET_READ ) ; AT_RetrieveData ( Obj , Obj -> CmdResp , 0 , RET_CRLF , UG96_TOUT_300 ) ; ParseQIRD ( ( char * ) Obj -> CmdResp , & Obj -> SocketInfo [ Socket ] . ComulatedQirdData ) ; ret = UG96_RECEIVE_RET_OK ; } else { ret = UG96_RECEIVE_RET_INCOMPLETE ; } break ; } if ( Obj -> SocketInfo [ Socket ] . UnreadLength > 0 ) { if ( Requestedlen > Obj -> SocketInfo [ Socket ] . UnreadLength ) { Requestedlen = Obj -> SocketInfo [ Socket ] . UnreadLength ; } } else { urc_retval = AT_RetrieveUrc ( Obj , Timeout , & parsedlen , UG96_BUFFER_MODE ) ; #ifdef UG96_DBG if ( urc_retval < 0 ) { printf ( " \n " ) ; } else { printf ( " \n " ) ; } #endif } snprintf ( CmdString , 24 , " \r \n " , Socket , Requestedlen ) ; qird_retval = AT_ExecuteCommand ( Obj , UG96_TOUT_300 , ( uint8_t * ) CmdString , RET_ERROR | RET_READ ) ; if ( ( qird_retval < 0 ) || ( qird_retval == RET_ERROR ) ) { #ifdef UG96_DBG printf ( " \n " ) ; #endif return UG96_RECEIVE_RET_COM_ERR ; } AT_RetrieveData ( Obj , Obj -> CmdResp , 0 , RET_CRLF , UG96_TOUT_300 ) ; parsedlen = ( uint16_t ) ParseNumber ( ( char * ) Obj -> CmdResp , & parse_count ) ; #ifdef UG96_DBG if ( ( Obj -> SocketInfo [ Socket ] . UnreadLength > 0 ) && ( parsedlen != Requestedlen ) ) { printf ( " \n " , Requestedlen ) ; } printf ( " \n " , parsedlen ) ; #endif rcvlen = AT_RetrieveData ( Obj , ptr , parsedlen , RET_NONE , Timeout ) ; if ( rcvlen < 0 ) { * Receivedlen = 0 ; break ; } if ( rcvlen != parsedlen ) { #ifdef UG96_DBG printf ( " \n " ) ; #endif Obj -> SocketInfo [ Socket ] . UartRemaining = parsedlen - rcvlen ; Obj -> SocketInfo [ Socket ] . UnreadLength -= rcvlen ; * Receivedlen = rcvlen ; ret = UG96_RECEIVE_RET_INCOMPLETE ; } else { #ifdef UG96_DBG printf ( " \n " , rcvlen ) ; #endif * Receivedlen = rcvlen ; Obj -> SocketInfo [ Socket ] . UartRemaining = 0 ; AT_RetrieveData ( Obj , Obj -> CmdResp , 0 , RET_OK , UG96_TOUT_SHORT ) ; snprintf ( CmdString , 24 , " \r \n " , Socket ) ; AT_ExecuteCommand ( Obj , UG96_TOUT_300 , ( uint8_t * ) CmdString , RET_ERROR | RET_READ ) ; AT_RetrieveData ( Obj , Obj -> CmdResp , 0 , RET_CRLF , UG96_TOUT_300 ) ; ParseQIRD ( ( char * ) Obj -> CmdResp , & Obj -> SocketInfo [ Socket ] . ComulatedQirdData ) ; AT_RetrieveData ( Obj , Obj -> CmdResp , 0 , RET_OK , UG96_TOUT_SHORT ) ; ret = UG96_RECEIVE_RET_OK ; } break ; case UG96_DIRECT_PUSH : if ( Obj -> RemainRxData > 0 ) { if ( Requestedlen <= Obj -> RemainRxData ) { Obj -> RemainRxData -= Requestedlen ; if ( AT_RetrieveData ( Obj , ptr , Requestedlen , RET_NONE , Timeout ) != Requestedlen ) { return UG96_RECEIVE_RET_COM_ERR ; } else { return UG96_RECEIVE_RET_OK ; } } else { Requestedlen -= Obj -> RemainRxData ; if ( AT_RetrieveData ( Obj , ptr , Obj -> RemainRxData , RET_NONE , Timeout ) == Obj -> RemainRxData ) { ptr += Obj -> RemainRxData ; Obj -> RemainRxData = 0 ; } else { return UG96_RECEIVE_RET_COM_ERR ; } } } urc_retval = AT_RetrieveUrc ( Obj , Timeout , & parsedlen , UG96_DIRECT_PUSH ) ; if ( urc_retval == RET_URC_RECV ) { if ( parsedlen > 0 ) { if ( Requestedlen > parsedlen ) { Obj -> RemainRxData = 0 ; Requestedlen = parsedlen ; } else { Obj -> RemainRxData = parsedlen - Requestedlen ; } * Receivedlen = AT_RetrieveData ( Obj , ptr , Requestedlen , RET_NONE , Timeout ) ; if ( * Receivedlen == Requestedlen ) { ret = UG96_RECEIVE_RET_OK ; } } } break ; case UG96_TRANSPARENT_MODE : ret = UG96_RECEIVE_RET_PARAM_ERR ; break ; } } else { ret = UG96_RECEIVE_RET_PARAM_ERR ; } return ret ; }
@brief  Receive an amount data over C2C.
@brief Receive an amount data over C2C .
/* currently only TCP connection is implemented */ /* if Timeout respects UART speed this should never happen*/ /* update Obj->SocketInfo[Socket] and exit */ /* even this iteration was not sufficient to get all data from modem */ /* some data remaining from previous operation */ /* Just take the one to end remaining data */ /* Wait for parsing URC */ /* length parsing */ /* Retrieving data */ /* return UG96_RECEIVE_RET_COM_ERR */ /* uart has not retrieved all data from modem yet*/ /* if Timeout respects UART speed this should never happen*/ /* OK */ /* Update SocketInfo for next iteration*/ /* OK */ /* ******** Careful: NOT fully TESTED ******** */ /* some data remaining from previous operation */ /* in UG96_DIRECT_PUSH Requestedlen is the max the applic can receive */ /* all remaining data can be retried */ /* error */ /* retrieve all data */ /* not enough space in the applic buffer */ /* TBD */ /*end switch case */