📄 af_can.c
字号:
//****************************************************************************//
// File: af_canpie.c //
// Description: //
// Author: Uwe Koppe //
// e-mail: koppe@microcontrol.net //
// //
//============================================================================//
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU Lesser General Public License as published //
// by the Free Software Foundation; either version 2.1 of the License, or //
// (at your option) any later version. //
//============================================================================//
// //
// Date History //
// ---------- -------------------------------------------------------------- //
// 16.02.2004 Initial version //
// //
//****************************************************************************//
//------------------------------------------------------------------------------
// CVS version information:
// $Id: af_can.c,v 1.4 2005/07/01 14:12:37 microcontrol Exp $
//------------------------------------------------------------------------------
/*----------------------------------------------------------------------------*\
** Include files **
** **
\*----------------------------------------------------------------------------*/
#include <linux/config.h>
#include <linux/module.h>
#include <net/sock.h>
#include <net/can/af_can.h>
#include <net/can/canpie_dbg.h>
#include <net/can/canpie_hal.h>
#include <net/can/cpcanmsg.h>
#include <net/can/cpcore.h>
// #include <linux/can.h> // CAN definitions
//-----------------------------------------------------------------------------
/*! \file af_can.c
**
**
*/
/*----------------------------------------------------------------------------*\
** Function implementations **
** **
\*----------------------------------------------------------------------------*/
static struct proto_ops can_raw_ops;
//----------------------------------------------------------------------------//
// can_sock_alloc() //
// create a CAN sock structure //
//----------------------------------------------------------------------------//
static int can_sock_alloc(struct sock * sk)
{
struct can_sock * ptsCanSockT;
//-----------------------------------------------------------------
// create a new 'can_sock' structure and zero its contents
//
ptsCanSockT = kmalloc(sizeof(struct can_sock), GFP_ATOMIC);
if(ptsCanSockT == NULL)
{
return(-ENOMEM);
}
memset(ptsCanSockT, 0x00, sizeof(struct can_sock));
//-----------------------------------------------------------------
// now link the 'sock' and the 'can_sock' together
//
ptsCanSockT->ptsSock = sk;
ptsCanSockT->rcv_fifo_size = CP_QUEUE_MSG_DEF;
ptsCanSockT->trm_fifo_size = CP_QUEUE_MSG_DEF;
sk->sk_protinfo = ptsCanSockT;
PK_DBG(eDBG_SOCK, "created new CAN socket (%p)", ptsCanSockT);
return(0);
}
//----------------------------------------------------------------------------//
// can_sock_release() //
// remove a CAN sock structure //
//----------------------------------------------------------------------------//
static void can_sock_release(struct sock *sk)
{
struct can_sock *csock;
csock = sk->sk_protinfo;
if(csock)
{
PK_DBG(4, "can_sock is %p", csock);
kfree(csock);
}
sk->sk_protinfo = NULL;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
static struct proto can_family =
{
.name = "CAN",
.obj_size = sizeof(struct sock)
};
#endif
//----------------------------------------------------------------------------//
// can_create() //
// create a CAN socket //
//----------------------------------------------------------------------------//
static int can_create(struct socket *sock, int protocol)
{
struct sock * sk;
PK_DBG(4, "sock=%p prot=%d", sock, protocol);
//-----------------------------------------------------------------
// create a new 'sock' structure and zero its contents (done by
// setting the 3rd parameter to '1')
//
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
sk = sk_alloc(AF_CAN, GFP_ATOMIC, &can_family, 1);
#else
sk = sk_alloc(AF_CAN, GFP_ATOMIC, 1, NULL);
#endif
if(sk == NULL)
{
return(-ENOMEM);
}
//-----------------------------------------------------------------
// allocate new CAN sock structure
//
if(can_sock_alloc(sk) < 0)
{
kfree(sk);
return(-ENOMEM);
}
PK_DBG(4, "can_sock_alloc !!!!");
//-----------------------------------------------------------------
// init the socket
//
sock_init_data(sock, sk);
sock->ops = &can_raw_ops;
sk->sk_protocol = protocol;
// sk_set_owner(sk, THIS_MODULE);
return 0;
}
//----------------------------------------------------------------------------//
// can_raw_accept() //
// //
//----------------------------------------------------------------------------//
static int can_raw_accept(struct socket *sock, struct socket *newsock,
int flags)
{
PK_DBG(2, "socket %p", sock);
return(0);
}
//----------------------------------------------------------------------------//
// can_raw_bind() //
// //
//----------------------------------------------------------------------------//
static int can_raw_bind(struct socket *sock, struct sockaddr *myaddr,
int sockaddr_len)
{
PK_DBG(2, "socket %p", sock);
return(0);
}
//----------------------------------------------------------------------------//
// can_raw_connect() //
// this functions is called upon "connect()" in userspace //
//----------------------------------------------------------------------------//
static int can_raw_connect(struct socket *sock, struct sockaddr *vaddr,
int sockaddr_len, int flags)
{
struct sockaddr_can * ptsAddrCanT;
struct can_sock * ptsCanSockT;
_TsCpHal * ptsHalT;
//-----------------------------------------------------------------
// get pointer to can_sock structure
//
ptsCanSockT = sock->sk->sk_protinfo;
PK_DBG(eDBG_SOCK, "socket=%p flags=%d", sock, flags);
PK_DBG(eDBG_SOCK, "can_sock=%p ", ptsCanSockT);
//-----------------------------------------------------------------
// test size of the supplied socket address structure
//
if(sockaddr_len > sizeof(struct sockaddr_can))
{
PK_DBG(eDBG_SOCK, "wrong size for sockaddr_can (%d)", sockaddr_len);
return(-EADDRNOTAVAIL); // Cannot assign requested address
}
//-----------------------------------------------------------------
// vaddr points to a sockaddr_can structure
//
ptsAddrCanT = (struct sockaddr_can *) vaddr;
PK_DBG(eDBG_SOCK, "CAN I/F = %d", ptsAddrCanT->can_if);
PK_DBG(eDBG_SOCK, "CAN ID = %X", ptsAddrCanT->can_id);
//-----------------------------------------------------------------
// check if there is a driver installed on the requested port
//
ptsHalT = can_get_hal(ptsAddrCanT->can_if);
if(ptsHalT == 0L)
{
PK_DBG(eDBG_SOCK, "No driver on CAN port %d", ptsAddrCanT->can_if);
return(-EADDRNOTAVAIL); // Cannot assign requested address
}
if( ( (ptsHalT->slStatus) & CP_HAL_DRV_OK) == 0)
{
PK_DBG(1, "No driver on CAN port %d", ptsAddrCanT->can_if);
return(-EADDRNOTAVAIL); // Cannot assign requested address
}
//-----------------------------------------------------------------
// link the socket to the driver
//
ptsCanSockT->ptsCanPort = can_queue_create( ptsAddrCanT->can_if,
ptsCanSockT->rcv_fifo_size,
ptsCanSockT->rcv_fifo_size);
if(ptsCanSockT->ptsCanPort == 0L)
{
return(-ENOMEM);
}
return(0);
}
//----------------------------------------------------------------------------//
// can_raw_getname() //
// //
//----------------------------------------------------------------------------//
static int can_raw_getname(struct socket *sock, struct sockaddr *addr,
int *sockaddr_len, int peer)
{
PK_DBG(eDBG_SOCK, "socket %p", sock);
return(0);
}
//----------------------------------------------------------------------------//
// can_raw_getsockopt() //
// //
//----------------------------------------------------------------------------//
static int can_raw_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
PK_DBG(eDBG_SOCK, "socket %p", sock);
return(0);
}
//----------------------------------------------------------------------------//
// can_raw_ioctl() //
// //
//----------------------------------------------------------------------------//
static int can_raw_ioctl( struct socket *sock, unsigned int cmd,
unsigned long arg)
{
int slErrCodeT = 0;
_TsCpBitrate tsBitTimingT;
uint32_t aslValueT[8]; // buffer for ioctl values
struct can_sock * ptsCanSockT;
int ret;
//-----------------------------------------------------------------
// get pointer to can_sock structure
//
ptsCanSockT = sock->sk->sk_protinfo;
switch(cmd)
{
//---------------------------------------------------
// set new bitrate
//
case SIOC_CAN_SET_BITRATE:
PK_DBG(eDBG_SOCK, "Set bitrate");
ret = copy_from_user(&tsBitTimingT, (void __user *)arg,
sizeof(tsBitTimingT));
CpCoreBitrate(ptsCanSockT->ptsCanPort, &tsBitTimingT);
break;
//---------------------------------------------------
// get current bitrate
//
case SIOC_CAN_GET_BITRATE:
PK_DBG(eDBG_SOCK, "Get bitrate");
break;
case SIOC_CAN_SET_MODE:
PK_DBG(eDBG_SOCK, "Set CAN mode");
break;
case SIOC_CAN_GET_STATE:
PK_DBG(eDBG_SOCK, "Get CAN state");
break;
//---------------------------------------------------
// get max channel number (logical CAN I/F)
//
case SIOC_CAN_GET_CHANNEL_MAX:
PK_DBG(eDBG_SOCK, "Get maximum CAN channel");
aslValueT[0] = CP_CHANNEL_MAX;
ret = copy_to_user( (void __user *)arg,
&aslValueT[0],
sizeof(uint32_t));
break;
//---------------------------------------------------
// set size of FIFO
//
case SIOC_CAN_SET_FIFOSIZE:
PK_DBG(eDBG_SOCK, "Set Rcv-FIFO size");
ret = copy_from_user( &aslValueT[0],
(void __user *)arg,
sizeof(uint32_t) * 2);
//can_queue_resize(ptsCanSockT->ptsCanPort, aslValueT[0], aslValueT[1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -