CAN bus receiver don't receive - c

I am working with a PIC32MX795F512L. With below code I can transmit but cannot receive. How can it be possible I can transmit but I cannot receive? Any suggestions will be appreciated.
Here is the init code:
void CAN1Init(void) {
CAN_BIT_CONFIG canBitConfig;
UINT baudPrescalar;
PORTSetPinsDigitalIn(IOPORT_F, BIT_0);
PORTSetPinsDigitalOut(IOPORT_F, BIT_1);
// ODCFSET = BIT_1;
// change the CAN1 RX register from anlog to digital
// PORTSetPinsDigitalIn(IOPORT_F, BIT_0);
// PORTSetPinsDigitalOut(IOPORT_F, BIT_1);
CANEnableModule(CAN1, TRUE);
// Set the CAN_en pin to low, which is at RC3
mPORTCClearBits(BIT_3);
PORTSetPinsDigitalOut(IOPORT_C, BIT_3);
CANSetOperatingMode(CAN1, CAN_CONFIGURATION);
while (CANGetOperatingMode(CAN1) != CAN_CONFIGURATION);
canBitConfig.phaseSeg2Tq = CAN_BIT_3TQ;
canBitConfig.phaseSeg1Tq = CAN_BIT_3TQ;
canBitConfig.propagationSegTq = CAN_BIT_3TQ;
canBitConfig.phaseSeg2TimeSelect = TRUE;
canBitConfig.sample3Time = TRUE;
canBitConfig.syncJumpWidth = CAN_BIT_2TQ;
// baudPrescalar = CANCalcBitClockPrescalar(&canBitConfig,80000000,250000);
CANSetSpeed(CAN1, & canBitConfig, SYS_FREQ, CAN_BUS_SPEED);
/* Step 3: Assign the buffer area to the
* CAN module.
*/
CANAssignMemoryBuffer(CAN1, CAN1MessageFifoArea, (2 * 8 * 16));
CANConfigureChannelForTx(CAN1, CAN_CHANNEL0, 8, CAN_TX_RTR_DISABLED, CAN_LOW_MEDIUM_PRIORITY);
CANConfigureChannelForRx(CAN1, CAN_CHANNEL1, 8, CAN_RX_FULL_RECEIVE);
//CANConfigureFilter (CAN1, CAN_FILTER0, 0x000, CAN_SID);
//CANConfigureFilterMask (CAN1, CAN_FILTER_MASK0, 0x7FF, CAN_SID, CAN_FILTER_MASK_IDE_TYPE);
// CANLinkFilterToChannel (CAN1, CAN_FILTER0, CAN_FILTER_MASK0, CAN_CHANNEL1);
// CANEnableFilter (CAN1, CAN_FILTER0, TRUE);
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
CANEnableModuleEvent(CAN1, CAN_RX_EVENT, TRUE);
INTSetVectorPriority(INT_CAN_1_VECTOR, INT_PRIORITY_LEVEL_4);
INTSetVectorSubPriority(INT_CAN_1_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
INTEnable(INT_CAN1, INT_ENABLED);
/* Step 7: Switch the CAN mode
* to normal mode. */
CANSetOperatingMode(CAN1, CAN_NORMAL_OPERATION);
mPORTEToggleBits(BIT_6 | BIT_7);
while (CANGetOperatingMode(CAN1) != CAN_NORMAL_OPERATION);
CANSetTimeStampValue(CAN1, 0x00);
printf("CAN BUS is working\n");
}
Edit: main part of the code:
void RxMsgProcess(void)
{
if(isCAN1MsgReceived == FALSE) // This flag to make sure there is an interrupt from receiving a new message, if it's true then there are new packet
{
return;
}
isCAN1MsgReceived = FALSE;
CANRxMessageBuffer * message2;
message2 = CANGetRxMessage(CAN1,CAN_CHANNEL1);
printf(" received\n");
CANUpdateChannel(CAN1, CAN_CHANNEL1);
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, TRUE);
}
void __attribute__((vector(46), interrupt(ipl4), nomips16)) CAN1InterruptHandler(void)
{
/* Check if the source of the interrupt is
* RX_EVENT. This is redundant since only this
* event is enabled in this example but
* this shows one scheme for handling events. */
if((CANGetModuleEvent(CAN1) & CAN_RX_EVENT) != 0)
{
/* Within this, you can check which channel caused the
* event by using the CANGetModuleEvent() function
* which returns a code representing the highest priority
* pending event. */
if(CANGetPendingEventCode(CAN1) == CAN_CHANNEL1_EVENT)
{
CANEnableChannelEvent(CAN1, CAN_CHANNEL1, CAN_RX_CHANNEL_NOT_EMPTY, FALSE);
isCAN1MsgReceived = TRUE;
}
}
INTClearFlag(INT_CAN1);
}

