⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 af_can.c

📁 canpie 一个can bus的协议栈 - CAN interface for embedded control - CAN interface for PC (without local
💻 C
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************//
// 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 + -