하드웨어
#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 int main( int argc, char *argv[]) { char can_port[BUFF_SIZE]; char server_ip[BUFF_SIZE]; if ( 3 > argc){ printf( "인수가 모자릅니다. 포트의 서버 IP를 입력하여 주십시오.\n"); printf( "실행방법: ]$ ./app_can_to_tcp can0 127.0.0.1\n"); exit( 0); } sprintf( can_port , argv[1]); sprintf( server_ip , argv[2]); // can 포트 open //////////////////////////////////////////////////////////// int fd_sock; struct sockaddr_can addr; struct can_filter rfilter[4]; struct ifreq ifr; int ifindex; // can 포트를 open if ( 0 > ( fd_sock = socket(PF_CAN, SOCK_RAW, CAN_RAW))) { perror("socket"); return 1; } rfilter[0].can_id = 0x32; rfilter[0].can_mask = CAN_SFF_MASK; rfilter[1].can_id = 0x200; rfilter[1].can_mask = 0x700; rfilter[2].can_id = 0x80123456; rfilter[2].can_mask = 0x1FFFF000; rfilter[3].can_id = 0x80333333; rfilter[3].can_mask = CAN_EFF_MASK; setsockopt( fd_sock, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); strcpy( ifr.ifr_name, can_port); // 사용할 CAN 번호 ioctl( fd_sock, SIOCGIFINDEX, &ifr); ifindex = ifr.ifr_ifindex; addr.can_family = AF_CAN; addr.can_ifindex = ifindex; if ( bind( fd_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } // poll 초기화 및 등록 //////////////////////////////////////////////////// struct pollfd poll_events; // 체크할 event 정보를 갖는 struct int poll_state; poll_events.fd = fd_sock; 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 시간 ); if ( 0 < poll_state) // 발생한 event 가 있음 { if ( poll_events.revents & POLLIN) // event 가 자료 수신? { struct can_frame frame; int rd_size; rd_size = read( fd_sock, &frame, sizeof(struct can_frame)); if ( 0 > rd_size) { fprintf(stderr, "read error"); } else if ( rd_size < sizeof( struct can_frame)) { fprintf(stderr, "read: incomplete CAN frame\n"); return 1; } else { int client_socket; struct sockaddr_in server_addr; char tx_buff[BUFF_SIZE+1]; int ndx; if (frame.can_id & CAN_EFF_FLAG) printf("%8X ", frame.can_id & CAN_EFF_MASK); else printf("%3X ", frame.can_id & CAN_SFF_MASK); if (frame.can_id & CAN_RTR_FLAG) printf("remote request"); printf(" [%d] ", frame.can_dlc); for ( ndx = 0; ndx < frame.can_dlc; ndx++) { printf("%02X ", frame.data[ndx]); tx_buff[ndx] = frame.data[ndx]; } printf("\n"); tx_buff[ndx++] = '\0'; client_socket = socket( PF_INET, SOCK_STREAM, 0); // 클라이언트 소겟 생성 if( -1 == client_socket) { printf( "socket 생성 실패n"); exit( 1); } memset( &server_addr, 0, sizeof( server_addr)); // 서버 주소 정보 작성 server_addr.sin_family = AF_INET; server_addr.sin_port = htons( 4000); server_addr.sin_addr.s_addr= inet_addr( server_ip); if( -1 == connect( client_socket, (struct sockaddr*)&server_addr, sizeof( server_addr) ) ) { printf( "접속 실패\n"); } else { write( client_socket, tx_buff, ndx ); close( client_socket ); } } } if ( poll_events.revents & POLLERR) // event 가 에러? { printf( "통신 라인에 에러가 발생, 프로그램 종료"); break; } } } close( fd_sock ); return 0; } |
===========
다음 강좌에서는 can to udp 프로그램을 설명하도록 하겠습니다