Example #1
0
bool I2C::_MasterRead (uint8_t* data, uint32_t data_size, uint8_t slave_addr, uint8_t* reg_addr)
{
    if (!WaitStatus(I2C::BUSY, false))
    {
        //ClearBUSY();
        _stuckBUSY = true;
        return false;
    }
    

    if (reg_addr)
    {
        SendStart(true);

        if (!WaitStatus(I2C::MASTER_EV5, true)) //BSY MSL SB
            return false;

        Send7bitAddress(slave_addr, true);

        if (!WaitStatus(I2C::MASTER_EV6_TRA, true)) //MSL | BUSY | ADDR | TXE | TRA
            return false;

        SendByte(*reg_addr);

        if (!WaitStatus(I2C::MASTER_EV8_2, true))  //TRA, BUSY, MSL, TXE and BTF
            return false;

    }

    SendStart(true);

    if (!WaitStatus(I2C::MASTER_EV5, true)) //BSY MSL SB
        return false;

    Send7bitAddress(slave_addr, false);

    if (!WaitStatus(I2C::MASTER_EV6_RECV, true)) //MSL | BUSY | ADDR
        return false;

    if (data_size == 1)
    //if (false)
    {
        EnableACK(false);
        SendStop(true);

 //       if (!WaitStatus(I2C::MASTER_EV7, true))  //MSL | BUSY | ADDR
        if (!WaitStatus(I2C::RXNE, true))  //MSL | BUSY | ADDR
            return false;

        *data = ReceiveByte();

        EnableACK(true);
        return true;
    }
    else
    {
        return ReceiveDMA(data, data_size);
    }
}
Example #2
0
uint8_t i2c_t::CmdWriteRead(uint8_t Addr,
        uint8_t *WPtr, uint8_t WLength,
        uint8_t *RPtr, uint8_t RLength) {
    if(IBusyWait() != OK) return FAILURE;
    // Clear flags
    ii2c->SR1 = 0;
    while(RxIsNotEmpty()) (void)ii2c->DR;   // Read DR until it empty
    ClearAddrFlag();
    // Start transmission
    SendStart();
    if(WaitEv5() != OK) return FAILURE;
    SendAddrWithWrite(Addr);
    if(WaitEv6() != OK) { SendStop(); return FAILURE; }
    // Start TX DMA if needed
    if(WLength != 0) {
        if(WaitEv8() != OK) return FAILURE;
        dmaStreamSetMemory0(PDmaTx, WPtr);
        dmaStreamSetTransactionSize(PDmaTx, WLength);
        PRequestingThread = chThdSelf();
        dmaStreamEnable(PDmaTx);
        chSysLock();
        chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
        chSysUnlock();
        dmaStreamDisable(PDmaTx);
    }
    // Read if needed
    if(RLength != 0) {
        if(WaitEv8() != OK) return FAILURE;
        // Send repeated start
        SendStart();
        if(WaitEv5() != OK) return FAILURE;
        SendAddrWithRead(Addr);
        if(WaitEv6() != OK) { SendStop(); return FAILURE; }
        // If number of data to be read is 1, then DMA cannot be used
        if(RLength == 1) {
            AckDisable();
            SendStop();
            if(WaitRx() != OK) return FAILURE;
            *RPtr = ReceiveData();
            if(WaitStop() != OK) return FAILURE;
            return OK;
        }
        else {  // more than 1 byte, use DMA
            AckEnable();
            dmaStreamSetMemory0(PDmaRx, RPtr);
            dmaStreamSetTransactionSize(PDmaRx, RLength);
            DmaLastTransferSet(); // Inform DMA that this is last transfer => do not ACK last byte
            PRequestingThread = chThdSelf();
            dmaStreamEnable(PDmaRx);
            chSysLock();
            chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
            chSysUnlock();
            dmaStreamDisable(PDmaRx);
        } // if lng==1
    } // if != 0
    SendStop();
    return OK;
}
Example #3
0
uint8_t i2c_t::CmdWriteRead(uint8_t Addr,
        uint8_t *WPtr, uint8_t WLength,
        uint8_t *RPtr, uint8_t RLength) {
    if(IBusyWait() != OK) return FAILURE;
    // Clear flags
    ii2c->SR1 = 0;
    while(RxIsNotEmpty()) (void)ii2c->DR;   // Read DR until it empty
    ClearAddrFlag();
    // Start transmission
    SendStart();
    if(WaitEv5() != OK) return FAILURE;
    SendAddrWithWrite(Addr);
    if(WaitEv6() != OK) { SendStop(); return FAILURE; }
    ClearAddrFlag();
    // Start TX DMA if needed
    if(WLength != 0) {
        if(WaitEv8() != OK) return FAILURE;
        dmaStreamSetMemory0(PDmaTx, WPtr);
        dmaStreamSetMode   (PDmaTx, I2C_DMATX_MODE);
        dmaStreamSetTransactionSize(PDmaTx, WLength);
        chSysLock();
        PRequestingThread = chThdSelf();
        dmaStreamEnable(PDmaTx);
        chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
        chSysUnlock();
        dmaStreamDisable(PDmaTx);
    }
    // Read if needed
    if(RLength != 0) {
        if(WaitEv8() != OK) return FAILURE;
        // Send repeated start
        SendStart();
        if(WaitEv5() != OK) return FAILURE;
        SendAddrWithRead(Addr);
        if(WaitEv6() != OK) { SendStop(); return FAILURE; }
        // If single byte is to be received, disable ACK before clearing ADDR flag
        if(RLength == 1) AckDisable();
        else AckEnable();
        ClearAddrFlag();
        dmaStreamSetMemory0(PDmaRx, RPtr);
        dmaStreamSetMode   (PDmaRx, I2C_DMARX_MODE);
        dmaStreamSetTransactionSize(PDmaRx, RLength);
        DmaLastTransferSet(); // Inform DMA that this is last transfer => do not ACK last byte
        chSysLock();
        PRequestingThread = chThdSelf();
        dmaStreamEnable(PDmaRx);
        chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
        chSysUnlock();
        dmaStreamDisable(PDmaRx);
    } // if != 0
    else WaitBTF(); // if nothing to read, just stop
    SendStop();
    return OK;
}
Example #4
0
int RunAVRTool( unsigned char * motors )
{
	int adc;
	int ca = 0, cb = 0;
	int tries = 0;
retry:
	SendStart();
	ca |= SendByte( 0x20 );
	ca |= SendByte( 31 );

	//I have no idea why we have to do this.  If we don't have some extra 0's here, the motors will go crazy and the AVR will lose its mind.
	ca |= SendByte( 0x00 ); //unused.
	ca |= SendByte( 0x00 ); //unused.

	if( ca )
	{
		SendStop();
		tries++;
		ca = 0;
		if( tries < 3 )
			goto retry;
		return 2;
	}

	ca |= SendByte( motors[0] );
	ca |= SendByte( motors[1] );
	ca |= SendByte( motors[2] );
	ca |= SendByte( motors[3] );
	SendStop();


	SendStart();
	cb |= SendByte( 0x21 );
	adc = GetByte( 1 );
	SendStop();

	//1.1 / 5 * 256 = 56.32
	//56.32 / 1.1 = 5 * 256
	//(1.1*256) / (56.32) = 5
	//(1.1*256*5) / ADC = voltage in centivolts.

	//ADC = 1.1v reference with bus as reference.

	if( cb ) return 3;
	if( adc == 0xff || adc == 0 )
		return 1;
	else
		return 28444 / adc;
}
Example #5
0
/***************************************************************************
  Function:		TwiSendBytes(void)
  Description:	Sends the given number of bytes over TWI.
  Receives:		BYTE* bytesToSend		:		Pointer to an array with the bytes to send.
				BYTE numberOfBytes		:		Number of bytes to send.
  Returns:		Integer indicating success (0x00), timeout error (0x01) or TWI error (0x02).
***************************************************************************/
void TwiSendBytes(BYTE address, BYTE* bytesToSend, BYTE numberOfBytes)
{
	/* Check if TWI is initialized */
	if(twi.twiInitialized != TRUE)
		return;
		
	BYTE result = SUCCEEDED;
	
	/* Send start condition */
	result = SendStart();
	if(result != SUCCEEDED)
		return result;
		
	/* Send address of device */
	TransmitAddress(address);
	if(result != SUCCEEDED)
		return result;
	
	/* Send data bytes */
	for(int i = 0; i < numberOfBytes; i++)
	{
		result = SendData(bytesToSend[i]);
		if(result != SUCCEEDED)
			return result;
	}	
		
	/* Send stop condition */
	SendStop();
	if(result != SUCCEEDED)
		return result;
}
//-----------------------------------------------------------------------------
// main process
void
TestEndpointBridgeMainParent::Main()
{
  if (!SendStart()) {
    fail("sending Start");
  }
}
Example #7
0
bool twi::ReadBytes(U8 slave_address, U8 *bytes, U8 length)
{
  slave_address |= 0x01;
  _error_state = TWI_RESULT_OKAY;

  SendStart();
  
  if(!SetAddress(slave_address))
  {
    _error_state = TWI_RESULT_NO_ACK_ON_ADDRESS;
    return false;
  }
  
  do
  {
    SDA.set_input();
    *(bytes++)  = USI_TWI_Master_Transfer( true );
    //*(bytes++) = 0x22;
    
    if(length == 1)                            // If transmission of last byte was performed.
      SendNACK();
    else
      SendACK();
  }while(--length > 0);
  
  SendStop();

  return true;
}
Example #8
0
bool twi::WriteBytes(U8 slave_address, U8* bytes, U8 length)
{
  _error_state = TWI_RESULT_OKAY;

  SendStart();

  if(!SetAddress(slave_address))
  {
    _error_state = TWI_RESULT_NO_ACK_ON_ADDRESS;
    return false;
  }

  /*Write address and Read/Write data */
  do
  {
    /* Write a byte */
    PullPin(&SCL);
    USIDR = (*(bytes++));
    USI_TWI_Master_Transfer( true );    // Send 8 bits on bus.

    /* Clock and verify (N)ACK from slave */
    if(!ACK_received())
    {
      _error_state = TWI_RESULT_NO_ACK_ON_DATA;
      return false;
    }
  }while(--length > 0);
  
  SendStop();

  return true;
}
Example #9
0
//-----------------------------------------------------------------------------
// 伺服器處理執行
void C_XServer::ServerProc()
{
	m_ccKernal.BenchmarkProcStart();

	// 核心處理
	m_ccKernal.Process();

	// 新增連線處理
	for(unsigned long ulCount = m_ccListUnit.Size(), ulMax = m_ccKernal.SocketTotal(); ulCount < ulMax; ++ulCount)
		AcceptStart();

	// 開始接收/傳送處理
	for(const std::set<SOCKET>::value_type &Itor : m_ccListUnit.SocketProcess())
	{
		RecvStart(Itor);
		SendStart(Itor);
		NoticeStart(Itor);
	}//for

	// 開始斷線處理
	for(const std::set<SOCKET>::value_type &Itor : m_ccListUnit.SocketDisconnect())
		m_ccAPI.ReleaseSocket(Itor);

	m_ccKernal.BenchmarkProcEnd();
}
Example #10
0
void
TestDataStructuresParent::Main()
{
    for (uint32_t i = 0; i < nactors; ++i)
        if (!SendPTestDataStructuresSubConstructor(i))
            fail("can't alloc actor");

    if (!SendStart())
        fail("can't send Start()");
}
Example #11
0
int SetupAVRTool()
{
	int c = 0;

	SendStart();
	c |= SendByte( 0x20 );
	c |= SendByte( 0x01 );
	c |= SendByte( 0x00 );
	c |= SendByte( 0x00 );
	c |= SendByte( 0x00 );
	c |= SendByte( 0x00 );
	SendStop();

	return c;
}
void
TestNestedLoopsParent::Main()
{
    if (!SendStart())
        fail("sending Start");

    // sigh ... spin for a while to let Nonce arrive
    puts(" (sleeping to wait for nonce ... sorry)");
    PR_Sleep(5000);

    // while waiting for the reply to R, we'll receive Nonce
    if (!CallR())
        fail("calling R");

    Close();
}
bool STNetConnect::SendData( const unsigned char* pMsg, unsigned int uLength )
{
	try
	{
		unsigned char *ioBuf = NULL;
		uint32 nSendSize = 0;
		AutoLock lock(&m_sendMutex);//回复与主动通知存在并发send
		if ( 0 >= m_sendBuffer.GetLength() )//没有等待发送的数据,可直接发送
		{
			nSendSize = m_socket.Send( pMsg, uLength );
		}
		if ( -1 == nSendSize ) return false;//发生错误,连接可能已断开
		if ( uLength == nSendSize ) return true;//所有数据已发送,返回成功
		
		//数据加入发送缓冲,交给底层去发送
		uLength -= nSendSize;
		while ( true )
		{
			if ( uLength > BUFBLOCK_SIZE )
			{
				ioBuf = m_sendBuffer.PrepareBuffer( BUFBLOCK_SIZE );
				memcpy( ioBuf, &pMsg[nSendSize], BUFBLOCK_SIZE );
				m_sendBuffer.WriteFinished( BUFBLOCK_SIZE );
				nSendSize += BUFBLOCK_SIZE;
				uLength -= BUFBLOCK_SIZE;
			}
			else
			{
				ioBuf = m_sendBuffer.PrepareBuffer( uLength );
				memcpy( ioBuf, &pMsg[nSendSize], uLength );
				m_sendBuffer.WriteFinished( uLength );
				break;
			}
		}
		if ( !SendStart() ) return true;//已经在发送
		//发送流程开始
#ifdef WIN32
		m_pNetMonitor->AddSend( m_socket.GetSocket(), NULL, 0 );
#else
		//在STNetEngine::MsgWorker()中执行,一定是在RecvData()之后,所以绝对不会被
		//m_pNetMonitor->AddIO( m_socket.GetSocket(), true, false );覆盖,不会遗漏发送请求
		((STEpoll*)m_pNetMonitor)->AddIO( m_socket.GetSocket(), true, true );
#endif
	}
	catch(...){}
	return true;
}
Example #14
0
bool I2C::_MasterWrite (uint8_t* data, uint32_t data_size, uint8_t slave_addr, uint8_t* preg_addr)
{
    if (!WaitStatus(I2C::BUSY, false))
    {
        //ClearBUSY();
        _stuckBUSY= true;
        return false;
    }

    SendStart(true);

    if (!WaitStatus(I2C::MASTER_EV5, true))
        return false;

    Send7bitAddress(slave_addr, true);

    if (!WaitStatus(I2C::MASTER_EV6_TRA, true)) //MSL | BUSY | ADDR | TXE | TRA
        return false;

    ////////////////////////////////////////////////////////////////////////////
    if (preg_addr)
    {
        SendByte(*preg_addr);
        if (!WaitStatus(I2C::MASTER_EV8_2, true))  //TRA, BUSY, MSL, TXE and BTF
            return false;
    }
    ////////////////////////////////////////////////////////////////////////////

    if (data_size == 1)
    {
        SendByte(*data);

        if (!WaitStatus(I2C::MASTER_EV8, true))  //TRA, BUSY, MSL, TXE and BTF
            return false;

        SendStop(true);

        return true;

    }
    else
    {
        return SendDMA (data, data_size);
    }

}
Example #15
0
uint8_t i2cMgr_t::WriteRegPoll(uint8_t AI2CAddr, uint8_t ARegAddr, uint8_t AValue) {
    //Uart.Printf("i2c WriteReg Poll\r");
    if(BusyWait()) return I2C_ERR_TIMEOUT;
    uint8_t rslt;
    if ((rslt = SendStart()) == I2C_OK) {
        if((rslt = SendAddrTXPoll(AI2CAddr)) == I2C_OK) {
            // Send reg addr
            if((rslt = WriteBytePoll(ARegAddr)) == I2C_OK) {
                // Send data
                rslt = WriteBytePoll(AValue);
            }
        }
        I2C_GenerateSTOP(I2C1, ENABLE);
    }
    //if(rslt == I2C_OK) Uart.Printf("Done\r");
    return rslt;
}
bool NetConnect::SendData( const unsigned char* pMsg, unsigned int uLength )
{
	unsigned char *ioBuf = NULL;
	int nSendSize = 0;
	AutoLock lock(&m_sendMutex);//回复与主动通知存在并发send
	if ( 0 >= m_sendBuffer.GetLength() )//没有等待发送的数据,可直接发送
	{
		nSendSize = m_socket.Send( pMsg, uLength );
	}
	if ( Socket::seError == nSendSize ) return false;//发生错误,连接可能已断开
	if ( uLength == nSendSize ) return true;//所有数据已发送,返回成功
	
	//数据加入发送缓冲,交给底层去发送
	uLength -= nSendSize;
	while ( true )
	{
		if ( uLength > BUFBLOCK_SIZE )
		{
			ioBuf = m_sendBuffer.PrepareBuffer( BUFBLOCK_SIZE );
			memcpy( ioBuf, &pMsg[nSendSize], BUFBLOCK_SIZE );
			m_sendBuffer.WriteFinished( BUFBLOCK_SIZE );
			nSendSize += BUFBLOCK_SIZE;
			uLength -= BUFBLOCK_SIZE;
		}
		else
		{
			ioBuf = m_sendBuffer.PrepareBuffer( uLength );
			memcpy( ioBuf, &pMsg[nSendSize], uLength );
			m_sendBuffer.WriteFinished( uLength );
			break;
		}
	}
	if ( !SendStart() ) return true;//已经在发送
#ifdef WIN32
	IOCP_DATA iocpData;
	iocpData.connectId = m_id;
	iocpData.buf = NULL; 
	iocpData.bufSize = 0;
	return m_pNetMonitor->AddSend( m_socket.GetSocket(), (char*)&iocpData, sizeof(IOCP_DATA) );
#else
	return m_pNetMonitor->AddSend( m_socket.GetSocket(), (char*)&m_id, sizeof(int) );
#endif
	return true;
}
Example #17
0
uint8_t i2c_t::CmdWriteWrite(uint8_t Addr,
        uint8_t *WPtr1, uint8_t WLength1,
        uint8_t *WPtr2, uint8_t WLength2) {
    if(IBusyWait() != OK) return FAILURE;
    // Clear flags
    ii2c->SR1 = 0;
    while(RxIsNotEmpty()) (void)ii2c->DR;   // Read DR until it empty
    ClearAddrFlag();
    // Start transmission
    SendStart();
    if(WaitEv5() != OK) return FAILURE;
    SendAddrWithWrite(Addr);
    if(WaitEv6() != OK) { SendStop(); return FAILURE; }
    ClearAddrFlag();
    // Start TX DMA if needed
    if(WLength1 != 0) {
        if(WaitEv8() != OK) return FAILURE;
        dmaStreamSetMemory0(PDmaTx, WPtr1);
        dmaStreamSetMode   (PDmaTx, I2C_DMATX_MODE);
        dmaStreamSetTransactionSize(PDmaTx, WLength1);
        chSysLock();
        PRequestingThread = chThdSelf();
        dmaStreamEnable(PDmaTx);
        chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
        chSysUnlock();
        dmaStreamDisable(PDmaTx);
    }
    if(WLength2 != 0) {
        if(WaitEv8() != OK) return FAILURE;
        dmaStreamSetMemory0(PDmaTx, WPtr2);
        dmaStreamSetMode   (PDmaTx, I2C_DMATX_MODE);
        dmaStreamSetTransactionSize(PDmaTx, WLength2);
        chSysLock();
        PRequestingThread = chThdSelf();
        dmaStreamEnable(PDmaTx);
        chSchGoSleepS(THD_STATE_SUSPENDED); // Sleep until end
        chSysUnlock();
        dmaStreamDisable(PDmaTx);
    }
    WaitBTF();
    SendStop();
    return OK;
}
Example #18
0
U8 twi::USI_TWI_Start_Transceiver_With_Data(U8 address, U8 *msg, U8 msgSize, bool ReadNotWrite)
{
  if(ReadNotWrite)
    address |= 0x01;

  _error_state = TWI_RESULT_OKAY;

  SendStart();

  if(!SetAddress(address))
  {
    _error_state = TWI_RESULT_NO_ACK_ON_ADDRESS;
    return 0x01;
  }

  /*Write address and Read/Write data */
  do
  {
    if(ReadNotWrite)
    {
      ReadByte(msg++, msgSize == 1);
    }
    /* Else masterRead cycle*/
    else
    {
      if(!WriteByte(*(msg++)))
      {
        _error_state = TWI_RESULT_NO_ACK_ON_DATA;
        return 0x01;
      }
    }
  }while( --msgSize) ;                             // Until all data sent/received.
  
  SendStop();                           // Send a STOP condition on the TWI bus.

/* Transmission successfully completed*/
  return 0x00;
}
Example #19
0
void
TestHangsParent::Main()
{
    // Here we try to set things up to test the following sequence of events:
    //
    // - subprocess causes an OnMaybeDequeueOne() task to be posted to
    //   this thread
    //
    // - subprocess hangs just long enough for the hang timer to expire
    //
    // - hang-kill code in the parent starts running
    //
    // - subprocess replies to message while hang code runs
    //
    // - reply is processed in OnMaybeDequeueOne() before Close() has
    //   been called or the channel error notification has been posted

    // this tells the subprocess to send us Nonce()
    if (!SendStart())
        fail("sending Start");

    // now we sleep here for a while awaiting the Nonce() message from
    // the child.  since we're not blocked on anything, the IO thread
    // will enqueue an OnMaybeDequeueOne() task to process that
    // message
    // 
    // NB: PR_Sleep is exactly what we want, only the current thread
    // sleeping
    PR_Sleep(5000);

    // when we call into this, we'll pull the Nonce() message out of
    // the mPending queue, but that doesn't matter ... the
    // OnMaybeDequeueOne() event will remain
    if (CallStackFrame() && mDetectedHang)
        fail("should have timed out!");

    // the Close() task in the queue will shut us down
}
Example #20
0
void
TestRPCParent::Main()
{
  if (!SendStart())
    fail("sending Start");
}
Example #21
0
void
TestActorPunningParent::Main()
{
    if (!SendStart())
        fail("sending Start");
}
Example #22
0
// nsIStreamListener implementation
NS_IMETHODIMP
nsMultiMixedConv::OnDataAvailable(nsIRequest *request, nsISupports *context,
                                  nsIInputStream *inStr, uint64_t sourceOffset,
                                  uint32_t count) {
    nsresult rv = NS_OK;
    AutoFree buffer(nullptr);
    uint32_t bufLen = 0, read = 0;

    NS_ASSERTION(request, "multimixed converter needs a request");

    nsCOMPtr<nsIChannel> channel = do_QueryInterface(request, &rv);
    if (NS_FAILED(rv)) return rv;

    // fill buffer
    {
        bufLen = count + mBufLen;
        NS_ENSURE_TRUE((bufLen >= count) && (bufLen >= mBufLen),
                       NS_ERROR_FAILURE);
        buffer = (char *) malloc(bufLen);
        if (!buffer)
            return NS_ERROR_OUT_OF_MEMORY;

        if (mBufLen) {
            // incorporate any buffered data into the parsing
            memcpy(buffer, mBuffer, mBufLen);
            free(mBuffer);
            mBuffer = 0;
            mBufLen = 0;
        }
        
        rv = inStr->Read(buffer + (bufLen - count), count, &read);

        if (NS_FAILED(rv) || read == 0) return rv;
        NS_ASSERTION(read == count, "poor data size assumption");
    }

    char *cursor = buffer;

    if (mFirstOnData) {
        // this is the first OnData() for this request. some servers
        // don't bother sending a token in the first "part." This is
        // illegal, but we'll handle the case anyway by shoving the
        // boundary token in for the server.
        mFirstOnData = false;
        NS_ASSERTION(!mBufLen, "this is our first time through, we can't have buffered data");
        const char * token = mToken.get();

        PushOverLine(cursor, bufLen);

        bool needMoreChars = bufLen < mTokenLen + 2;
        nsAutoCString firstBuffer(buffer, bufLen);
        int32_t posCR = firstBuffer.Find("\r");

        if (needMoreChars || (posCR == kNotFound)) {
            // we don't have enough data yet to make this comparison.
            // skip this check, and try again the next time OnData()
            // is called.
            mFirstOnData = true;
        } else if (mPackagedApp) {
            // We need to check the line starts with --
            if (!StringBeginsWith(firstBuffer, NS_LITERAL_CSTRING("--"))) {
                return NS_ERROR_FAILURE;
            }

            // If the boundary was set in the header,
            // we need to check it matches with the one in the file.
            if (mTokenLen &&
                !StringBeginsWith(Substring(firstBuffer, 2), mToken)) {
                return NS_ERROR_FAILURE;
            }

            // Save the token.
            if (!mTokenLen) {
                mToken = nsCString(Substring(firstBuffer, 2).BeginReading(),
                                   posCR - 2);
                mTokenLen = mToken.Length();
            }

            cursor = buffer;
        } else if (!PL_strnstr(cursor, token, mTokenLen + 2)) {
            char *newBuffer = (char *) realloc(buffer, bufLen + mTokenLen + 1);
            if (!newBuffer)
                return NS_ERROR_OUT_OF_MEMORY;
            buffer = newBuffer;

            memmove(buffer + mTokenLen + 1, buffer, bufLen);
            memcpy(buffer, token, mTokenLen);
            buffer[mTokenLen] = '\n';

            bufLen += (mTokenLen + 1);

            // need to reset cursor to the buffer again (bug 100595)
            cursor = buffer;
        }
    }

    char *token = nullptr;

    // This may get initialized by ParseHeaders and the resulting
    // HttpResponseHead will be passed to nsPartChannel by SendStart

    if (mProcessingHeaders) {
        // we were not able to process all the headers
        // for this "part" given the previous buffer given to 
        // us in the previous OnDataAvailable callback.
        bool done = false;
        rv = ParseHeaders(channel, cursor, bufLen, &done);
        if (NS_FAILED(rv)) return rv;

        if (done) {
            mProcessingHeaders = false;
            rv = SendStart(channel);
            if (NS_FAILED(rv)) return rv;
        }
    }

    int32_t tokenLinefeed = 1;
    while ( (token = FindToken(cursor, bufLen)) ) {

        if (((token + mTokenLen) < (cursor + bufLen)) &&
            (*(token + mTokenLen + 1) == '-')) {
            // This was the last delimiter so we can stop processing
            rv = SendData(cursor, LengthToToken(cursor, token));
            if (NS_FAILED(rv)) return rv;
            if (mPartChannel) {
                mPartChannel->SetIsLastPart();
            }
            return SendStop(NS_OK);
        }

        if (!mNewPart && token > cursor) {
            // headers are processed, we're pushing data now.
            NS_ASSERTION(!mProcessingHeaders, "we should be pushing raw data");
            rv = SendData(cursor, LengthToToken(cursor, token));
            bufLen -= token - cursor;
            if (NS_FAILED(rv)) return rv;
        }
        // XXX else NS_ASSERTION(token == cursor, "?");
        token += mTokenLen;
        bufLen -= mTokenLen;
        tokenLinefeed = PushOverLine(token, bufLen);

        if (mNewPart) {
            // parse headers
            mNewPart = false;
            cursor = token;
            bool done = false; 
            rv = ParseHeaders(channel, cursor, bufLen, &done);
            if (NS_FAILED(rv)) return rv;
            if (done) {
                rv = SendStart(channel);
                if (NS_FAILED(rv)) return rv;
            }
            else {
                // we haven't finished processing header info.
                // we'll break out and try to process later.
                mProcessingHeaders = true;
                break;
            }
        }
        else {
            mNewPart = true;
            // Reset state so we don't carry it over from part to part
            mContentType.Truncate();
            mContentLength = UINT64_MAX;
            mContentDisposition.Truncate();
            mIsByteRangeRequest = false;
            mByteRangeStart = 0;
            mByteRangeEnd = 0;
            
            rv = SendStop(NS_OK);
            if (NS_FAILED(rv)) return rv;
            // reset the token to front. this allows us to treat
            // the token as a starting token.
            token -= mTokenLen + tokenLinefeed;
            bufLen += mTokenLen + tokenLinefeed;
            cursor = token;
        }
    }

    // at this point, we want to buffer up whatever amount (bufLen)
    // we have leftover. However, we *always* want to ensure that
    // we buffer enough data to handle a broken token.

    // carry over
    uint32_t bufAmt = 0;
    if (mProcessingHeaders)
        bufAmt = bufLen;
    else if (bufLen) {
        // if the data ends in a linefeed, and we're in the middle
        // of a "part" (ie. mPartChannel exists) don't bother
        // buffering, go ahead and send the data we have. Otherwise
        // if we don't have a channel already, then we don't even
        // have enough info to start a part, go ahead and buffer
        // enough to collect a boundary token.
        if (!mPartChannel || !(cursor[bufLen-1] == nsCRT::LF) )
            bufAmt = std::min(mTokenLen - 1, bufLen);
    }

    if (bufAmt) {
        rv = BufferData(cursor + (bufLen - bufAmt), bufAmt);
        if (NS_FAILED(rv)) return rv;
        bufLen -= bufAmt;
    }

    if (bufLen) {
        rv = SendData(cursor, bufLen);
        if (NS_FAILED(rv)) return rv;
    }

    return rv;
}
void
TestInterruptShutdownRaceParent::Main()
{
    if (!SendStart())
        fail("sending Start");
}
Example #24
0
//-----------------------------------------------------------------------------
// main process
void
TestBridgeMainParent::Main()
{
    if (!SendStart())
        fail("sending Start");
}
void
TestRacyUndeferParent::Main()
{
    if (!SendStart())
        fail("sending Start");
}
Example #26
0
//-----------------------------------------------------------------------------
// parent
void
TestRPCRacesParent::Main()
{
    SendStart();
}
Example #27
0
void
TestStackHooksParent::Main()
{
    if (!SendStart())
        fail("sending Start()");
}
Example #28
0
void i2cMgr_t::Task() {
    if (IsError) {
        Init();
        return;
    }
    uint8_t IEvt;
    switch (CmdToRead->State) {
        case CmdPending:
            if (SendStart() == I2C_OK) {    // Send Start
                // Send Addr of needed type
                if (CmdToRead->DataToWrite.Length != 0) {
                    SendAddrTX();
                    CmdToRead->State = CmdWritingAddrTX;
                }
                else {  // nothing to write
                    CmdToRead->State = CmdSucceded;
                    StopAndGetNext();
                }
            } // if start
            else {
                Uart.Printf("I2C Start failed\r");
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
            }
            break;

        // ****** Writing Address with TX bit *******
        case CmdWritingAddrTX:
            IEvt = CheckAddrTXSending();        // Check if ok
            if (IEvt == I2C_OK) {               // Addr sent, write data
                if (CmdToRead->DataToWrite.Length == 1) {   // Single byte to write
                    WriteOneByte();
                    CmdToRead->State = CmdWritingOne;
                }
                else {  // Many bytes to write
                    WriteMany();
                    CmdToRead->State = CmdWritingMany;
                }
            }
            else if (IEvt != I2C_WAITING) { // Some error occured
                if (IEvt == I2C_ERR_TIMEOUT) Uart.Printf("I2C Addr TX timeout\r");
                else if (IEvt == I2C_ERR_SLAVE_NACK) Uart.Printf("I2C NACK\r");
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
            }
            break;  // Otherwise still sending address

        case CmdWritingOne: // ****** Writing one byte *******
            IEvt = CheckOneByteWriting();
            if (IEvt == I2C_OK) {               // Byte sent, check if reading needed
                if (CmdToRead->DataToRead.Length != 0) {    // Send RepeatedStart
                    if (SendStart() == I2C_OK) {
                        SendAddrRX();
                        CmdToRead->State = CmdWritingAddrRX;
                    }
                    else {  // Repeated start failed
                        CmdToRead->State = CmdFailed;
                        StopAndGetNext();
                        Uart.Printf("I2C OneByte RS failed\r");
                    }
                }
                else {  // nothing to read
                    CmdToRead->State = CmdSucceded;
                    StopAndGetNext();
                    Uart.Printf("I2C OneByte no read\r");
                }
            } //
            else if (IEvt != I2C_WAITING) { // Some error occured
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
                Uart.Printf("I2C OneByte timeout\r");
            }
            break;  // Otherwise still sending byte

        // ****** Writing Address with RX bit *******
        case CmdWritingAddrRX:
            IEvt = CheckAddrRXSending();        // Check if ok
            if (IEvt == I2C_OK) {               // Addr sent, read data
                if (CmdToRead->DataToRead.Length == 1) {   // Single byte to read
                    ReadOneByte();
                    CmdToRead->State = CmdReadingOne;
                }
                else {  // Many bytes to read
                    ReadMany();
                    CmdToRead->State = CmdReadingMany;
                }
            }
            else if (IEvt != I2C_WAITING) { // Some error occured
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
                Uart.Printf("I2C Addr RX timeout\r");
            }
            break;  // Otherwise still sending address

        case CmdReadingOne: // ****** Reading one byte *******
            IEvt = CheckOneByteReading();
            if (IEvt == I2C_OK) {               // Byte read
                CmdToRead->State = CmdSucceded;
                GetNext();  // No need to send stop as it sent automatically
            }
            else if (IEvt != I2C_WAITING) { // Some error occured
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
            }
            break;  // Otherwise still reading byte

        case CmdWritingMany: // ****** Writing many bytes *******
            IEvt = CheckManyWriting();
            if (IEvt == I2C_OK) {               // Bytes sent, check if reading needed
                if (CmdToRead->DataToRead.Length != 0) {    // Send RepeatedStart and address RX
                    if (SendStart() == I2C_OK) {            // Send Start
                        SendAddrRX();
                        CmdToRead->State = CmdWritingAddrRX;
                    }
                    else {  // Repeated start failed
                        CmdToRead->State = CmdFailed;
                        StopAndGetNext();
                    }
                }
                else {  // nothing to read
                    CmdToRead->State = CmdSucceded;
                    StopAndGetNext();
                }
            } //
            else if (IEvt != I2C_WAITING) { // Some error occured
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
            }
            break;  // Otherwise still sending bytes

        case CmdReadingMany: // ****** Reading many bytes *******
            IEvt = CheckManyReading();
            if (IEvt == I2C_OK) {               // Byte read
                CmdToRead->State = CmdSucceded;
                StopAndGetNext();
            }
            else if (IEvt != I2C_WAITING) { // Some error occured
                CmdToRead->State = CmdFailed;
                StopAndGetNext();
                Uart.Printf("I2C ReadMany timeout\r");
            }
            break;  // Otherwise still reading bytes

        case CmdFailed:
        case CmdSucceded:
            GetNext();
            break;
    } // switch
}
Example #29
0
void
TestUrgencyParent::Main()
{
  if (!SendStart())
    fail("sending Start");
}
Example #30
0
uint8_t i2cMgr_t::CmdPoll(I2C_Cmd_t ACmd) {
	//Uart.Printf("i2c Cmd Poll\r");
    if(ACmd.StateReport != 0) *ACmd.StateReport = CmdFailed;
	if(BusyWait()) return I2C_ERR_TIMEOUT;
	if(ACmd.DataToWrite.Length == 0) return I2C_OK;
	uint8_t rslt=I2C_ERR_TIMEOUT;
    uint32_t IEvt, ITimeout;
    uint8_t i, b;
	// ==== First stage ====
    //Uart.Printf("i2c write: %A\r", ACmd.DataToWrite.Buf, ACmd.DataToWrite.Length);
	if ((rslt = SendStart()) == I2C_OK) {
		rslt = SendAddrTXPoll(ACmd.Address);
		for(i=0; (i < ACmd.DataToWrite.Length) and (rslt == I2C_OK); i++) {
		    b = ACmd.DataToWrite.Buf[i];
			//Uart.Printf("%X\r", b);
		    rslt = WriteBytePoll(b);
		} // while

		// ==== Second stage ====
		if((ACmd.DataToRead.Length != 0) and (rslt == I2C_OK)) {
			//Uart.Printf("i2c read %u\r", ACmd.DataToRead.Length);
			if((rslt = SendStart()) == I2C_OK) {
				if((rslt = SendAddrRXPoll(ACmd.Address)) == I2C_OK) {
					// Act accordingly to number of bytes to receive
					if(ACmd.DataToRead.Length == 1) {		// 1 byte to read
						I2C_AcknowledgeConfig(I2C1, DISABLE);
						I2C_GenerateSTOP(I2C1, ENABLE);
						// Wait for the byte to be received
						ITimeout = I2C_TIMEOUT;
						while(1) {	// Check if received
							IEvt = I2C_GetLastEvent(I2C1);
							if(IEvt == I2C_EVENT_MASTER_BYTE_RECEIVED) {
								ACmd.DataToRead.Buf[0] = I2C_ReceiveData(I2C1);
								break;
							}
							if(ITimeout-- == 0) {
								rslt = I2C_ERR_TIMEOUT;
								break;
							}
						} // while
					} // if 1
					else if(ACmd.DataToRead.Length == 2) {	// 2 bytes to read
						I2C_AcknowledgeConfig(I2C1, DISABLE);
						// Wait for the two bytes to be received
						ITimeout = I2C_TIMEOUT;
						while(1) {
							IEvt = I2C_GetLastEvent(I2C1);
							if(IEvt & I2C_FLAG_BTF) {
								I2C_GenerateSTOP(I2C1, ENABLE);
								ACmd.DataToRead.Buf[0] = I2C_ReceiveData(I2C1);
								ACmd.DataToRead.Buf[1] = I2C_ReceiveData(I2C1);
								break;
							}
							if(ITimeout-- == 0) {
								rslt = I2C_ERR_TIMEOUT;
								break;
							}
						} // while
					}
					else {	// many bytes to read
						I2C_AcknowledgeConfig(I2C1, ENABLE);
						i = 0;
						while((i < ACmd.DataToRead.Length) and (rslt == I2C_OK)) {
							ITimeout = I2C_TIMEOUT;
							while(1) {
								IEvt = I2C_GetLastEvent(I2C1);
								if(i == ACmd.DataToRead.Length-3) {	// Catch BTF
									if(IEvt & I2C_FLAG_BTF) {
										__disable_irq();
										I2C_AcknowledgeConfig(I2C1, DISABLE);
										ACmd.DataToRead.Buf[i] = I2C_ReceiveData(I2C1);
										I2C_GenerateSTOP(I2C1, ENABLE);
										i++;
										ACmd.DataToRead.Buf[i] = I2C_ReceiveData(I2C1);
										__enable_irq();
										break;
									}
								}
								else if(IEvt & I2C_FLAG_RXNE) {
									ACmd.DataToRead.Buf[i] = I2C_ReceiveData(I2C1);
									break;
								}

								if(ITimeout-- == 0) {
									rslt = I2C_ERR_TIMEOUT;
									break;
								}
							} // while 1
							i++;
						} // while
					} // many bytes to read
				} // Send addr
			} // send repstart
		} // if second stage

		else {	// only write operation (or failure), generate Stop
			//Uart.Printf("st\r");
			I2C_GenerateSTOP(I2C1, ENABLE);
		}
	} // if start
    if((rslt == I2C_OK) and (ACmd.StateReport != 0)) *ACmd.StateReport = CmdSucceded;
    //if(rslt == I2C_OK) Uart.Printf("Done\r");
	return rslt;
}