Related

How do I copy values from one integer array into another integer array using only the keyboard to fill them?

I am trying to store values received from a non-blocking UART protocol. I enter characters from my keyboard and they are stored in an array called buffer that holds the value. I then want to fill a new array called newbuffer using the value from buffer array and then clear the value in buffer array so it is ready to receive another value from the keyboard.
Here is my initialization:
uint8_t buffer[2] = {0}; //initialize array for receiving keyboard input
uint8_t newbuffer[256] = {0}; //initialize array to store keyboard input from buffer array
int i = 0; //array index variable
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
Here is the callback routine after I have entered my first character. I could really use some help with this part!!!
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
for (i = 0; i < sizeof(newbuffer); i++)
{
newbuffer[i] = buffer[0]; //put value entered from keyboard into newbuffer array
memset(buffer, 0, sizeof(buffer)); //clear buffer array for next value
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
}
printf("%d", newbuffer);
}
This is the interrupt function for getting keyboard values, in case you need to see that.
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t *tmp;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if (huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t *) huart->pRxBuffPtr;
if (huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2U;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1U;
}
}
else
{
if (huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Rx complete callback*/
huart->RxCpltCallback(huart);
#else
/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
THANKS IN ADVANCE :)
Have you realized that you are copying exactly 1 byte in the for loop inside HAL_UART_RxCpltCallback, whereas array buffer is two bytes in size ?
This sentence: newbuffer[i] = buffer[0]; is just copying the first byte.
If you are reading from the keyboard you are probably getting scan codes. Scan codes are not all one byte, but many of them. Depending on the keys they can be up to three bytes: https://en.wikipedia.org/wiki/Scancode.
I solved the problem. The issue was with having the logic in a for loop. Since the size of newbuffer is 256, the program would not exit the for loop unless all of the characters had been entered and newbuffer was full. By taking my logic out of the for loop, the function could complete and return to main to be recalled in the main loop when the next character was entered.
I also added a flag variable so that I can print the string that was entered when the user types the carriage return button.
Receive Callback Routine:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//Prevent unused argument(s) compilation warning
UNUSED(huart);
newbuffer[i] = buffer[0] //put value entered from keyboard into newbuffer array
if (newbuffer[i] == '\r') //if user enters a carriage return the input will be flagged and trigger the while loop to print the string
{
flag = 1;
}
else
{
flag = 0;
}
memset(buffer, 0, sizeof(buffer)); //clear buffer array to receive next keyboard value
i++; //increment newbuffer index
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call interrupt that handles entering keyboard values
Main:
int main(void)
{
HAL_Init();
/* Configure the system clock to 180 MHz */
SystemClock_Config();
/* Initialize BSP Led for LED2 */
BSP_LED_Init(LED2);
UartHandle.Instance = USARTx;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_9B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_EVEN;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
NVIC_SetPriority(USART3_IRQn, (1u << __NVIC_PRIO_BITS) - 5u); //set interrupt priority
NVIC_EnableIRQ(USART3_IRQn);
/*INTERRUPT METHOD*/
HAL_UART_Receive_IT (&UartHandle, buffer, 1); //call UART receive interrupt to get keyboard input
//Infinite loop
while (1)
{
//output a message in Hyperterminal requesting keyboard input
printf("\n\rEnter your string: ");
NVIC_DisableIRQ(USART3_IRQn);
if (flag == 1)
{
printf("%s", newbuffer); //string is printed if user enters a carriage return
flag = 0; //reset flag so the interrupt routine can look for another carriage return
memset(newbuffer, 0, sizeof(newbuffer)); //clear newbuffer so it is ready to store a new string
i = 0; //reset index so newbuffer begins storing its new string starting at newbuffer[0]
}
NVIC_EnableIRQ(USART3_IRQn);
HAL_Delay (1000);
}

How to make a single function from repetitive code?

I'm writing some code for my embedded system. As I'm adding more different channels of the same periphery, I'm getting code that's really repetitive. For example:
void pos1_write_read(int *pwriteData)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf0, 0, m_length0);
spi0_xfer_done = false;
nrfx_spi_xfer_desc_t m_pos1_write;
m_pos1_write.p_tx_buffer = pwriteData;
m_pos1_write.tx_length = m_length0;
m_pos1_write.p_rx_buffer = m_rx_buf0;
m_pos1_write.rx_length = m_length0;
nrf_gpio_pin_clear(SPI0_CS0_PIN); //Set CS0 to 0 (on)
APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));
while (!spi0_xfer_done){} //Wait until the tranfser is done
nrf_gpio_pin_set(SPI0_CS0_PIN); //Set CS0 to 1 (off)
}
void pos2_write_read(int *pwriteData)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf0, 0, m_length0);
spi0_xfer_done = false;
nrfx_spi_xfer_desc_t m_pos2_write;
m_pos2_write.p_tx_buffer = pwriteData;
m_pos2_write.tx_length = m_length0;
m_pos2_write.p_rx_buffer = m_rx_buf0;
m_pos2_write.rx_length = m_length0;
nrf_gpio_pin_clear(SPI0_CS1_PIN); //Set CS1 to 0 (on)
APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));
while (!spi0_xfer_done){} //Wait until the tranfser is done
nrf_gpio_pin_set(SPI0_CS1_PIN); //Set CS1 to 1 (off)
}
How would I write a single function that could be used in both examples? Is there any general good practice to avoid repeating the same code?
Finding the right design depends on how it's intended to be used, how generic you feel is appropriate, etc. There is no single correct way to do this. But the naive solution based only on your code snippet is something like:
void write_read(int *pwriteData, int pin)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf0, 0, m_length0);
spi0_xfer_done = false;
nrfx_spi_xfer_desc_t m_pos1_write;
m_pos1_write.p_tx_buffer = pwriteData;
m_pos1_write.tx_length = m_length0;
m_pos1_write.p_rx_buffer = m_rx_buf0;
m_pos1_write.rx_length = m_length0;
nrf_gpio_pin_clear(pin); //Set CS0 to 0 (on)
APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));
while (!spi0_xfer_done){} //Wait until the tranfser is done
nrf_gpio_pin_set(pin); //Set CS0 to 1 (off)
}
void pos1_write_read(int *pwriteData)
{
write_read(pwriteData, SPI0_CS0_PIN);
}
void pos2_write_read(int *pwriteData)
{
write_read(pwriteData, SPI0_CS1_PIN);
}
The idea is to just take the common code, and parameterize anything that's different between them.
The only real difference is the SC pin, which you can pass as an argument:
void pos_write_read(int *pwriteData, uint32_t pin)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf0, 0, m_length0);
spi0_xfer_done = false;
nrfx_spi_xfer_desc_t m_pos_write;
m_pos_write.p_tx_buffer = pwriteData;
m_pos_write.tx_length = m_length0;
m_pos_write.p_rx_buffer = m_rx_buf0;
m_pos_write.rx_length = m_length0;
nrf_gpio_pin_clear(pin); //Set CS to 0 (on)
APP_ERROR_CHECK(nrfx_spi_xfer(&spi0, &spi0_transfer, NULL));
while (!spi0_xfer_done){} //Wait until the tranfser is done
nrf_gpio_pin_set(pin); //Set CS to 1 (off)
}
/* This allows you to do the following: */
void pos1_write_read(int *pwriteData)
{
pos_write_read(pwriteData, SPI0_CS0_PIN);
}
void pos2_write_read(int *pwriteData)
{
pos_write_read(pwriteData, SPI0_CS1_PIN);
}

