172 lines
5.5 KiB
C
172 lines
5.5 KiB
C
/*
|
|
* 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 <mcy@lm7.fr>
|
|
*
|
|
***********************************************************************
|
|
*
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
|
|
|
|
/*
|
|
* 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 OWLPS_DEBUG
|
|
printf("Sent packets: ") ;
|
|
#endif // OWLPS_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 OWLPS_DEBUG
|
|
putchar('\n') ;
|
|
#endif // OWLPS_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 OWLPS_DEBUG
|
|
putchar('.') ;
|
|
fflush(stdout) ;
|
|
#endif // OWLPS_DEBUG
|
|
}
|