tipc_bcast.c 4.57 KB
/**
    @file     tipc_bcast.c
    @date     2015-08-31
    @author   장길석 jks@falinux.com
    @brief    TIPC-DGRAM 소켓을 사용하여 멀티캐스트가 가능한 통신을 담당한다.

    @modify
    @todo
    @bug
    @remark

    @warning
*/
//
//  저작권    에프에이리눅스(주)
//            외부공개 금지
//
//----------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/tipc.h>
#include <pollmng.h>
#include "../../include/fanet/tipc_bcast.h"

char desc_tipc_bcast[] = "falinux tipc broadcast ver 0.0.1";

/// tipc_bcast 개별 구조체
typedef struct {
    int   type;                                                     // server type
    int   lower;                                                    // port lower
    int   upper;                                                    // port upper
} tipc_bcast_priv_t;

//------------------------------------------------------------------------------
/** @brief    tipc_bcast 소켓을 서버형태로 open 한다.
    @param    port  포트번호
    @return   poll_obj_t 형태의 포인터
*///----------------------------------------------------------------------------

poll_obj_t  *tipc_bcast_open( int type, int lower, int upper )
{
    struct sockaddr_tipc server_addr;

    server_addr.family             = AF_TIPC;
    server_addr.addrtype           = TIPC_ADDR_NAMESEQ;
    server_addr.scope              = TIPC_CLUSTER_SCOPE;
    server_addr.addr.nameseq.type  = type;
    server_addr.addr.nameseq.lower = lower;
    server_addr.addr.nameseq.upper = upper;

    int sockfd = socket (AF_TIPC, SOCK_RDM, 0);

    if ( bind( sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr))) {
        printf("Server: port {%u,%u,%u} could not be created\n",
                type, lower, upper);
        close( sockfd );
        return NULL;
    }

    tipc_bcast_priv_t *tipc_bcast;
    poll_obj_t *obj;

    // tipc_bcast 만의 정보를 설정한다.
    tipc_bcast = (tipc_bcast_priv_t *)malloc( sizeof(tipc_bcast_priv_t) );
    tipc_bcast->type        = type;
    tipc_bcast->lower       = lower;
    tipc_bcast->upper       = upper;

    obj             = poll_add( sockfd );
    obj->type       = STYP_TIPC_DGRAM;
    obj->priv       = (void *)tipc_bcast;

    return obj;
}

//------------------------------------------------------------------------------
/** @brief    tipc_bcast 소켓을 close 한다.
    @param    obj  폴객체 포인터
*///----------------------------------------------------------------------------
void tipc_bcast_close( poll_obj_t *obj )
{
    close( obj->fd );

    if ( obj->priv ){
        free( obj->priv );
    }

    poll_delete( obj );
}
//------------------------------------------------------------------------------
/** @brief    tipc_bcast 소켓을 통해 데이타를 전송한다.
    @param    obj     폴객체 포인터
    @param    host    상대방 IP 나 호스트이름 문자열포인터
    @param    port    상대방 포트번호
    @param    buf     전송버퍼
    @param    len     버퍼의 길이
    @return   전송한 데이타 개수
*///----------------------------------------------------------------------------
int  tipc_bcast_write( poll_obj_t *obj, int type, int lower, int upper, char *buf, int len )
{
    struct sockaddr_tipc server_addr;

    server_addr.family              = AF_TIPC;
    server_addr.addrtype            = TIPC_ADDR_MCAST;
    server_addr.addr.nameseq.type   = type;
    server_addr.addr.nameseq.lower  = lower;
    server_addr.addr.nameseq.upper  = upper;

    int wrcnt = sendto( obj->fd, buf, len, 0,
                   (struct sockaddr *)&server_addr, sizeof( server_addr));

    return wrcnt;
}
//------------------------------------------------------------------------------
/** @brief    tipc_bcast 소켓을 통해 데이타를 읽는다.
    @param    obj     폴객체 포인터
    @param    len     버퍼의 길이
    @return   전송된 데이타 개수
*///----------------------------------------------------------------------------
int  tipc_bcast_read( poll_obj_t *obj, char *buf, int len )
{
    struct sockaddr_tipc client_addr;
    socklen_t            alen = sizeof(struct sockaddr_tipc);

    int rdcnt = recvfrom( obj->fd, buf, len, 0,
                     (struct sockaddr *)&client_addr, &alen);

    if ( 0 > rdcnt ){
        perror( "tipc_bcast recv error:" );
    }

    return rdcnt;
}