Confusion regarding #interrupt-cells configuration on PCA9555 expander

I'm trying to setup a device tree source file for the first time on my custom platform. On the board is a NXP PCA9555 gpio expander. I'm attempting to setup node for the device and am a bit confused.
Here is where I'm at with the node in the dts file:
ioexp0: gpio-exp#21 {
compatible = "nxp,pca9555";
reg = <21>;
interrupt-parent = <&gpio>;
interrupts = <8 0>;
gpio-controller;
#gpio-cells = <2>;
/*I don't understand the following two lines*/
interrupt-controller;
#interrupt-cells = <2>;
};
I got to this point by using the armada-388-gp.dts source as a guide.
My confusion is on what code processes the #interrupt-cells property. The bindings documentation is not very helpful at all for this chip as it doesn't say anything regarding interrupt cell interpretation.
Looking at the pca953x_irq_setup function in the source code for the pca9555 driver - I don't see anywhere that the #interrupt-cells property is handled. Is this handled in the linux interrupt handling code? I'm just confused as to how I'm suppose to know the meaning of the two interrupt cells.
pca953x_irq_setup for your convenience:
static int pca953x_irq_setup(struct pca953x_chip *chip,
int irq_base)
{
struct i2c_client *client = chip->client;
int ret, i;
if (client->irq && irq_base != -1
&& (chip->driver_data & PCA_INT)) {
ret = pca953x_read_regs(chip,
chip->regs->input, chip->irq_stat);
if (ret)
return ret;
/*
* There is no way to know which GPIO line generated the
* interrupt. We have to rely on the previous read for
* this purpose.
*/
for (i = 0; i < NBANK(chip); i++)
chip->irq_stat[i] &= chip->reg_direction[i];
mutex_init(&chip->irq_lock);
ret = devm_request_threaded_irq(&client->dev,
client->irq,
NULL,
pca953x_irq_handler,
IRQF_TRIGGER_LOW | IRQF_ONESHOT |
IRQF_SHARED,
dev_name(&client->dev), chip);
if (ret) {
dev_err(&client->dev, "failed to request irq %d\n",
client->irq);
return ret;
}
ret = gpiochip_irqchip_add_nested(&chip->gpio_chip,
&pca953x_irq_chip,
irq_base,
handle_simple_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&client->dev,
"could not connect irqchip to gpiochip\n");
return ret;
}
gpiochip_set_nested_irqchip(&chip->gpio_chip,
&pca953x_irq_chip,
client->irq);
}
return 0;
}
This is my first time working with device tree so I'm hoping it's something obvious that I'm just missing.
After looking at all of the comments I did some additional reading and figured out my answer.
I now understand that I was misinterpreting some properties of the device tree. I was previously under the impression that the driver had to specify how all properties were handled. I now see that linux will actually handle many of the generic properties such as gpios or interrupts (which makes a lot of sense).
The documentation on the actual interrupts binding was very helpful, not the documentation for the device driver.
Here is a bit more of a detailed explanation of how the translation from intspec to IRQ_TYPE* happens:
The function of_irq_parse_one copies the interrupt specifier integers to a struct of_phandle_args here. This arg is then passed to irq_create_of_mapping via a consumer function (e.g. of_irq_get). This function then maps these args to a struct irq_fwspec via of_phandle_args_to_fwspec and passes it's fwspec data to irq_create_fwspec_mapping. These functions are all found in irqdomain.c. At this point the irq will belong to an irq_domain or use the irq_default_domain. As far I can tell - the pca853x driver uses the default domain. This domain is often setup by platform specific code. I found mine by searching for irq_domain_ops on cross reference. A lot of these seem to do simple copying of intspec[1] & IRQ_TYPE_SENSE_MASK to the type variable in irq_create_fwspec_mapping via irq_domain_translate. From here the type is set to the irq's irq_data via irqd_set_trigger_type.
of_irq_parse_one:
/**
* of_irq_parse_one - Resolve an interrupt for a device
* #device: the device whose interrupt is to be resolved
* #index: index of the interrupt to resolve
* #out_irq: structure of_irq filled by this function
*
* This function resolves an interrupt for a node by walking the interrupt tree,
* finding which interrupt controller node it is attached to, and returning the
* interrupt specifier that can be used to retrieve a Linux IRQ number.
*/
int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq)
{
struct device_node *p;
const __be32 *intspec, *tmp, *addr;
u32 intsize, intlen;
int i, res;
pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);
/* OldWorld mac stuff is "special", handle out of line */
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
return of_irq_parse_oldworld(device, index, out_irq);
/* Get the reg property (if any) */
addr = of_get_property(device, "reg", NULL);
/* Try the new-style interrupts-extended first */
res = of_parse_phandle_with_args(device, "interrupts-extended",
"#interrupt-cells", index, out_irq);
if (!res)
return of_irq_parse_raw(addr, out_irq);
/* Get the interrupts property */
intspec = of_get_property(device, "interrupts", &intlen);
if (intspec == NULL)
return -EINVAL;
intlen /= sizeof(*intspec);
pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen);
/* Look for the interrupt parent. */
p = of_irq_find_parent(device);
if (p == NULL)
return -EINVAL;
/* Get size of interrupt specifier */
tmp = of_get_property(p, "#interrupt-cells", NULL);
if (tmp == NULL) {
res = -EINVAL;
goto out;
}
intsize = be32_to_cpu(*tmp);
pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
/* Check index */
if ((index + 1) * intsize > intlen) {
res = -EINVAL;
goto out;
}
/* Copy intspec into irq structure */
intspec += index * intsize;
out_irq->np = p;
out_irq->args_count = intsize;
for (i = 0; i < intsize; i++)
out_irq->args[i] = be32_to_cpup(intspec++);
/* Check if there are any interrupt-map translations to process */
res = of_irq_parse_raw(addr, out_irq);
out:
of_node_put(p);
return res;
}
EXPORT_SYMBOL_GPL(of_irq_parse_one)
irq_create_fwspec_mapping:
unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec)
{
struct irq_domain *domain;
struct irq_data *irq_data;
irq_hw_number_t hwirq;
unsigned int type = IRQ_TYPE_NONE;
int virq;
if (fwspec->fwnode) {
domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_WIRED);
if (!domain)
domain = irq_find_matching_fwspec(fwspec, DOMAIN_BUS_ANY);
} else {
domain = irq_default_domain;
}
if (!domain) {
pr_warn("no irq domain found for %s !\n",
of_node_full_name(to_of_node(fwspec->fwnode)));
return 0;
}
if (irq_domain_translate(domain, fwspec, &hwirq, &type))
return 0;
/*
* WARN if the irqchip returns a type with bits
* outside the sense mask set and clear these bits.
*/
if (WARN_ON(type & ~IRQ_TYPE_SENSE_MASK))
type &= IRQ_TYPE_SENSE_MASK;
/*
* If we've already configured this interrupt,
* don't do it again, or hell will break loose.
*/
virq = irq_find_mapping(domain, hwirq);
if (virq) {
/*
* If the trigger type is not specified or matches the
* current trigger type then we are done so return the
* interrupt number.
*/
if (type == IRQ_TYPE_NONE || type == irq_get_trigger_type(virq))
return virq;
/*
* If the trigger type has not been set yet, then set
* it now and return the interrupt number.
*/
if (irq_get_trigger_type(virq) == IRQ_TYPE_NONE) {
irq_data = irq_get_irq_data(virq);
if (!irq_data)
return 0;
irqd_set_trigger_type(irq_data, type);
return virq;
}
pr_warn("type mismatch, failed to map hwirq-%lu for %s!\n",
hwirq, of_node_full_name(to_of_node(fwspec->fwnode)));
return 0;
}
if (irq_domain_is_hierarchy(domain)) {
virq = irq_domain_alloc_irqs(domain, 1, NUMA_NO_NODE, fwspec);
if (virq <= 0)
return 0;
} else {
/* Create mapping */
virq = irq_create_mapping(domain, hwirq);
if (!virq)
return virq;
}
irq_data = irq_get_irq_data(virq);
if (!irq_data) {
if (irq_domain_is_hierarchy(domain))
irq_domain_free_irqs(virq, 1);
else
irq_dispose_mapping(virq);
return 0;
}
/* Store trigger type */
irqd_set_trigger_type(irq_data, type);
return virq;
}
EXPORT_SYMBOL_GPL(irq_create_fwspec_mapping);

