Open iceman1001 opened 6 years ago
@michaelneurohr, can you verify? I agree with @iceman1001 that this line looks fishy.
Forget my link to JohnMcLer, that was me trying to find the method via google. Instead I extracted the source for NFC-Reader-Library-4.010-2.deb package.
phStatus_t phbalReg_Stub_Exchange(
phbalReg_Stub_DataParams_t * pDataParams,
uint16_t wOption,
uint8_t * pTxBuffer,
uint16_t wTxLength,
uint16_t wRxBufSize,
uint8_t * pRxBuffer,
uint16_t * pRxLength
)
{
int ret = 0;
size_t pos = 0;
if( (pDataParams->bMultiRegRW == PH_ON) && ( pDataParams->wHalType != PHBAL_REG_HAL_HW_PN5180 ) )
{
//"Fast" bundled exchange for EMVCo compatibility -- only necessary for PN512/RC663 derivatives
if( wTxLength < 1 )
{
return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_BAL);
}
if( ((pDataParams->wHalType == PHBAL_REG_HAL_HW_RC663)
&& ( (pTxBuffer[0] & 0x01) == 0x01 ))
|| ((pDataParams->wHalType == PHBAL_REG_HAL_HW_RC523)
&& ( (pTxBuffer[0] & 0x80) == 0x80 )) )
{
//Perform a "MultiRegRead" exchange
//This is a read operation
ret = spi_transfer(pTxBuffer, pRxBuffer, wTxLength);
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERFACE_ERROR, PH_COMP_BAL);
}
if( pRxLength != NULL )
{
*pRxLength = wTxLength;
}
return PH_ERR_SUCCESS;
}
else if( (pDataParams->wHalType == PHBAL_REG_HAL_HW_RC663)
&& ( (pTxBuffer[0] & 0x01) == 0x00 ) )
{
//Perform a "MultiRegWrite" exchange
if( (wTxLength % 2) != 0 )
{
return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_BAL);
}
while( pos < wTxLength )
{
ret = spi_transfer(pTxBuffer, NULL, 2);
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERFACE_ERROR, PH_COMP_BAL);
}
pTxBuffer += 2;
pos += 2;
}
if( pRxLength != NULL )
{
*pRxLength = 0;
}
return PH_ERR_SUCCESS;
}
}
//Standard exchange
if( pDataParams->wHalType == PHBAL_REG_HAL_HW_PN5180 )
{
//If PN5180, wait for busy line to be released
ret = wait_not_busy();
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_BAL);
}
//Transmit first
ret = spi_transfer(pTxBuffer, NULL, wTxLength);
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERFACE_ERROR, PH_COMP_BAL);
}
//Receive response
if( pRxBuffer != NULL )
{
//Wait again
ret = wait_not_busy();
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERNAL_ERROR, PH_COMP_BAL);
}
ret = spi_transfer(NULL, pRxBuffer, wRxBufSize);
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERFACE_ERROR, PH_COMP_BAL);
}
if( pRxLength != NULL )
{
*pRxLength = wRxBufSize;
}
}
}
else
{
//Transfer everything at once
ret = spi_transfer(pTxBuffer, pRxBuffer, wTxLength);
if(ret)
{
return PH_ADD_COMPCODE(PH_ERR_INTERFACE_ERROR, PH_COMP_BAL);
}
if( pRxLength != NULL )
{
*pRxLength = wTxLength;
}
}
return PH_ERR_SUCCESS;
}
The bug is triggered in my stress tests, when sending a select/write sequence in a loop with a sleep 1sec each iteration. It takes around 240-320 times before triggered. If the loop has a sleep for two seconds or more the loop can run to 3000 times at least.
Could it be spi transfer being called too fast?
Please answer these questions as part of your new issue.
Which version of Python are you using?
v2.7
Which OS and version are you running?
PI
Is SPI enabled?
yes
Are you trying to read/write a Mifare Classic card? (This is currently unsupported)
no
There seems to be a bug in the NxpLib.
https://github.com/JohnMcLear/NXP-Raspberry-Pi-Card-Polling-Demo/blob/master/source/NxpRdLib_PublicRelease/comps/phbalReg/src/R_Pi_spi/phbalReg_R_Pi_spi.c#L319
The source here, seems to be using the same buffer TX and RX
spi.tx_buf = (unsigned long)pTxBuffer ; spi.rx_buf = (unsigned long)pTxBuffer ;
-- gdb trace.
Thread 1 "python" received signal SIGSEGV, Segmentation fault. 0x76aa47e8 in phbalReg_Stub_Exchange () from /home/pi/.local/lib/python2.7/site-packages/nxppy.so (gdb) bt
0 0x76aa47e8 in phbalReg_Stub_Exchange ()
from /home/pi/.local/lib/python2.7/site-packages/nxppy.so
1 0x76a9127c in phhalHw_Rc523_ReadRegister ()
from /home/pi/.local/lib/python2.7/site-packages/nxppy.so
2 0x76a8e2e0 in phhalHw_Rc523_FieldOff ()
from /home/pi/.local/lib/python2.7/site-packages/nxppy.so
3 0x76a7fad0 in Mifare_select (self=0x3d7368) at Mifare.c:289
4 0x0008be70 in PyEval_EvalFrameEx ()
5 0x00084494 in PyEval_EvalCodeEx ()
6 0x0008c8dc in PyEval_EvalFrameEx ()
7 0x0008c7d0 in PyEval_EvalFrameEx ()
8 0x0008c7d0 in PyEval_EvalFrameEx ()
9 0x00084494 in PyEval_EvalCodeEx ()
10 0x000841f8 in PyEval_EvalCode ()
11 0x000bd8b8 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)