/* * This file is part of the Owl Positioning System (OwlPS). * OwlPS is a project of the University of Franche-Comte * (Université de Franche-Comté), France. * * Copyright © Université de Franche-Comté 2007-2012. * * Corresponding author: Matteo Cypriani * *********************************************************************** * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL: * http://www.cecill.info * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided * only with a limited warranty and the software's authors, the holder * of the economic rights, and the successive licensors have only * limited liability. * * In this respect, the user's attention is drawn to the risks * associated with loading, using, modifying and/or developing or * reproducing the software by the user in light of its specific status * of free software, that may mean that it is complicated to manipulate, * and that also therefore means that it is reserved for developers and * experienced professionals having in-depth computer knowledge. Users * are therefore encouraged to load and test the software's suitability * as regards their requirements in conditions enabling the security of * their systems and/or data to be ensured and, more generally, to use * and operate it in the same conditions as regards security. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. * *********************************************************************** * * This is the main source file of libowlps-client. */ #include "owlps-client.h" #include #include #include #include #include /* * Opens an UDP socket to the server whose IP address is 'dest_ip' * and which listens 'dest_port'. The server information is stored * into 'server'. The socket will send through the network interface * 'iface' if specified (if you want the interface to be selected, * automatically, this parameter should be NULL or an empty string). */ int owl_create_trx_socket(const char *const dest_ip, const uint_fast16_t dest_port, struct sockaddr_in *const server, const char *const iface) { struct sockaddr_in client ; int sockfd = owl_create_udp_trx_socket(dest_ip, dest_port, server, &client) ; if (sockfd < 0) { perror("Error! Cannot create UDP sending socket to the aggregation" " server") ; exit(OWL_ERR_SOCKET_CREATE) ; } // If we specified an interface name if (iface != NULL && iface[0] != '\0') owl_use_iface(sockfd, iface) ; return sockfd ; } /* Selects 'iface' as sending interface for the socket 'sockfd'. */ void owl_use_iface(const int sockfd, const char *const iface) { #if defined(linux) && defined(__GLIBC__) if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) { fprintf(stderr, "Error! Cannot select interface %s to send the" " packet: ", iface) ; perror("") ; fprintf(stderr, "Sending through the default interface.\n") ; } #else // linux && __GLIBC__ fprintf(stderr, "Cannot select interface %s to send the packet:" " this option is currently Linux and GNU libc-specific.\n" "Sending through the default interface.\n", iface) ; #endif // linux && __GLIBC__ } /* * Transmits a request. * No packet will be transmitted if the variable owl_run is (or * becomes) false. * nb_pkt: number of packets to transmit. * delay: delay between two transmissions, in milliseconds. */ void owl_send_request(const int sockfd, const struct sockaddr_in *const server, const void *const packet, const uint_fast16_t packet_size, const uint_fast16_t nb_pkt, const uint_fast32_t delay) { uint_fast16_t i ; if (nb_pkt == 0 || !owl_run) return ; #ifdef DEBUG printf("Sent packets: ") ; #endif // DEBUG // Transmit first packet: owl_send_packet(sockfd, server, packet, packet_size) ; // Transmit remaining packets (if any): for (i = 1 ; i < nb_pkt ; ++i) { uint16_t current_pkt = htons(i + 1) ; owl_msleep(delay) ; // Wait during the wanted delay if (! owl_run) break ; // Update the packet number: memcpy(&((char*) packet)[1], ¤t_pkt, sizeof(uint16_t)) ; owl_send_packet(sockfd, server, packet, packet_size) ; } #ifdef DEBUG putchar('\n') ; #endif // DEBUG } void owl_send_packet(const int sockfd, const struct sockaddr_in *const server, const void *const packet, const uint_fast16_t packet_size) { ssize_t nsent = sendto(sockfd, packet, packet_size, 0, (struct sockaddr *) server, (socklen_t) sizeof(*server)) ; if (nsent != (ssize_t) packet_size) { perror("Error sending data to the aggregation server") ; exit(OWL_ERR_SOCKET_SEND) ; } #ifdef DEBUG putchar('.') ; fflush(stdout) ; #endif // DEBUG }