Hostapd - print wpa passphrase

It's possible to print wpa passphrase in hostapd (by editing the code)?
This is the conf of hostapd (we use TKIP) :
wpa=1
#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
wpa_passphrase=passphrase
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
In the file hostpad/src/ap/wpa_auth.c, we have lots of information about the connection :
SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
{
struct wpa_ptk PTK;
int ok = 0, psk_found = 0;
const u8 *pmk = NULL;
unsigned int pmk_len;
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
sm->EAPOLKeyReceived = FALSE;
sm->update_snonce = FALSE;
/* WPA with IEEE 802.1X: use the derived PMK from EAP
* WPA-PSK: iterate through possible PSKs and select the one matching
* the packet */
for (;;) {
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
sm->p2p_dev_addr, pmk);
if (pmk == NULL)
break;
psk_found = 1;
pmk_len = PMK_LEN;
} else {
pmk = sm->PMK;
pmk_len = sm->pmk_len;
}
wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK);
if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
sm->last_rx_eapol_key,
sm->last_rx_eapol_key_len) == 0) {
ok = 1;
break;
}
if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt))
break;
}
if (!ok) {
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"invalid MIC in msg 2/4 of 4-Way Handshake");
if (psk_found)
wpa_auth_psk_failure_report(sm->wpa_auth, sm->addr);
return;
}
#ifdef CONFIG_IEEE80211R
// ....
#endif /* CONFIG_IEEE80211R */
sm->pending_1_of_4_timeout = 0;
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
/* PSK may have changed from the previous choice, so update
* state machine data based on whatever PSK was selected here.
*/
os_memcpy(sm->PMK, pmk, PMK_LEN);
sm->pmk_len = PMK_LEN;
}
sm->MICVerified = TRUE;
os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
sm->PTK_valid = TRUE;
}
My knowledge in networks are limited, and I do not understand very well WPA protocol. There is an article interesting on the question here, but the situation is a little bit different because we are in the case of an attack "man in the middle".

