#include #include #include #include #include #include #include "CORE_network.h" #include "CORE_xml.h" #define DEFAULT_LOCAL_PORT 1337 /* k3v1n RoXXoRz ! */ #define DEFAULT_SERV_BASE_PORT 16150 #define DEFAULT_SERV_IP "192.168.1.2" /************************************* PRIVATE *************************************/ static int create_socket(unsigned short *port, int type); static int sendto_rs(int sockfd, const void *msg, size_t count, int flags, const struct sockaddr *to, int tolen); /************************************/ /* Write ip text into buffer returns 1 ok 0 failed */ unsigned char network_ip2str(char* buffer, int size, ip_t ip){ if(size<16) return 0; sprintf(buffer, "%d.%d.%d.%d", ip.bytes.b1, ip.bytes.b2, ip.bytes.b3, ip.bytes.b4); return 1; } /* Init defaults network values */ void network_init(network_t* n){ n->connected = 0; n->wifi_ok = 0; n->local_sock = 0; n->local_port = DEFAULT_LOCAL_PORT; n->serv_base_port = DEFAULT_SERV_BASE_PORT; n->serv_real_port = n->serv_base_port; n->serv_ip.inaddr.s_addr = ntohl(inet_addr(DEFAULT_SERV_IP)); return; } /* Connect wifi Return: 1 OK 0 Error */ int network_connect(network_t* n){ int sock; if(n->connected == 1) return 1; if(!n->wifi_ok) PA_InitWifi(); if(!PA_ConnectWifiWFC()){ Wifi_DisableWifi(); return 0; } sock = create_socket(&(n->local_port), SOCK_DGRAM); if(sock == -1){ Wifi_DisconnectAP(); Wifi_DisableWifi(); return 0; } n->local_sock = sock; n->connected = 1; n->wifi_ok = 1; PA_SetLedBlink(1, 1); // fast blink #ifdef DEBUG PA_Print(1, "Network init OK\n"); PA_Print(1, "Server: %d.%d.%d.%d:%d\n", n->serv_ip.bytes.b1, n->serv_ip.bytes.b2, n->serv_ip.bytes.b3, n->serv_ip.bytes.b4, n->serv_base_port); PA_Print(1, "Real server port: %d\n", n->serv_real_port); #endif return 1; } /* Disconnect wifi */ void network_disconnect(network_t* n){ if(n->connected == 0) return; closesocket(n->local_sock); n->connected = 0; Wifi_DisconnectAP(); Wifi_DisableWifi(); PA_SetLedBlink(0, 0); // no blink return; } /* Send a message */ void network_send_msg(network_t* n, void* msg, int msglen){ int ok; struct sockaddr_in adr; int lgr; if(n->connected == 0) return; lgr = sizeof(struct sockaddr_in); memset(&adr, 0, lgr); adr.sin_family = AF_INET; adr.sin_port = htons(n->serv_real_port); adr.sin_addr.s_addr = htonl(n->serv_ip.inaddr.s_addr); // TODO: try simple sendto() ok = sendto_rs(n->local_sock, msg, msglen, 0, (struct sockaddr*)&adr, lgr); if(ok == -1){ #ifdef DEBUG PA_Print(1, "sendto() error\n"); #endif } } /* Process xml atoms */ int network_process_xml(void* elem, char* tag, char* content){ network_t* n = (network_t*)elem; if(tag != NULL && content != NULL){ if(strcmp(content, "")){ /* process atom: */ if(!strcmp(tag, "local_port")){ n->local_port = atoi(content); return 1; } else if(!strcmp(tag, "serv_base_port")){ n->serv_base_port = atoi(content); return 1; } else if(!strcmp(tag, "serv_ip")){ n->serv_ip.inaddr.s_addr = ntohl(inet_addr(content)); return 1; } return xml_read(elem, network_process_xml, content); } } /* Should not happend... (compiler warning) */ return 0; } /* Write xml atoms */ void network_write_xml(network_t* n, FILE* out){ fprintf(out, " \n"); fprintf(out, " \n"); fprintf(out, " %d\n", n->local_port); fprintf(out, " %d\n", n->serv_base_port); fprintf(out, " %d.%d.%d.%d\n", n->serv_ip.bytes.b1, n->serv_ip.bytes.b2, n->serv_ip.bytes.b3, n->serv_ip.bytes.b4); fprintf(out, " \n"); return; } /************************************* PRIVATE *************************************/ /* Create a socket Return: socket id -1 if error */ static int create_socket(unsigned short *port, int type){ int sock, ok; struct sockaddr_in add; int l = sizeof(struct sockaddr_in); sock = socket(PF_INET, type, 0); if(sock == -1){ #ifdef DEBUG PA_Print(1, "socket() error\n"); #endif return -1; } if(type != SOCK_DGRAM){ memset(&add, 0, l) ; add.sin_family = AF_INET ; add.sin_port = htons(*port); add.sin_addr.s_addr = htonl(INADDR_ANY); ok = bind(sock, (struct sockaddr*)&add, l); if(ok == -1){ #ifdef DEBUG PA_Print(1, "bind() error\n"); #endif return -1; } ok = getsockname(sock, (struct sockaddr*)&add, &l); if(ok == -1){ #ifdef DEBUG PA_Print(1, "getsockname() error\n"); #endif return -1; } } // *port = ntohs(add.sin_port); return sock; } /* Send a *complete* datagram in one shot Return size of sent datas */ static int sendto_rs(int sockfd, const void *msg, size_t count, int flags, const struct sockaddr *to, int tolen){ int returnValue = 0; do{ returnValue = sendto(sockfd, msg, count, flags, to, tolen); }while( (returnValue == -1) && (errno == EINTR) ); return returnValue; }