Blame view

app/app-prime-modbus/lib/fanet/can.c 5.78 KB
8c2952457   김태훈   응용 프로그램 추가
1
2
3
  /**
      @file     can.c
      @date     2012-02-24
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
4
5
      @author   장길석 jks@falinux.com
      @brief    can을 사용한 통신을 담당한다.
8c2952457   김태훈   응용 프로그램 추가
6
7
  
      @modify
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
8
                2010-08-18 (장길석) mingw와 함께 사용할 수 있는 코드 추가
8c2952457   김태훈   응용 프로그램 추가
9
10
11
12
13
14
15
      @todo
      @bug
      @remark
  
      @warning
  */
  //
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
16
17
  //  저작권    에프에이리눅스(주)
  //            외부공개 금지
8c2952457   김태훈   응용 프로그램 추가
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  //
  //----------------------------------------------------------------------------
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
  #include <net/if.h>
  #include <sys/types.h>
  #include <sys/ioctl.h>
  #include <sys/socket.h>
  
  #include <socketcan/can.h>
  #include <socketcan/can/raw.h>
  #include <socketcan/can/error.h>
  
  #include <pollmng.h>
  #include <can.h>
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
35
  /// udp 개별 구조체
8c2952457   김태훈   응용 프로그램 추가
36
37
38
39
40
  typedef struct {
  
      int                  im_server;
      struct sockaddr_can  addr;
  } can_priv_t;
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
41
  static poll_obj_t  *tmp_can_poll = NULL;  // poll 관리객체없이 전송함수를 위해
8c2952457   김태훈   응용 프로그램 추가
42
43
44
45
46
  
  #define PF_CAN      29                      /* Controller Area Network.  */
  #define AF_CAN      PF_CAN
  
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
47
48
49
  /** @brief    udp 소켓을 서버형태로 open 한다.
      @param    port  포트번호
      @return   poll_obj_t 형태의 포인터
8c2952457   김태훈   응용 프로그램 추가
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  *///----------------------------------------------------------------------------
  poll_obj_t  *can_open( char *can_port, can_filter_t *rfilter, int filter_size)
  {
      struct sockaddr_can  addr;
      poll_obj_t          *obj;
      can_priv_t          *can;
      int                  sockfd;
  
      struct ifreq        ifr;
      int                 ifindex;
  
      sockfd = socket( PF_CAN, SOCK_RAW, CAN_RAW);
      if ( sockfd < 0 ){
          perror( "can open error:" );
          return NULL;
      }
      setsockopt( sockfd, SOL_CAN_RAW, CAN_RAW_FILTER, rfilter, filter_size);
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
67
      // 소켓을 시스템에 연결한다.
8c2952457   김태훈   응용 프로그램 추가
68
      bzero( &addr, sizeof(struct sockaddr_can) );
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
69
      strcpy( ifr.ifr_name, can_port);                         // 사용할 CAN 번호
8c2952457   김태훈   응용 프로그램 추가
70
71
72
73
74
75
76
77
78
79
80
81
      ioctl(sockfd, SIOCGIFINDEX, &ifr);
      ifindex = ifr.ifr_ifindex;
  
      addr.can_family     = AF_CAN;
      addr.can_ifindex    = ifindex;
  
      if( bind( sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0 )
      {
          perror("udp bind error :");
          close( sockfd );
          return NULL;
      }
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
82
      // udp 만의 정보를 설정한다.
8c2952457   김태훈   응용 프로그램 추가
83
84
85
86
87
88
89
90
91
92
93
94
95
96
      can = (can_priv_t *)malloc( sizeof(can_priv_t) );
      can->im_server  = 1;
      memcpy( &can->addr, &addr, sizeof( can->addr));
  
      obj             = poll_add( sockfd );
      obj->type       = STYP_CAN;
      obj->priv       = (void *)can;
  
      tmp_can_poll    = obj;
  
      return obj;
  }
  
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
97
98
  /** @brief    udp 소켓을 close 한다.
      @param    obj  폴객체 포인터
8c2952457   김태훈   응용 프로그램 추가
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  *///----------------------------------------------------------------------------
  void can_close( poll_obj_t *obj )
  {
      close( obj->fd );
  
      if ( obj->priv )
      {
          free( obj->priv );
      }
  
      poll_delete( obj );
  
      if ( tmp_can_poll == obj ) tmp_can_poll = NULL;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
114
115
116
117
118
119
120
  /** @brief    udp 소켓을 통해 데이타를 전송한다.
      @param    obj     폴객체 포인터
      @param    host    상대방 IP 나 호스트이름 문자열포인터
      @param    port    상대방 포트번호
      @param    buf     전송버퍼
      @param    len     버퍼의 길이
      @return   전송한 데이타 개수
8c2952457   김태훈   응용 프로그램 추가
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  *///----------------------------------------------------------------------------
  int  can_write( poll_obj_t *obj, can_frame_t *frame)
  {
      struct sockaddr_can     *p_addr;
      can_priv_t              *p_can;
      int                      wrcnt;
  
      p_can   = ( can_priv_t *)obj->priv;
      p_addr  = &p_can->addr;
  
      wrcnt = sendto( obj->fd, frame, sizeof( can_frame_t), 0, (struct sockaddr*)p_addr, sizeof( struct sockaddr_can));
      if ( 0 > wrcnt ){
          perror( "can send error:" );
      }
      return wrcnt;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
138
139
140
141
  /** @brief    udp 소켓을 통해 데이타를 읽는다.
      @param    obj     폴객체 포인터
      @param    len     버퍼의 길이
      @return   전송된 데이타 개수
8c2952457   김태훈   응용 프로그램 추가
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  *///----------------------------------------------------------------------------
  int  can_read( poll_obj_t *obj, can_frame_t *frame)
  {
      int     rdcnt;
  
      rdcnt = read( obj->fd, frame, sizeof(can_frame_t));
      if ( 0 > rdcnt )
      {
          perror( "can recv error:" );
      }
  
      return rdcnt;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
156
157
158
159
160
161
162
  /** @brief    poll 객체없이 udp 소켓을 통해 데이타를 전송한다.
      @param    host    상대방 IP 나 호스트이름 문자열포인터
      @param    port    상대방 포트번호
      @param    buf     전송버퍼
      @param    len     버퍼의 길이
      @return   전송한 데이타 개수
      @remark   can_open_server(), can_open_client() 함수는 한번 호출되어야 한다.
8c2952457   김태훈   응용 프로그램 추가
163
164
165
166
167
168
169
170
171
172
173
  *///----------------------------------------------------------------------------
  int  can_write_simple( can_frame_t *frame )
  {
      if ( tmp_can_poll )
      {
          return can_write( tmp_can_poll, frame);
      }
  
      return -1;
  }
  //------------------------------------------------------------------------------
3061c73f6   김태훈   인코딩 변경 EUC-KR -> ...
174
175
176
177
178
  /** @brief    poll 객체없이 udp 소켓을 통해 데이타를 읽는다.
      @param    buf  전송버퍼
      @param    len  버퍼의 길이
      @return   전송된 데이타 개수
      @remark   can_open_server(), can_open_client() 함수는 한번 호출되어야 한다.
8c2952457   김태훈   응용 프로그램 추가
179
180
181
182
183
184
185
186
187
188
  *///----------------------------------------------------------------------------
  int  can_read_simple( can_frame_t *frame )
  {
      if ( tmp_can_poll )
      {
          return can_read( tmp_can_poll, frame);
      }
  
      return -1;
  }