Kernel mode keyboard filter intercept - double output

I've edited the WDK kbfiltr.c callback routine to intercept the Esc key and replace it with 'E'.
It works except that it always replaces it with 2 'E's.
So pressing Esc will output 'ee'.
Here's the code:
{
PKEYBOARD_INPUT_DATA pCur = InputDataStart;
PDEVICE_EXTENSION devExt;
WDFDEVICE hDevice;
hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject);
devExt = FilterGetData(hDevice);
while (pCur < InputDataEnd)
{
ULONG consumed = 0;
if (pCur->MakeCode == 0x01) {//Esc
pCur->MakeCode = 0x12; //E
}
else{
pCur++;
continue;
}
// indicate one packet at a time
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)
devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
pCur,
pCur+1,
&consumed);
pCur++;
}
// tell the caller you consumed everything
*InputDataConsumed = (InputDataEnd-InputDataStart);
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR) devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
InputDataStart,
InputDataEnd,
InputDataConsumed);
}
Anyone know what I'm doing wrong?
I think this was coding error.
Changing the code as below seems to make it work.
{
PKEYBOARD_INPUT_DATA pCur = InputDataStart;
PDEVICE_EXTENSION devExt;
WDFDEVICE hDevice;
hDevice = WdfWdmDeviceGetWdfDeviceHandle(DeviceObject);
devExt = FilterGetData(hDevice);
while (pCur < InputDataEnd)
{
ULONG consumed = 0;
if (pCur->MakeCode == 0x01) {//Esc
pCur->MakeCode = 0x12; //E
}
// indicate one packet at a time
(*(PSERVICE_CALLBACK_ROUTINE)(ULONG_PTR)
devExt->UpperConnectData.ClassService)(
devExt->UpperConnectData.ClassDeviceObject,
pCur,
pCur+1,
&consumed);
pCur++;
}
// tell the caller you consumed everything
*InputDataConsumed = (InputDataEnd-InputDataStart);
}

Resources