#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, EOSMessage *msg, uint16_t len) { unsigned char sock; int i; if ((msg == NULL) || (len < 2)) { eos_net_bad_handler(type, msg, len); return; } switch(msg->buffer[0]) { case EOS_SOCK_MTYPE_PKT: { sock = msg->buffer[1]; if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { eos_net_bad_handler(type, msg, len); return; } evt_handler[sock - 1](type, msg, len); break; } case EOS_SOCK_MTYPE_CLOSE: { for (i=1; ibuffer[i]; if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { eos_net_bad_handler(type, msg, len); continue; } evt_handler[sock - 1](type, msg, len); evt_handler[sock - 1] = NULL; } break; } default: eos_net_bad_handler(type, msg, len); break; } } void eos_sock_init(void) { int i; for (i=0; isize < 2) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_SOCK; len = 1; msg->buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; rv = eos_net_xchg(&type, msg, &len); if (rv) return rv; if (type != EOS_NET_MTYPE_SOCK) return EOS_ERR_NET; if (len < 2) return EOS_ERR_SIZE; sock = msg->buffer[1]; if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; eos_sock_set_handler(sock, handler); return sock; } void eos_sock_close(unsigned char sock, EOSMessage *msg) { if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return; if (msg->size < 2) return; msg->buffer[0] = EOS_SOCK_MTYPE_CLOSE; msg->buffer[1] = sock; eos_net_send_sync(EOS_NET_MTYPE_SOCK, msg, 2); eos_sock_set_handler(sock, NULL); } static void sock_sendto(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg) { unsigned char *buffer; buffer = msg->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, EOSMessage *msg, uint16_t pkt_len) { if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; sock_sendto(sock, addr, msg); return eos_net_send_sync(EOS_NET_MTYPE_SOCK, msg, pkt_len + EOS_SOCK_SIZE_UDP_HDR); } int eos_sock_sendto_async(unsigned char sock, EOSNetAddr *addr, EOSMessage *msg, uint16_t pkt_len, int more) { if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) return EOS_ERR_NET; sock_sendto(sock, addr, msg); return eos_net_send(EOS_NET_MTYPE_SOCK, msg, pkt_len + EOS_SOCK_SIZE_UDP_HDR, more); } int eos_sock_recvfrom(EOSMessage *msg, uint16_t len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) { char *buffer = msg->buffer; if (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 < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; memcpy(pkt, buffer, len - EOS_SOCK_SIZE_UDP_HDR); } return EOS_OK; } unsigned char *eos_sock_msg2pkt(EOSMessage *msg, uint16_t *len, uint16_t *pkt_size) { if (len && (*len < EOS_SOCK_SIZE_UDP_HDR)) return NULL; if (msg->size < EOS_SOCK_SIZE_UDP_HDR) return NULL; if (len && (msg->buffer[0] != EOS_SOCK_MTYPE_PKT)) return NULL; if (len) *len -= EOS_SOCK_SIZE_UDP_HDR; if (pkt_size) *pkt_size = msg->size - EOS_SOCK_SIZE_UDP_HDR; return msg->buffer + EOS_SOCK_SIZE_UDP_HDR; } void eos_sock_pkt2msg(EOSMessage *msg, unsigned char *pkt, uint16_t pkt_size) { msg->buffer = pkt - EOS_SOCK_SIZE_UDP_HDR; msg->size = pkt_size + EOS_SOCK_SIZE_UDP_HDR; }