#include #include #include #include "eos.h" #include "event.h" #include "dev/net.h" #include "sock.h" static eos_evt_handler_t evt_handler[EOS_SOCK_MAX_SOCK]; static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) { unsigned char sock; int i; if ((buffer == NULL) || (buf_len < 2)) { eos_net_bad_handler(type, buffer, buf_len); return; } switch(buffer[0]) { case EOS_SOCK_MTYPE_PKT: { sock = buffer[1]; if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { eos_net_bad_handler(type, buffer, buf_len); return; } evt_handler[sock - 1](type, buffer, buf_len); break; } case EOS_SOCK_MTYPE_CLOSE: { for (i=1; i EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { eos_net_bad_handler(type, buffer, buf_len); return; } evt_handler[sock - 1](type, buffer, buf_len); } break; } default: eos_net_bad_handler(type, buffer, buf_len); break; } } void eos_sock_init(void) { int i; for (i=0; i EOS_SOCK_MAX_SOCK)) { rv = EOS_ERR_NET; goto sock_open_udp_fin; } rv = sock; eos_sock_set_handler(sock, handler); sock_open_udp_fin: if (do_release) eos_net_free(buffer, 1); return rv; } void eos_sock_close(unsigned char sock, unsigned char *buffer) { int async; async = 0; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } buffer[0] = EOS_SOCK_MTYPE_CLOSE; buffer[1] = sock; _eos_net_send(EOS_NET_MTYPE_SOCK, buffer, 2, async, 1); eos_sock_set_handler(sock, NULL); } int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len) { *buffer = NULL; if (pkt && (pkt_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF)) return EOS_ERR_SIZE; *buffer = eos_net_alloc(); *buffer += EOS_SOCK_SIZE_UDP_HDR; if (pkt) memcpy(*buffer, pkt, pkt_len); return EOS_OK; } unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len) { if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return NULL; return buf + EOS_SOCK_SIZE_UDP_HDR; } unsigned char *eos_sock_pkt2buf(unsigned char *pkt) { return pkt - EOS_SOCK_SIZE_UDP_HDR; } static void sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer) { buffer[0] = EOS_SOCK_MTYPE_PKT; buffer[1] = sock; buffer += 2; memcpy(buffer, addr->host, sizeof(addr->host)); buffer += sizeof(addr->host); buffer[0] = addr->port >> 8; buffer[1] = addr->port; buffer += sizeof(addr->port); } int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more) { int rv; buffer -= EOS_SOCK_SIZE_UDP_HDR; sock_sendto(sock, addr, buffer); rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR, more); return rv; } int eos_sock_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len) { int rv; buffer -= EOS_SOCK_SIZE_UDP_HDR; sock_sendto(sock, addr, buffer); rv = eos_net_send_sync(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR); return rv; } int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) { if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; if (buffer[0] == EOS_SOCK_MTYPE_CLOSE) return EOS_SOCK_ERR_CLOSED; if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET; buffer += 2; if (addr) { memcpy(addr->host, buffer, sizeof(addr->host)); } buffer += sizeof(addr->host); if (addr) { addr->port = (uint16_t)buffer[0] << 8; addr->port |= (uint16_t)buffer[1]; } buffer += sizeof(addr->port); if (pkt) { if (pkt_size < buf_len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; memcpy(pkt, buffer, buf_len - EOS_SOCK_SIZE_UDP_HDR); } return EOS_OK; }