CANopen RPi : bibliothèque socket Unix pour LabVIEW

Écrit par

dans

/* unix_socket.c : accès à une socket Unix (AF_UNIX) depuis LabVIEW,
 * via un nœud d'appel de bibliothèque (Call Library Function Node).
 * Compilation dans le chroot du runtime LabVIEW :
 *   gcc -shared -fPIC -o libunixsocket.so unix_socket.c
 *   puis copie dans /usr/lib du chroot (/srv/chroot/labview/usr/lib vu de l'extérieur)
 */
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

/* Ouvre une connexion sur la socket ; renvoie le descripteur ou une valeur négative */
int Open(const char *socketPath)
{
    struct sockaddr_un addr;
    int fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (fd == -1)
        return -1;

    memset(&addr, 0, sizeof addr);
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, socketPath, sizeof addr.sun_path - 1);

    if (connect(fd, (struct sockaddr *)&addr, sizeof addr) == -1) {
        close(fd);
        return -2;
    }
    return fd;
}

int Close(int fd)
{
    return close(fd);
}

/* Écrit une commande texte ; 0 si tout est parti */
int Write(int fd, const char *command, size_t length)
{
    return write(fd, command, length) == (ssize_t)length ? 0 : -1;
}

/* Lit la réponse (appel bloquant) ; renvoie le nombre d'octets reçus ou -1 */
int Read(int fd, char *replyBuf, int bufSize)
{
    ssize_t n = read(fd, replyBuf, (size_t)bufSize);
    return n < 0 ? -1 : (int)n;
}

/* Commande puis réponse en un seul appel */
int SendCommand(int fd, const char *command, size_t length, char *replyBuf, int bufSize)
{
    if (Write(fd, command, length) != 0)
        return -1;
    return Read(fd, replyBuf, bufSize);
}