C221-S3C6410 보드에 있는 UDP로 들어오는 데이터를 CAN 통신으로 보내는 프로그램은 다음과 같습니다.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <net/if.h>

#include <arpa/inet.h>
#include <sys/socket.h>

#include <linux/can.h>
#include <linux/can/raw.h>

 

#define BUFF_SIZE       1024
#define UDP_PORT        4000

 

int     fd_can;                      // can 통신을 위한 파일 디스크립터
int     fd_udp;                      // fd_udp 서버 소켙의 파일 디스크립터

struct  sockaddr_can    addr_can;

 

void on_data( )
{
    char                    buff_rcv[BUFF_SIZE+1];
    struct can_frame        frame;
    struct sockaddr_in      client_addr;
    socklen_t               sz_client_addr;
    int                     rd_cnt;
   
    sz_client_addr  = sizeof( sz_client_addr);
    rd_cnt = recvfrom( fd_udp, buff_rcv, BUFF_SIZE, 0 , ( struct sockaddr*)&client_addr, &sz_client_addr);
   
    if ( 0 < rd_cnt)
    {
         int ndx_loop;
        
         printf( "receive:");           // 수령 메시지 화면 출력
         frame.can_id  = 0x32;
         frame.can_dlc = 8;
         memset( frame.data, 0, 8);
         for ( ndx_loop = 0; ndx_loop < rd_cnt; ndx_loop++)
         {
             printf( "%2x ", buff_rcv[ndx_loop]);
             frame.data[ndx_loop] = buff_rcv[ndx_loop];
         }
         printf( "\n");
        
         sendto( fd_can, &frame, sizeof(struct can_frame), 0, (struct sockaddr*)&addr_can, sizeof(addr_can));
    }
}   
   
int main( int argc, char *argv[])
{   
    char can_port[1024];
   
    if ( 2 > argc) {
        printf( "인수가 모자릅니다. CAN 포트를 입력하여 주시오\n");
        printf( "실행방법: ]$ ./app_udp_to_can can0\n");
        exit( 0);
    }
   
    sprintf( can_port, "%s", argv[1] );
   
    // can 포트 open ////////////////////////////////////////////////////////////
   
    struct ifreq    ifr;
    int             ifindex;
   
    if ( 0 > ( fd_can = socket(PF_CAN, SOCK_RAW, CAN_RAW)) ) {
        perror("socket");
        return 1;
    }
   
    strcpy(ifr.ifr_name, can_port);
    ioctl( fd_can, SIOCGIFINDEX, &ifr);
    ifindex = ifr.ifr_ifindex;
   
    addr_can.can_family  = AF_CAN;
    addr_can.can_ifindex = ifindex; /* send via this interface */
   
    if ( 0 > bind( fd_can, (struct sockaddr *)&addr_can, sizeof(addr_can)) ) {
        perror("bind");
        return 1;
    }
   
    // fd_udp 서버  ////////////////////////////////////////////////////////////////
   
    struct sockaddr_in addr_in;
    int option;
   
    fd_udp = socket( PF_INET, SOCK_DGRAM, 0);
    if ( fd_udp < 0 )
    {
        perror( "fd_udp server open error:" );
        return 1;
    }
   
    option = 1;
    setsockopt( fd_udp, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
   
    bzero( &addr_in, sizeof(struct sockaddr_in) );
    addr_in.sin_family      = AF_INET;
    addr_in.sin_addr.s_addr = htonl( INADDR_ANY  );
    addr_in.sin_port        = htons( UDP_PORT);
   
    if( bind( fd_udp, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in) ) < 0 )
    {
        perror("fd_udp bind error :");
        close( fd_udp );
        return 1;
    }
   
    // poll 초기화 및 등록  ////////////////////////////////////////////////////
   
    struct  pollfd       poll_events;                          // fd_udp 서버 소켙과 클라이언트 소켙을 위해 2개 사용
    int     poll_state;
   
    poll_events.fd             = fd_udp;                    // 서버 소켙의 파일 디스크립터 저정
    poll_events.events      = POLLIN | POLLERR;     // 수신된 자료가 있는지, 에러가 있는지
    poll_events.revents     = 0;
   
    // 자료 송수신 ////////////////////////////////////////////////////////////
   
    while ( 1)
    {
        poll_state = poll(                                              // poll()을 호출하여 event 발생 여부 확인
                                (struct pollfd*)&poll_events,      // event 등록 변수
                                                                    1,      // 체크할 pollfd 개수
                                                               1000       // time out 시간
                             );
       
        printf( "=================\n");
        if ( 0 < poll_state)                                            // 발생한 event 가 있음
        {
               printf( "-------------------\n");
              if ( poll_events.revents & POLLIN)                  // event 가 자료 수신?
              {
                     on_data();
              }
              if ( poll_events.revents & POLLERR)                // event 가 에러?
              {
                    printf( "클라이언트 소켙 이상. 프로그램 종료\n");
                    break;
               }
        }
    }
    close( fd_udp );
    close( fd_can );
    return 0;

}