Porting PicoTCP WIP
This commit is contained in:
112
kernel/ipc/netsock/netsock.c
Normal file
112
kernel/ipc/netsock/netsock.c
Normal file
@ -0,0 +1,112 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/hal.h"
|
||||
#include "spinlock/spinlock.h"
|
||||
#include "netsock.h"
|
||||
#include "errors.h"
|
||||
#include "pico_socket.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
#include "util/util.h"
|
||||
#include "sysdefs/ipcnetsock.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
IpcNetSocks IPC_NETSOCKS;
|
||||
|
||||
void ipc_netsockinit(void) {
|
||||
hal_memset(&IPC_NETSOCKS, 0, sizeof(IPC_NETSOCKS));
|
||||
spinlock_init(&IPC_NETSOCKS.spinlock);
|
||||
}
|
||||
|
||||
void ipc_netsock_event(uint16_t ev, struct pico_socket *sock1) {
|
||||
IpcNetSock *netsock, *netsocktmp;
|
||||
|
||||
spinlock_acquire(&IPC_NETSOCKS.spinlock);
|
||||
LL_FOREACH_SAFE(IPC_NETSOCKS.netsocks, netsock, netsocktmp) {
|
||||
if (netsock->picosock == sock1)
|
||||
break;
|
||||
}
|
||||
spinlock_release(&IPC_NETSOCKS.spinlock);
|
||||
|
||||
if (netsock == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
spinlock_acquire(&netsock->spinlock);
|
||||
|
||||
/* if (ev & PICO_SOCK_EV_RD) { */
|
||||
/* uint8_t *buf = dlmalloc(IPC_PIPE_MAX); */
|
||||
/* int32_t len = 0; */
|
||||
/* int32_t read; */
|
||||
/* do { */
|
||||
/* read = pico_socket_read(netsock->picosock, buf + len, IPC_PIPE_MAX - len); */
|
||||
/* if (read > 0) { */
|
||||
/* len += read; */
|
||||
/* } */
|
||||
/* } while(read > 0); */
|
||||
/* ipc_pipewrite(netsock->datapipe, buf, len); */
|
||||
/* dlfree(buf); */
|
||||
/* } */
|
||||
|
||||
/* if (ev & PICO_SOCK_EV_WR) { */
|
||||
/* uint8_t *buf = dlmalloc(IPC_PIPE_MAX); */
|
||||
/* int32_t read = ipc_piperead(netsock->datapipe, buf, IPC_PIPE_MAX); */
|
||||
/* if (read > 0) { */
|
||||
/* pico_socket_write(netsock->picosock, buf, read); */
|
||||
/* } */
|
||||
/* dlfree(buf); */
|
||||
/* } */
|
||||
|
||||
/* if (ev & PICO_SOCK_EV_FIN) { */
|
||||
/* // normal close */
|
||||
/* } */
|
||||
|
||||
|
||||
|
||||
/* if (ev & PICO_SOCK_EV_CLOSE) { */
|
||||
/* pico_socket_shutdown(netsock->picosock, PICO_SHUT_WR); */
|
||||
/* } */
|
||||
|
||||
rbuft_push(&netsock->eventbuffer, &ev);
|
||||
|
||||
spinlock_release(&netsock->spinlock);
|
||||
}
|
||||
|
||||
IpcNetSock *ipc_netsockmake(uint16_t net, uint16_t proto, uint16_t port) {
|
||||
IpcNetSock *netsock = dlmalloc(sizeof(*netsock));
|
||||
if (netsock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
netsock->picosock = pico_socket_open(net, proto, &ipc_netsock_event);
|
||||
if (netsock->picosock == NULL) {
|
||||
goto err_sock_open;
|
||||
}
|
||||
|
||||
spinlock_init(&netsock->spinlock);
|
||||
netsock->datapipe = dlmalloc(sizeof(*netsock->datapipe));
|
||||
ipc_pipeinit(netsock->datapipe, (uint64_t)-1);
|
||||
|
||||
uint8_t *eventbuffer = dlmalloc(sizeof(IpcNetSockEventBuffer) * IPC_NETSOCK_EVENTBUFFER_MAX);
|
||||
rbuft_init(&netsock->eventbuffer, eventbuffer, sizeof(IpcNetSockEventBuffer), IPC_NETSOCK_EVENTBUFFER_MAX);
|
||||
|
||||
uint16_t port_be = short_be(port);
|
||||
struct pico_ip4 inaddr_any = {0};
|
||||
pico_socket_bind(netsock->picosock, &inaddr_any, &port_be);
|
||||
|
||||
spinlock_acquire(&IPC_NETSOCKS.spinlock);
|
||||
LL_APPEND(IPC_NETSOCKS.netsocks, netsock);
|
||||
spinlock_release(&IPC_NETSOCKS.spinlock);
|
||||
|
||||
return netsock;
|
||||
|
||||
err_sock_open:
|
||||
dlfree(netsock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t ipc_netsocklisten(IpcNetSock *netsock, size_t maxlisteners) {
|
||||
spinlock_acquire(&netsock->spinlock);
|
||||
int32_t r = pico_socket_listen(netsock->picosock, (int)maxlisteners);
|
||||
spinlock_release(&netsock->spinlock);
|
||||
return r == 0 ? E_OK : E_NETSOCKLISTEN;
|
||||
}
|
||||
Reference in New Issue
Block a user