int net_probe(void) { void * pkt; int ret; /* drain the transmmit queue */ pkt = rs485_pkt_drain(&net.link); if (pkt != NULL) pktbuf_free(pkt); /* set the probe pin low */ net.probe_mode = true; stm32_gpio_clr(RS485_MODE); DCC_LOG(LOG_TRACE, "Probe mode."); thinkos_flag_clr(net.probe_flag); if ((pkt = pktbuf_alloc()) != NULL) { uint32_t seq; while ((seq = rand()) == 0); /* send a probe packet */ sprintf((char *)pkt, "PRB=%08x", seq); DCC_LOG1(LOG_TRACE, "seq=0x%08x", seq); rs485_pkt_enqueue(&net.link, pkt, 12); net.stat.tx.pkt_cnt++; net.stat.tx.octet_cnt += 12; /* wait for the end of transmission */ pkt = rs485_pkt_drain(&net.link); pktbuf_free(pkt); if ((ret = thinkos_flag_timedwait(net.probe_flag, 10)) == 0) { if (seq != net.probe_seq) { DCC_LOG(LOG_WARNING, "probe sequence mismatch!"); ret = -1; } } else if (ret == THINKOS_ETIMEDOUT) { DCC_LOG(LOG_WARNING, "probe sequence timedout!"); } DCC_LOG1(LOG_TRACE, "seq=0x%08x", seq); } else { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); ret = -1; } /* set the probe pin high */ net.probe_mode = false; stm32_gpio_set(RS485_MODE); DCC_LOG(LOG_TRACE, "Probe mode."); return ret; }
int net_recv(void * buf, int len) { void * pkt; pkt = pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); DBG("pktbuf_alloc() failed!\n"); return -1; } len = rs485_pkt_receive(&net.link, &pkt, pktbuf_len); // DBG("len=%d\n", len); DCC_LOG1(LOG_TRACE, "%d", len); DCC_LOG2(LOG_TRACE, "pkt=%p len=%d", pkt, len); if (pkt != NULL) { memcpy(buf, pkt, len); pktbuf_free(pkt); } return len; }
int net_send(const void * buf, int len) { void * pkt; pkt = pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); return -1; } DCC_LOG2(LOG_TRACE, "pkt=%p len=%d", pkt, len); len = MIN(len, pktbuf_len); memcpy(pkt, buf, len); pkt = rs485_pkt_enqueue(&net.link, pkt, len); net.stat.tx.pkt_cnt++; net.stat.tx.octet_cnt += len; if (pkt != NULL) pktbuf_free(pkt); return 0; }
int net_recv(void * buf, int len) { void * pkt; pkt = pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); printf("%s(): pktbuf_alloc() failed!\n", __func__); return -1; } len = rs485_pkt_receive(&link, &pkt, len); // printf("%s(): len=%d\n", __func__, len); DCC_LOG1(LOG_TRACE, "%d", len); DCC_LOG2(LOG_TRACE, "pkt=%p len=%d", pkt, len); if (pkt != NULL) { memcpy(buf, pkt, len); pktbuf_free(pkt); } return len; }
void __attribute__((noreturn)) net_recv_task(void) { void * pkt; int len; DCC_LOG1(LOG_TRACE, "thread=%d", thinkos_thread_self()); DBG("<%d> started...", thinkos_thread_self()); for (;;) { pkt = pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); DBG("pktbuf_alloc() failed!"); thinkos_sleep(1000); continue; } len = rs485_pkt_receive(&net.link, &pkt, pktbuf_len); if (len < 0) { DBG("rs485_pkt_receive() failed!"); thinkos_sleep(1000); continue; } if (len == 0) { DBG("rs485_pkt_receive() == 0!"); thinkos_sleep(1000); continue; } if (pkt != NULL) { if (net.probe_mode) net_probe_recv((char *)pkt, len); else if (net.pkt_mode) net_pkt_recv((struct net_pkt *)pkt, len); else net_recv((char *)pkt, len); pktbuf_free(pkt); } } }
int net_pkt_send(const void * buf, int len) { struct net_pkt * pkt; unsigned int data_len; uint8_t * dst; uint8_t * src; int i; pkt = (struct net_pkt *)pktbuf_alloc(); if (pkt == NULL) { DCC_LOG(LOG_ERROR, "pktbuf_alloc() failed!"); DBG("pktbuf_alloc() failed!\n"); net.stat.tx.err_cnt++; return -1; } data_len = MIN(len, pktbuf_len - sizeof(struct net_pkt)); pkt->crc = 0; pkt->data_len = data_len; pkt->seq = net.tx_seq++; dst = (uint8_t *)pkt->data; src = (uint8_t *)buf; for (i = 0; i < data_len; ++i) dst[i] = src[i]; pkt->crc = crc16ccitt(0, pkt, data_len + sizeof(struct net_pkt)); pkt = rs485_pkt_enqueue(&net.link, pkt, data_len + sizeof(struct net_pkt)); net.stat.tx.pkt_cnt++; net.stat.tx.octet_cnt += data_len + sizeof(struct net_pkt); if (pkt != NULL) pktbuf_free(pkt); return 0; }
static void start_auth_request(PgSocket *client, const char *username) { int res; PktBuf *buf; client->auth_user = client->db->auth_user; /* have to fetch user info from db */ client->pool = get_pool(client->db, client->db->auth_user); if (!find_server(client)) { client->wait_for_user_conn = true; return; } slog_noise(client, "Doing auth_conn query"); client->wait_for_user_conn = false; client->wait_for_user = true; if (!sbuf_pause(&client->sbuf)) { release_server(client->link); disconnect_client(client, true, "pause failed"); return; } client->link->ready = 0; res = 0; buf = pktbuf_dynamic(512); if (buf) { pktbuf_write_ExtQuery(buf, cf_auth_query, 1, username); res = pktbuf_send_immediate(buf, client->link); pktbuf_free(buf); /* * Should do instead: * res = pktbuf_send_queued(buf, client->link); * but that needs better integration with SBuf. */ } if (!res) disconnect_server(client->link, false, "unable to send login query"); }
static int eth_rx_worker(void *arg) { for (;;) { #if 0 status_t event_err = event_wait_timeout(ð.rx_event, 1000); if (event_err == ERR_TIMED_OUT) { /* periodically poll the phys status register */ /* XXX specific to DP83848 */ uint32_t val; /* Read PHY_MISR */ /* seems to take about 30 usecs */ HAL_ETH_ReadPHYRegister(ð.EthHandle, PHY_MISR, &val); /* Check whether the link interrupt has occurred or not */ if (val & PHY_LINK_INTERRUPT) { /* Read PHY_SR*/ HAL_ETH_ReadPHYRegister(ð.EthHandle, PHY_SR, &val); /* Check whether the link is up or down*/ if (val & PHY_LINK_STATUS) { printf("eth: link up\n"); //netif_set_link_up(link_arg->netif); } else { printf("eth: link down\n"); //netif_set_link_down(link_arg->netif); } } } else { #else status_t event_err = event_wait(ð.rx_event); if (event_err >= NO_ERROR) { #endif // XXX probably race with the event here while (HAL_ETH_GetReceivedFrame_IT(ð.EthHandle) == HAL_OK) { LTRACEF("got packet len %u, buffer %p, seg count %u\n", eth.EthHandle.RxFrameInfos.length, (void *)eth.EthHandle.RxFrameInfos.buffer, eth.EthHandle.RxFrameInfos.SegCount); #if WITH_LIB_MINIP /* allocate a pktbuf header, point it at our rx buffer, and pass up the stack */ pktbuf_t *p = pktbuf_alloc_empty(); if (p) { pktbuf_add_buffer(p, (void *)eth.EthHandle.RxFrameInfos.buffer, eth.EthHandle.RxFrameInfos.length, 0, 0, NULL, NULL); p->dlen = eth.EthHandle.RxFrameInfos.length; minip_rx_driver_callback(p); pktbuf_free(p, true); } #endif /* Release descriptors to DMA */ /* Point to first descriptor */ __IO ETH_DMADescTypeDef *dmarxdesc; dmarxdesc = eth.EthHandle.RxFrameInfos.FSRxDesc; /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ for (uint i=0; i< eth.EthHandle.RxFrameInfos.SegCount; i++) { dmarxdesc->Status |= ETH_DMARXDESC_OWN; dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr); } /* Clear Segment_Count */ eth.EthHandle.RxFrameInfos.SegCount =0; /* When Rx Buffer unavailable flag is set: clear it and resume reception */ if ((eth.EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) { /* Clear RBUS ETHERNET DMA flag */ eth.EthHandle.Instance->DMASR = ETH_DMASR_RBUS; /* Resume DMA reception */ eth.EthHandle.Instance->DMARPDR = 0; } } } } return 0; } #if WITH_LIB_MINIP status_t stm32_eth_send_minip_pkt(pktbuf_t *p) { LTRACEF("p %p, dlen %zu, eof %u\n", p, p->dlen, p->flags & PKTBUF_FLAG_EOF); DEBUG_ASSERT(p && p->dlen); if (!(p->flags & PKTBUF_FLAG_EOF)) { /* can't handle multi part packets yet */ PANIC_UNIMPLEMENTED; return ERR_NOT_IMPLEMENTED; } status_t err = eth_send(p->data, p->dlen); pktbuf_free(p, true); return err; }