view service.c @ 5:c0223d75444d

Fill the .hgignore with compiled files.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Mon, 23 Feb 2015 00:27:48 +0100
parents f362b20de51e
children eafcd170dc6d
line wrap: on
line source

#include "service.h"
#include "uinput.h"
#include "ds.h"
#include "restartOp.h"

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>


/*
    Create a socket
    Returns socket descriptor (-1 if error)
*/
int create_socket(unsigned short *port, int type){
    int sock, autorisation , ok;
    struct sockaddr_in  add;
    socklen_t l = sizeof(struct sockaddr_in);

    sock = socket(PF_INET, type, 0);
    if(sock == -1){
        perror("socket");
        return -1;
    }

    /* Pour pouvoir relancer immediatement un serveur TCP  */
    /* ou lancer, sur une meme machine,                    */
    /*    plusieurs recepteurs UDP sur                     */
    /*    le meme port de diffusion (broadcast, multicast) */
    autorisation = 1;
    ok = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &autorisation, sizeof(int));
    if(ok == -1){
        perror("setsockopt");
        return -1;
    }

    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){
        perror("bind");
        return -1;
    }

    ok = getsockname(sock, (struct sockaddr*)&add, &l);
    if(ok == -1){
        perror("getsockname");
        return -1;
    }

    *port = ntohs(add.sin_port);
    return sock;
}



/*
    Receive a DS datagram
    Returns size read or -1
*/
ssize_t receive_ds_info(int socket, ds_t* ds){
	struct sockaddr_in add;
	socklen_t l = sizeof(struct sockaddr_in);

	ssize_t result;

 	result = recvfrom_rs(socket, ds, sizeof(ds_t), 0, (struct sockaddr*)&add, &l);
 	if(result == -1) perror("recvfrom_rs");
 	return result;
}


/*
    Start the listening service yeah!
*/
void start_service(void){

    int uinput_fd;
    int sock_fd;
    uint16_t udp_port = base_port + curdev;

    ds_t ds;
    ssize_t result;


    fprintf(stdout, " [%d] Creation of service:\n", curdev);

    // Create joystick dev
    uinput_fd = init_uinput_device();
    if(uinput_fd == -1){
        fprintf(stderr, " [%d]  Joystick device failed\n", curdev);
        exit(EXIT_FAILURE);
    }
    fprintf(stdout, " [%d]  Joystick device OK\n", curdev);


    // Create udp socket
    sock_fd = create_socket(&udp_port, SOCK_DGRAM);
    if(sock_fd == -1){
        fprintf(stderr, " [%d]  Socket failed\n", curdev);
        exit(EXIT_FAILURE);
    }
    fprintf(stdout, " [%d]  Socket on port %d OK\n", curdev, udp_port);


    // Device and Socket are ok :-D
    fprintf(stdout, " [%d] Creation of service: OK\n", curdev);


    /* Center device axis when created */
    do_uinput(uinput_fd, ABS_Y, DS_MAX_Y/2, EV_ABS);
    do_uinput(uinput_fd, ABS_X, DS_MAX_X/2, EV_ABS);

    while(1){
        result = receive_ds_info(sock_fd, &ds);
        if(result == -1){
            fprintf(stderr, " [%d]  DS Info receive failed\n", curdev);
        }
        if(result > 0){
            ds_process_evt(&ds, uinput_fd);
        }
    }

    return;
}