43#include <sys/socket.h> 
   63#include <linux/net_tstamp.h> 
   64#include <linux/sockios.h> 
   67#include <linux/can/raw.h> 
  121#define READER_DEFAULT_PRIO 97 
  124#define WRITER_DEFAULT_PRIO 97 
  127#define MAX_WQ_MESSAGES 32 
  130#define MAX_QR_MESSAGES 32 
  171    unsigned char length;
 
  172    unsigned char received_length;
 
  179    struct timeval tv_request;
 
  181    unsigned long tm_inhibit_us;    
 
  182    unsigned short urcnt;  
 
  185    unsigned short ircnt;  
 
  187    unsigned char w_echo;  
 
 
  203    pthread_mutex_t mutex;
 
 
  210    char *interface_name;
 
  212    int interface_index_valid;
 
  214    unsigned int bitrate; 
 
 
  229static bool socan_use_rt_priority= 
true;
 
  230static bool socan_require_rt_priority= 
false;
 
  238static pthread_mutex_t global_semaphore;
 
  241static unsigned char can_ports_no= 0;
 
  243static int thread_count=0;
 
  249static int errprintlevel= 1;
 
  256static void errprint(
int level, 
const char *function, 
const int line,
 
  263    if (level>errprintlevel)
 
  265    va_start(args, format);
 
  266    snprintf(mypre, 80, 
"socan error in %s (line %d): ", function, line);
 
  267    vsnprintf(mymsg, 240, format, args);
 
  268    fprintf(stderr, 
"%s%s", mypre, mymsg);
 
  272#define ERRPRINT(lv, ...) errprint(lv, __func__, __LINE__, __VA_ARGS__) 
  274#define ERRPRINT_FUNC(lv, FUNC, ...) errprint(1, FUNC, __LINE__, __VA_ARGS__) 
  276#define ERRPRINT_ERRNO(syscall) \ 
  277  errprint(1, __func__, __LINE__, \ 
  278           syscall " failed, errno %d (%s)\n", errno, strerror(errno)) 
  280#define ERRPRINT_RC(syscall, rc) \ 
  281  errprint(1, __func__, __LINE__, \ 
  282           syscall " failed, error %d (%s)\n", rc, strerror(rc)) 
  284#define ERRPRINT_RC_FUNC(FUNC, syscall, rc) \ 
  285  errprint(1, FUNC, __LINE__, \ 
  286           syscall " failed, error %d (%s)\n", rc, strerror(rc)) 
  296      errprintlevel= level;
 
  297    return errprintlevel;
 
 
  304static int tracelevel= 0;
 
  310static void trace(
int level, 
char *format, ...)
 
  314    if (level>tracelevel)
 
  316    va_start(args, format);
 
  317    vprintf(format, args);
 
  321static void trace_object(
int level,
 
  326                         const struct can_frame *frame_)
 
  330    if (level>tracelevel)
 
  335        snprintf(databuf, 30, 
"CAN-LENGTH-OVERFLOW");
 
  341        for (i = 0; i < frame_->can_dlc; i++)
 
  345            sprintf(p, 
"%02X", frame_->data[i]);
 
  350    printf(
"(%s) port:%d t:%ld.%06ld  cob:0x%03X data: %s\n",
 
  351            TASK, port, obj->tv.tv_sec, obj->tv.tv_usec, cob, databuf);
 
  370#define CCODE(x) if (rc==x) return(#x) 
  390    ERRPRINT(1, 
"unexpected return code: %d\n", rc);
 
  391    return(
"UNKNOWN ERROR CODE!");
 
 
  432          ERRPRINT(1, 
"unexpected return code: %d\n", rc);
 
 
  445static bool check_len(
unsigned char len, 
const char *func)
 
  449        ERRPRINT_FUNC(2, func, 
"len %d invalid", len);
 
  455static bool check_cob(
unsigned short cob, 
const char *func)
 
  459        ERRPRINT_FUNC(2, func, 
"cob %d invalid", cob);
 
  465static socan_rc check_get_cob(
unsigned short cob, 
const char *func,
 
  472        ERRPRINT_FUNC(2, func, 
"cob %d invalid", cob);
 
  475    *obj= cob_dict_lookup(cp->dict, cob);
 
  482            ERRPRINT_FUNC(2, func, 
"can object for cob %d is not defined", cob);
 
  486    if ((*obj)->hdl_s == NULL)
 
  492            ERRPRINT_FUNC(2, func, 
"can object for cob %d has no owner", cob);
 
  499static bool check_get_port(
unsigned char port, 
const char *func, 
can_port **cp)
 
  501    if (port>=can_ports_no)
 
  503        ERRPRINT_FUNC(2, func, 
"port %d invalid", port);
 
  506    *cp= &(can_ports[port]);
 
  514static void tv_to_str(
const struct timeval *tv, 
char *buf, 
int buflen)
 
  520    nowtime = tv->tv_sec;
 
  521    localtime_r(&nowtime, &nowtm);
 
  522    len= strftime(buf, buflen, 
"%Y-%m-%d %H:%M:%S", &nowtm);
 
  523    snprintf(buf+len, buflen-len, 
".%06ld", tv->tv_usec);
 
  526static void us_to_tv(
unsigned long tv_us, 
struct timeval *tv)
 
  528    ldiv_t d= ldiv(tv_us, 1000000);
 
  533static unsigned long tv_to_us(
const struct timeval *tv)
 
  535    return tv->tv_sec * 1000000 + tv->tv_usec;
 
  538static unsigned long tv_to_ms(
const struct timeval *tv)
 
  540    return tv->tv_sec * 1000 + tv->tv_usec / 1000;
 
  543static unsigned long tm_ms_now(
void)
 
  549    gettimeofday(&now, NULL);
 
  550    return tv_to_ms(&now);
 
  553static unsigned long tm_us_now(
void)
 
  557    gettimeofday(&now, NULL);
 
  558    return tv_to_us(&now);
 
  561static unsigned long tm_ms_diff_to_now(
const struct timeval *tv)
 
  564    return tm_ms_now() - tv_to_ms(tv);
 
  567static void tv_now(
struct timeval *tv)
 
  569    gettimeofday(tv, NULL);
 
  572static void calc_abs_timeout(
int timeout_ms, 
struct timespec *ts)
 
  587    gettimeofday(&now, NULL);
 
  588    ts->tv_sec= now.tv_sec + s;
 
  589    ts->tv_nsec= now.tv_usec * 1000 + ms * 1000000;
 
  590    if (ts->tv_nsec >= 1000000000)
 
  592        ts->tv_nsec-= 1000000000;
 
  597static void mldelay(
long milliseconds)
 
  600  { 
struct timespec rq,rt;
 
  603    if (milliseconds >= 1000L)
 
  604      { rq.tv_sec = milliseconds / 1000L;
 
  605        rq.tv_nsec= (milliseconds-1000L*rq.tv_sec) * 1000000L;
 
  609        rq.tv_nsec= milliseconds * 1000000L;
 
  611    nanosleep( &rq, &rt);
 
  619#define THREAD_NAMELEN 16 
  621static char *thread_suffix(
bool is_reader, 
int port)
 
  623    static char buffer[THREAD_NAMELEN];
 
  626      snprintf(buffer, THREAD_NAMELEN, 
"-r%d", port);
 
  628      snprintf(buffer, THREAD_NAMELEN, 
"-w%d", port);
 
  633static bool get_curr_prio(
int *policy, 
int *min_prio, 
int *max_prio,
 
  643    struct sched_param param;
 
  644    rc= pthread_getschedparam(pthread_self(), policy, ¶m);
 
  647        ERRPRINT_RC(
"pthread_getschedparam", rc);
 
  650    *max_prio= sched_get_priority_max(*policy);
 
  651    *min_prio= sched_get_priority_min(*policy);
 
  652    *curr_prio= param.sched_priority;
 
  656static bool init_attr_p(pthread_attr_t *attr_p, 
int stack, 
int prio)
 
  668    int curr_policy, min_prio, max_prio, curr_prio;
 
  669    struct sched_param s_param;
 
  671    rc= pthread_attr_init(attr_p);
 
  674        ERRPRINT_RC(
"pthread_attr_init", rc);
 
  678#ifndef PTHREAD_STACK_MIN 
  679#define PTHREAD_STACK_MIN 16384 
  681    rc= pthread_attr_setstacksize(attr_p,
 
  682              (stack < PTHREAD_STACK_MIN) ? PTHREAD_STACK_MIN : stack);
 
  685        ERRPRINT_RC(
"pthread_attr_setstacksize", rc);
 
  690    if (!get_curr_prio(&curr_policy, &min_prio, &max_prio, &curr_prio))
 
  695        rc= pthread_attr_setschedpolicy(attr_p, curr_policy);
 
  698            ERRPRINT_RC(
"pthread_attr_setschedpolicy", rc);
 
  701        rc = pthread_attr_setinheritsched(attr_p, PTHREAD_INHERIT_SCHED);
 
  704            ERRPRINT_RC(
"pthread_attr_setinheritsched", rc);
 
  707        s_param.sched_priority= curr_prio;
 
  708        rc= pthread_attr_setschedparam(attr_p, &s_param);
 
  711            ERRPRINT_RC(
"pthread_attr_setschedparam", rc);
 
  717        rc= pthread_attr_setschedpolicy(attr_p, SCHED_FIFO);
 
  720            ERRPRINT_RC(
"pthread_attr_setschedpolicy", rc);
 
  727        rc = pthread_attr_setinheritsched(attr_p, PTHREAD_EXPLICIT_SCHED);
 
  730            ERRPRINT_RC(
"pthread_attr_setinheritsched", rc);
 
  733        s_param.sched_priority= prio;
 
  734        rc= pthread_attr_setschedparam(attr_p, &s_param);
 
  737            ERRPRINT_RC(
"pthread_attr_setschedparam", rc);
 
  744static bool thread_start(
void *(*th)(
void*), pthread_t *pst,
 
  753    char thread_name[THREAD_NAMELEN];
 
  760        rc = pthread_getname_np(pthread_self(), thread_name, THREAD_NAMELEN);
 
  763            ERRPRINT_RC(
"pthread_getname_np", rc);
 
  767        l= strlen(thread_name);
 
  769        if (m>THREAD_NAMELEN-1)
 
  771        if (l+m > THREAD_NAMELEN-1)
 
  772          l= THREAD_NAMELEN-1 - m;
 
  773        strncpy(thread_name+l, suffix, m);
 
  774        thread_name[THREAD_NAMELEN-1]= 0;
 
  777    if (!socan_use_rt_priority)
 
  780    if (!init_attr_p(&attr, stack, prio))
 
  782        ERRPRINT(1, 
"init_attr");
 
  786    rc = pthread_create( pst, &attr, th, arg);
 
  787    if ((rc==EPERM) && (prio>=0)) 
 
  789        if (socan_require_rt_priority)
 
  791            ERRPRINT(1, 
"Error: creating thread %s with policy\n" 
  792                    "\tSCHED_FIFO and priority %d failed.\n",
 
  796        ERRPRINT(1, 
"Warning: creating thread with policy\n" 
  797                    "\tSCHED_FIFO and priority %d failed.\n" 
  798                    "\tUsing SCHED_OTHER and priority 0 from now on.\n",
 
  801        socan_use_rt_priority= 
false;
 
  804        if (!init_attr_p(&attr, stack, -1))
 
  807        rc = pthread_create( pst, &attr, th, arg);
 
  811        ERRPRINT_RC(
"pthread_create", rc);
 
  816        rc = pthread_setname_np(*pst, thread_name);
 
  819            ERRPRINT_RC(
"pthread_setname_np", rc);
 
  830static bool mutex_init(pthread_mutex_t *mutex)
 
  835    pthread_mutexattr_t mutexattr;
 
  837    rc= pthread_mutexattr_init(&mutexattr);
 
  840        ERRPRINT_RC(
"pthread_mutexattr_init", rc);
 
  843    rc= pthread_mutexattr_setprotocol(&mutexattr, PTHREAD_PRIO_INHERIT);
 
  846        ERRPRINT_RC(
"pthread_mutexattr_setprotocol", rc);
 
  849    rc= pthread_mutex_init(mutex, &mutexattr);
 
  852        ERRPRINT_RC(
"pthread_mutex_init", rc);
 
  858static bool mutex_delete(pthread_mutex_t *mutex)
 
  862    rc= pthread_mutex_destroy(mutex);
 
  865        ERRPRINT_RC(
"pthread_mutex_destroy", rc);
 
  871static bool mutex_lock(pthread_mutex_t *mutex, 
const char *func)
 
  873    int rc= pthread_mutex_lock(mutex);
 
  876    ERRPRINT_RC_FUNC(func, 
"pthread_mutex_lock", rc);
 
  880static bool mutex_unlock(pthread_mutex_t *mutex, 
const char *func)
 
  882    int rc= pthread_mutex_unlock(mutex);
 
  885    ERRPRINT_RC_FUNC(func, 
"pthread_mutex_unlock", rc);
 
  889#define MUTEX_LOCK(mutex) mutex_lock(mutex, __func__) 
  891#define MUTEX_UNLOCK(mutex) mutex_unlock(mutex, __func__) 
  919static bool squeue_init(
squeue *q, 
unsigned int elements)
 
  926    if (!mutex_init(&(q->
qmutex)))
 
  928        ERRPRINT(1, 
"mutex_init failed\n");
 
  931    if (sem_init(&(q->
qsem), 0, 0)) 
 
  933        ERRPRINT_ERRNO(
"sem_init");
 
  934        mutex_delete(&(q->
qmutex));
 
  944static int squeue_inc(
const squeue *q, 
int index)
 
  953static bool squeue_delete(
squeue *q)
 
  956    if (!mutex_delete(&(q->
qmutex)))
 
  958        ERRPRINT(1, 
"mutex_delete failed\n");
 
  961    if (sem_destroy(&(q->
qsem)))
 
  963        ERRPRINT_ERRNO(
"sem_destroy");
 
  970static bool squeue_add(
squeue *q, 
unsigned short cob, 
unsigned char port)
 
  982        MUTEX_UNLOCK(&(q->
qmutex));
 
  990    if (sem_post(&(q->
qsem)))
 
  991      ERRPRINT_ERRNO(
"sem_post");
 
  992    MUTEX_UNLOCK(&(q->
qmutex));
 
  996static void squeue_get(
squeue *q, 
unsigned short *cob, 
unsigned char *port)
 
 1007        if (sem_wait(&(q->
qsem)))
 
 1009            ERRPRINT_ERRNO(
"sem_wait");
 
 1012        MUTEX_LOCK(&(q->
qmutex));
 
 1017        MUTEX_UNLOCK(&(q->
qmutex));
 
 1019    elm= &(q->
data[q->head]);
 
 1021    *port= (
unsigned char)(elm->
port);
 
 1022    q->head= squeue_inc(q, q->head);
 
 1023    if (q->head == q->
tail)
 
 1025    MUTEX_UNLOCK(&(q->
qmutex));
 
 1032static bool interface_exists(
const char *device)
 
 1042    snprintf(buf, 
sizeof(buf), 
"ip link show %s 2>&1", device);
 
 1043    cmd=popen(buf, 
"r");
 
 1044    while (fgets(buf, 
sizeof(buf), cmd) !=NULL)
 
 1078static bool socan_is_virtual_interface(
const char *device)
 
 1085    int rc= sscanf(device, 
"vcan%d%c", &dummy, &dummy2);
 
 1098    if (!check_get_port(port, __func__, &cp))
 
 1113        cp->bitrate= *bitrate;
 
 1118    if (cp->bitrate != 0)
 
 1120        *bitrate= cp->bitrate;
 
 1124    snprintf(buf, 
sizeof(buf), 
"ip -details link show %s",
 
 1125             cp->interface_name);
 
 1126    cmd=popen(buf, 
"r");
 
 1127    while (fgets(buf, 
sizeof(buf), cmd) !=NULL)
 
 1130        sscanf(buf, 
" bitrate %ud ", bitrate);
 
 1136        cp->bitrate= *bitrate;
 
 
 1158        ERRPRINT(1, 
"socan is not initialized\n");
 
 1161    MUTEX_LOCK(&global_semaphore);
 
 1163    if (sem_init(&(t->thread_sem), 0, 1)) 
 
 1165        ERRPRINT_ERRNO(
"sem_init");
 
 1167        MUTEX_UNLOCK(&global_semaphore);
 
 1170    rc= pthread_mutex_init(&(t->mutex), NULL);
 
 1173        ERRPRINT_RC(
"pthread_mutex_init", rc);
 
 1174        if (sem_destroy(&(t->thread_sem)))
 
 1175          ERRPRINT_ERRNO(
"sem_destroy");
 
 1177        MUTEX_UNLOCK(&global_semaphore);
 
 1182        ERRPRINT(1, 
"squeue_init failed\n");
 
 1183        if (sem_destroy(&(t->thread_sem)))
 
 1184          ERRPRINT_ERRNO(
"sem_destroy");
 
 1185        if (!mutex_delete(&(t->mutex)))
 
 1186          ERRPRINT(1, 
"mutex_delete failed\n");
 
 1188        MUTEX_UNLOCK(&global_semaphore);
 
 1192    MUTEX_UNLOCK(&global_semaphore);
 
 
 1204    h->is_active= 
false; 
 
 1207    MUTEX_LOCK(&global_semaphore);
 
 1208    if ((rc= pthread_mutex_destroy(&(h->mutex))))
 
 1209      ERRPRINT_RC(
"pthread_mutex_destroy", rc);
 
 1210    if (sem_destroy(&(h->thread_sem)))
 
 1212        ERRPRINT_ERRNO(
"sem_destroy");
 
 1215    for(port=0; port<can_ports_no; port++)
 
 1217        cob_dict *dict= can_ports[port].dict;
 
 1218        for(cob=0; cob<
COB_NO; cob++)
 
 1220            obj= cob_dict_lookup(dict, cob);
 
 1223            if (obj->hdl_s != h)
 
 1229    MUTEX_UNLOCK(&global_semaphore);
 
 
 1237    if (!check_get_port(port, __func__, &cp))
 
 1239    *dev= cp->interface_name;
 
 
 1247    if (sem_getvalue(&(h->thread_sem), &sval))
 
 1249        ERRPRINT_ERRNO(
"sem_getvalue");
 
 1254    if (sem_post(&(h->thread_sem)))
 
 1256        ERRPRINT_ERRNO(
"sem_post");
 
 1261static int socan_hdl_wait_tmo(
socan_hdl h, 
struct timespec *ts)
 
 1268    int rc= sem_timedwait(&(h->thread_sem), ts);
 
 1272    if (errno==ETIMEDOUT)
 
 1274    ERRPRINT_ERRNO(
"sem_timedwait");
 
 1286                              unsigned char length,
 
 1287                              unsigned int tmo_ms,
 
 1290    if (!check_len(length, __func__))
 
 1292    if (!check_cob(cob, __func__))
 
 1299    obj->length= length;
 
 1308    obj->tmo_ms= tmo_ms;
 
 1314    obj->user_ptr= NULL;
 
 1321    void *up= obj->user_ptr;
 
 1323    obj->user_ptr= NULL;
 
 1329static unsigned char *canobj_rtr_wbuf(
struct socan_obj_s *obj)
 
 1331    if (obj->use_buffer2)
 
 1332      return obj->buffer2;
 
 1336static unsigned char *canobj_rtr_wbuf_other(
struct socan_obj_s *obj)
 
 1338    if (obj->use_buffer2)
 
 1340    return obj->buffer2;
 
 1343static void canobj_rtr_switch(
struct socan_obj_s *obj)
 
 1345    if (obj->use_buffer2)
 
 1346      obj->use_buffer2= 
false;
 
 1348      obj->use_buffer2= 
true;
 
 1358    return calloc(1, 
sizeof(
cob_dict));
 
 1361void cob_dict_delete(
cob_dict *dict)
 
 1368    if (!check_cob(cob, __func__))
 
 1370    return (dict->objects)[cob];
 
 1373static bool cob_dict_set(
cob_dict *dict, 
unsigned short cob, 
void *ptr)
 
 1376    if (!check_cob(cob, __func__))
 
 1378    (dict->objects)[cob]= ptr;
 
 1382static bool cob_dict_remove(
cob_dict *dict, 
unsigned short cob)
 
 1385    if (!check_cob(cob, __func__))
 
 1387    (dict->objects)[cob]= NULL;
 
 1403        ERRPRINT(2, 
"cannot add ports in INITIALIZED state\n");
 
 1406    if (socan_state == 
ERROR)
 
 1408        ERRPRINT(2, 
"cannot add ports in ERROR state\n");
 
 1414        ERRPRINT(2, 
"too many ports\n");
 
 1417    if (!interface_exists(devicename))
 
 1419        ERRPRINT(2, 
"interface '%s' doesn't exist\n", devicename);
 
 1422    cp= &(can_ports[can_ports_no]);
 
 1423    cp->interface_name= strdup(devicename);
 
 1424    cp->interface_index_valid= 0;
 
 1425    cp->interface_index= 0;
 
 1426    cp->dict= cob_dict_new();
 
 1427    cp->port= can_ports_no;
 
 1429    cp->is_virtual= socan_is_virtual_interface(devicename);
 
 1432        ERRPRINT(1, 
"squeue_init failed\n");
 
 
 1440static int can_port_interface_index(
can_port *cp, 
int sock)
 
 1445    if (!cp->interface_index_valid)
 
 1447        MUTEX_LOCK(&global_semaphore);
 
 1449        strcpy(ifr.ifr_name, cp->interface_name);
 
 1450        ioctl(sock, SIOCGIFINDEX, &ifr);
 
 1451        cp->interface_index= ifr.ifr_ifindex;
 
 1452        cp->interface_index_valid= 1;
 
 1453        MUTEX_UNLOCK(&global_semaphore);
 
 1455    i= cp->interface_index;
 
 1460                       unsigned short cob, 
unsigned char length,
 
 1466    if (!check_get_port(port, __func__, &cp))
 
 1468    if (!check_cob(cob, __func__))
 
 1470    if (!check_len(length, __func__))
 
 1472    MUTEX_LOCK(&global_semaphore);
 
 1473    obj= cob_dict_lookup(cp->dict, cob);
 
 1476        if ((obj->hdl_s == hdl) && (obj->length == length) &&
 
 1477            (obj->type == type) && (obj->tmo_ms == tmo_ms))
 
 1481            MUTEX_UNLOCK(&global_semaphore);
 
 1484        if ((obj->hdl_s !=NULL) && (obj->hdl_s != hdl)) 
 
 1487            MUTEX_UNLOCK(&global_semaphore);
 
 1491        ERRPRINT(2, 
"CAN object cob %d port %d already exists\n",
 
 1493        MUTEX_UNLOCK(&global_semaphore);
 
 1496    obj= canobj_new(hdl, port, cob, length, tmo_ms, type);
 
 1497    cob_dict_set(cp->dict, cob, obj);
 
 1498    MUTEX_UNLOCK(&global_semaphore);
 
 
 1507    if (!check_get_port(port, __func__, &cp))
 
 1509    if (!check_cob(cob, __func__))
 
 1511    MUTEX_LOCK(&global_semaphore);
 
 1512    obj= cob_dict_lookup(cp->dict, cob);
 
 1516        cob_dict_remove(cp->dict, cob);
 
 1519    MUTEX_UNLOCK(&global_semaphore);
 
 
 1524                        unsigned char port, 
unsigned short cob,
 
 1525                        unsigned char *length,
 
 1526                        unsigned int *tmo_ms,
 
 1534    if (!check_get_port(port, __func__, &cp))
 
 1536    if (!check_cob(cob, __func__))
 
 1538    rc= check_get_cob(cob, __func__, cp, &obj, 
false);
 
 1541    if (obj->hdl_s != hdl)
 
 1543    *length= obj->length;
 
 1544    *tmo_ms= obj->tmo_ms;
 
 
 1554    unsigned long us1, us2;
 
 1557    if (!check_get_port(port, __func__, &cp))
 
 1559    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1565         us1= tv_to_us(&(obj->tv));
 
 1566         us2= tv_to_us(&(obj->tv));
 
 1567       } 
while (us1 != us2);
 
 
 1576    tv_to_str(&tv, buf, buflen);
 
 
 1586    if (!check_get_port(port, __func__, &cp))
 
 1588    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1593        ERRPRINT(2, 
"cob %d is not an ordinary write object\n", cob);
 
 1596    obj->tm_inhibit_us= inhibit_time;
 
 
 1607    if (!check_get_port(port, __func__, &cp))
 
 1609    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1614        ERRPRINT(2, 
"cob %d is not a read or rtr-read object\n", cob);
 
 1617    obj->use_queue= 
true;
 
 
 1630    if (!check_get_port(port, __func__, &cp))
 
 1632    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1635    if (obj->user_ptr != NULL)
 
 1636      free(obj->user_ptr);
 
 1637    obj->user_ptr= calloc(1, size);
 
 1638    *area= obj->user_ptr;
 
 
 1649    if (!check_get_port(port, __func__, &cp))
 
 1651    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1654    *area= obj->user_ptr;
 
 
 1665    if (!check_get_port(port, __func__, &cp))
 
 1667    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 
 1682    if (!check_get_port(port, __func__, &cp))
 
 1684    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1688    obj->user_ptr= NULL;
 
 
 1717    if (!check_get_port(port, __func__, &cp))
 
 1719    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1724        ERRPRINT(2, 
"cob %d is not a read object\n", cob);
 
 1731         rlen= obj->received_length;
 
 1732         memcpy(data, obj->buffer, obj->length);
 
 1733       } 
while (ircnt != obj->ircnt);
 
 1736        if (obj->urcnt == ircnt)
 
 1741        if (rlen != obj->length)
 
 1746        if ((
unsigned short)(ircnt - obj->urcnt) > 1)
 
 
 1778    if (!check_get_port(port, __func__, &cp))
 
 1780    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1787          obj->urcnt= obj->ircnt;
 
 1788          calc_abs_timeout(obj->tmo_ms, &ts);
 
 1789          if (!squeue_add(&(cp->writer_squeue), cob, port))
 
 1791              ERRPRINT(3, 
"squeue_add failed, queue full " 
 1792                          "(size %d) port:%d cob:%d\n",
 
 1793                       cp->writer_squeue.
elements, port, cob);
 
 1798              rc_i= socan_hdl_wait_tmo(hdl, &ts);
 
 1806              if (obj->urcnt != obj->ircnt)
 
 1811          if (obj->urcnt == obj->ircnt)
 
 1813              calc_abs_timeout(obj->tmo_ms, &ts);
 
 1816                  trace(1, 
"  read: wait on semaphore\n");
 
 1817                  rc_i= socan_hdl_wait_tmo(hdl, &ts);
 
 1818                  trace(1, 
"  read: semaphore wait returned: %d\n", rc_i);
 
 1819                  if ((rc_i==1) || (rc_i==-1)) 
 
 1821                  if (obj->urcnt != obj->ircnt)
 
 1831          ERRPRINT(2, 
"cob %d is not a read object\n", cob);
 
 1840         rlen= obj->received_length;
 
 1841         memcpy(data, obj->buffer, obj->length);
 
 1842       } 
while (ircnt != obj->ircnt);
 
 1845        if (rlen != obj->length)
 
 1850        if (obj->urcnt == ircnt)
 
 1855        if ((
unsigned short)(ircnt - obj->urcnt) > 1)
 
 
 1868                          unsigned short *cob, 
void *data)
 
 1873    unsigned short cob_;
 
 1874    unsigned char port_;
 
 1880        squeue_get(&(hdl->qread_queue), &cob_, &port_);
 
 1881        if (!check_get_port(port_, __func__, &cp))
 
 1883        rc= check_get_cob(cob_, __func__, cp, &obj, 
true);
 
 1886        if (!obj->use_queue)
 
 1888            ERRPRINT(2, 
"not a qread object: %d port %d\n", cob_, port_);
 
 1892        if (obj->urcnt == obj->ircnt)
 
 1900             rlen= obj->received_length;
 
 1901             memcpy(data, obj->buffer, obj->length);
 
 1902           } 
while (ircnt != obj->ircnt);
 
 1905        trace(1, 
"  queue_read: port:%d cob:%d urcnt:%d ircnt:%d\n",
 
 1906              port_, cob_, obj->urcnt, ircnt);
 
 1909            if (rlen != obj->length)
 
 1914            if ((
unsigned short)(ircnt - obj->urcnt) > 1)
 
 
 1928                     unsigned char port, 
unsigned short cob, 
const void *data)
 
 1943    if (!check_get_port(port, __func__, &cp))
 
 1945    rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 1952        ERRPRINT(2, 
"cob %d is not a write or RTR-read object\n", cob);
 
 1959        tv_now(&(obj->tv_request));
 
 1960        memcpy(canobj_rtr_wbuf_other(obj), data, obj->length);
 
 1963        canobj_rtr_switch(obj);
 
 1970    tv_now(&(obj->tv_request));
 
 1972    trace(1, 
"tm bef. write: %lu\n", tv_to_ms(&(obj->tv_request))); 
 
 1973    memcpy(obj->buffer, data, obj->length);
 
 1976    if (!squeue_add(&(cp->writer_squeue), cob, port))
 
 1978        ERRPRINT(3, 
"squeue_add failed, queue full " 
 1979                    "(size %d) port:%d cob:%d\n",
 
 1980                 cp->writer_squeue.
elements, port, cob);
 
 1983    calc_abs_timeout(obj->tmo_ms, &ts);
 
 1986        rc_i= socan_hdl_wait_tmo(hdl, &ts);
 
 1987        if ((rc_i==1) || (rc_i==-1)) 
 
 1992    trace(1, 
"tm aft. write: %lu\n", tm_ms_now()); 
 
 
 2001                          unsigned char port, 
unsigned short cob, 
const void *data)
 
 2019    if (!check_get_port(port, __func__, &cp))
 
 2021    my_rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 2028        ERRPRINT(2, 
"cob %d is not a write or RTR-read object\n", cob);
 
 2035        tv_now(&(obj->tv_request));
 
 2036        memcpy(canobj_rtr_wbuf(obj), data, obj->length);
 
 2039        canobj_rtr_switch(obj);
 
 2048        unsigned long tdelta= tm_ms_diff_to_now(&(obj->tv_request));
 
 2049        if (tdelta < obj->tmo_ms)
 
 2057    tv_now(&(obj->tv_request));
 
 2059    memcpy(obj->buffer, data, obj->length);
 
 2062    if (!squeue_add(&(cp->writer_squeue), cob, port))
 
 2064        ERRPRINT(3, 
"squeue_add failed, queue full " 
 2065                    "(size %d) port:%d cob:%d\n",
 
 2066                 cp->writer_squeue.
elements, port, cob);
 
 
 2073                             unsigned char port, 
unsigned short cob,
 
 2075                             unsigned long *inhibit_time)
 
 2089    unsigned long tm_us_next_write;
 
 2090    unsigned long tm_us_now_;
 
 2092    if (!check_get_port(port, __func__, &cp))
 
 2094    my_rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 2101        ERRPRINT(2, 
"cob %d is not a write or RTR-read object\n", cob);
 
 2109        tv_now(&(obj->tv_request));
 
 2110        memcpy(canobj_rtr_wbuf(obj), data, obj->length);
 
 2113        canobj_rtr_switch(obj);
 
 2121        unsigned long tdelta= tm_ms_diff_to_now(&(obj->tv_request));
 
 2122        if (tdelta < obj->tmo_ms)
 
 2125            *inhibit_time= obj->tm_inhibit_us;
 
 2132    tm_us_next_write= tv_to_us(&(obj->tv)) + obj->tm_inhibit_us;
 
 2133    tm_us_now_= tm_us_now();
 
 2134    if (tm_us_now_ < tm_us_next_write)
 
 2136        *inhibit_time= tm_us_next_write - tm_us_now_;
 
 2141    tv_now(&(obj->tv_request));
 
 2142    memcpy(obj->buffer, data, obj->length);
 
 2145    if (!squeue_add(&(cp->writer_squeue), cob, port))
 
 2147        ERRPRINT(3, 
"squeue_add failed, queue full " 
 2148                    "(size %d) port:%d cob:%d\n",
 
 2149                 cp->writer_squeue.
elements, port, cob);
 
 
 2159static int init_can_socket(
can_port *cp, 
int *sock)
 
 2162    struct sockaddr_can addr;
 
 2163    int interface_index;
 
 2167    if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
 
 2169        ERRPRINT_ERRNO(
"socket");
 
 2172    sval= SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_TX_HARDWARE;
 
 2173    if ((rc= setsockopt(s, SOL_SOCKET, SO_TIMESTAMPING, &sval, 
sizeof(sval))))
 
 2175        ERRPRINT_RC(
"setsockopt", rc);
 
 2178    interface_index= can_port_interface_index(cp, s);
 
 2179    if (interface_index==-1)
 
 2181        ERRPRINT(1, 
"can_port_interface_index failed\n");
 
 2185    memset(&addr, 0, 
sizeof(addr));
 
 2186    addr.can_family = AF_CAN;
 
 2187    addr.can_ifindex = interface_index;
 
 2190    if (bind(s, (
struct sockaddr *) &addr, 
sizeof(addr)) < 0)
 
 2192        ERRPRINT_ERRNO(
"bind");
 
 2199#define TASK "reader" 
 2200static void *reader(
void *arg)
 
 2204    unsigned char port= ((
can_port *)arg)->port;
 
 2207    struct can_frame frame;
 
 2208    static int read_can_device_rc= 0;
 
 2211    read_can_device_rc= init_can_socket(cp, &s);
 
 2212    if (read_can_device_rc!=0)
 
 2214        ERRPRINT(1, 
"init_can_socket failed: %d\n", read_can_device_rc);
 
 2218    MUTEX_LOCK(&global_semaphore);
 
 2220    MUTEX_UNLOCK(&global_semaphore);
 
 2224        int nbytes = read(s, &frame, 
sizeof(
struct can_frame));
 
 2230            ERRPRINT_ERRNO(
"read");
 
 2234        cob= frame.can_id & CAN_SFF_MASK; 
 
 2235        is_rtr= (frame.can_id & CAN_RTR_FLAG) ? 1 : 0;
 
 2236        rc= check_get_cob(cob, __func__, cp, &obj, 
false);
 
 2241        if (!obj->hdl_s->is_active)
 
 2247            trace(2, 
"(%s) ulock ! port:%d cob:0x%03X RTR:%1d",
 
 2248                  TASK, port, cob, is_rtr);
 
 2253        ioctl(s, SIOCGSTAMP, &(obj->tv));
 
 2260                  ERRPRINT(3, 
"  (%s) RTR on SOCAN_READ " 
 2262                              "port:%d cob:0x%03X RTR:%1d\n",
 
 2263                              TASK, port, cob, is_rtr);
 
 2268              memcpy(obj->buffer, frame.data, frame.can_dlc);
 
 2269              obj->received_length= frame.can_dlc;
 
 2272                  if (!squeue_add(&(obj->hdl_s->qread_queue), cob, port))
 
 2274                      ERRPRINT(3, 
"(task %s) " 
 2275                                  "squeue_add failed, queue full " 
 2276                                  "(size %d) port:%d cob:%d RTR:%1d\n",
 
 2278                               cp->writer_squeue.
elements, port, cob, is_rtr);
 
 2282              socan_hdl_give(obj->hdl_s);
 
 2291                      socan_hdl_give(obj->hdl_s);
 
 2299                  memcpy(obj->buffer, frame.data, frame.can_dlc);
 
 2300                  obj->received_length= frame.can_dlc;
 
 2303                      if (!squeue_add(&(obj->hdl_s->qread_queue), cob, port))
 
 2305                          ERRPRINT(3, 
"(task %s) " 
 2306                                      "squeue_add failed, queue full " 
 2307                                      "(size %d) port:%d cob:%d RTR:%1d\n",
 
 2314                  socan_hdl_give(obj->hdl_s);
 
 2320                  ERRPRINT(3, 
"  (%s) non-RTR on SOCAN_WRITE_RTR " 
 2322                              "port:%d cob:0x%03X RTR:%1d\n",
 
 2323                              TASK, port, cob, is_rtr);
 
 2328              if (!squeue_add(&(cp->writer_squeue), cob, port))
 
 2330                  ERRPRINT(3, 
"(task %s) " 
 2331                              "squeue_add failed, queue full " 
 2332                              "(size %d) port:%d cob:%d RTR:%1d\n",
 
 2334                           cp->writer_squeue.
elements, port, cob, is_rtr);
 
 2337              trace(2, 
"  (%s) create reply on received " 
 2339                       "port:%d cob:0x%03X RTR:%1d\n",
 
 2340                       TASK, port, cob, is_rtr);
 
 2345                  ERRPRINT(3, 
"  (%s) RTR on SOCAN_WRITE " 
 2347                              "port:%d cob:0x%03X RTR:%1d\n",
 
 2348                              TASK, port, cob, is_rtr);
 
 2355              trace(2, 
"  (%s) local echo of CAN write received " 
 2356                       "port:%d cob:0x%03X RTR:%1d\n",
 
 2357                       TASK, port, cob, is_rtr);
 
 2362                  socan_hdl_give(obj->hdl_s);
 
 2366        if (tracelevel >= 2)
 
 2367          trace_object(2, TASK, obj, port, cob, &frame);
 
 2372        ERRPRINT_ERRNO(
"close");
 
 2373        read_can_device_rc= 5;
 
 2379#define TASK "writer" 
 2380static void *writer(
void *arg)
 
 2383    unsigned char writer_port= cp->port;
 
 2385    static int write_can_device_rc= 0;
 
 2386    struct can_frame frame;
 
 2388    int can_frame_sz= 
sizeof(
struct can_frame);
 
 2392    memset(&frame, 0, 
sizeof(
struct can_frame));
 
 2394    write_can_device_rc= init_can_socket(cp, &s);
 
 2396    if (write_can_device_rc!=0)
 
 2398        ERRPRINT(1, 
"init_can_socket failed: %d\n", write_can_device_rc);
 
 2401    MUTEX_LOCK(&global_semaphore);
 
 2403    MUTEX_UNLOCK(&global_semaphore);
 
 2411        squeue_get(&(cp->writer_squeue), &cob, &port);
 
 2412        if (writer_port != port)
 
 2414            ERRPRINT(3, 
"port %d != %d\n", port, writer_port);
 
 2418        rc= check_get_cob(cob, __func__, cp, &obj, 
true);
 
 2423        if (!obj->hdl_s->is_active)
 
 2431              memcpy(frame.data, canobj_rtr_wbuf(obj), obj->length);
 
 2432              frame.can_dlc= obj->length;
 
 2436              frame.can_id= cob | CAN_RTR_FLAG;
 
 2437              memset(frame.data, 0, obj->length);
 
 2438              frame.can_dlc= obj->length;
 
 2449              memcpy(frame.data, obj->buffer, obj->length);
 
 2450              frame.can_dlc= obj->length;
 
 2454        trace(2, 
"(%s) port:%d cob:0x%03X ", TASK, port, cob);
 
 2456        for (i = 0; i < frame.can_dlc; i++)
 
 2457          trace(2, 
"%02X ", frame.data[i]);
 
 2460        if (write(s, &frame, can_frame_sz) != can_frame_sz)
 
 2462            ERRPRINT_ERRNO(
"write");
 
 2473                          bool require_rt_priority,
 
 2474                          int reader_priority,
 
 2475                          int writer_priority)
 
 2484    int min_prio, max_prio;
 
 2486    switch (socan_state)
 
 2489             ERRPRINT(1, 
"socan is in ERROR state, cannot setup realtime\n");
 
 2492             ERRPRINT(1, 
"socan is already initialized, " 
 2493                         "cannot setup realtime\n");
 
 2498             ERRPRINT(1, 
"unknown internal state: %d\n", socan_state);
 
 2502    if (use_rt_priority)
 
 2504        min_prio= sched_get_priority_min(SCHED_FIFO);
 
 2505        max_prio= sched_get_priority_max(SCHED_FIFO);
 
 2506        if ((reader_priority < min_prio) || (reader_priority > max_prio))
 
 2508            ERRPRINT(1, 
"Error, reader priority %d out of range " 
 2510                        reader_priority, min_prio, max_prio);
 
 2513        if ((writer_priority < min_prio) || (writer_priority > max_prio))
 
 2515            ERRPRINT(1, 
"Error, writer priority %d out of range " 
 2517                        writer_priority, min_prio, max_prio);
 
 2522    socan_use_rt_priority= use_rt_priority;
 
 2523    socan_require_rt_priority= require_rt_priority;
 
 2524    if (use_rt_priority)
 
 2526        socan_reader_priority= reader_priority;
 
 2527        socan_writer_priority= writer_priority;
 
 
 2536_Atomic 
static int _lock= 0;
 
 2548    if (socan_state == 
ERROR)
 
 2550    if (can_ports_no==0)
 
 2552        ERRPRINT(1, 
"no ports are defined\n");
 
 2564        if (socan_state == 
ERROR)
 
 2569    if (!mutex_init(&global_semaphore))
 
 2571        ERRPRINT(1, 
"mutex_init failed\n");
 
 2576    MUTEX_LOCK(&global_semaphore);
 
 2578    for (p=0; p<can_ports_no; p++)
 
 2581        if (!thread_start(reader, &(socan_read_threads[p]), 
 
 2582                          thread_suffix(
true, p),
 
 2584                          socan_reader_priority, 
 
 2587            ERRPRINT(1, 
"thread_start (reader) failed\n");
 
 2589            MUTEX_UNLOCK(&global_semaphore);
 
 2593        if (!thread_start(writer, &(socan_write_threads[p]), 
 
 2594                          thread_suffix(
false, p),
 
 2596                          socan_writer_priority,  
 
 2599            ERRPRINT(1, 
"thread_start (writer) failed\n");
 
 2601            MUTEX_UNLOCK(&global_semaphore);
 
 2607    MUTEX_UNLOCK(&global_semaphore);
 
 2610    for(n=can_ports_no;n>0;n--) 
 
 2613        MUTEX_LOCK(&global_semaphore);
 
 2614        if (thread_count >= can_ports_no*2)
 
 2617            MUTEX_UNLOCK(&global_semaphore);
 
 2620        MUTEX_UNLOCK(&global_semaphore);
 
 2625        ERRPRINT(1, 
"starting all threads took too long\n");
 
 
socan_rc socan_user_area(unsigned char port, unsigned short cob, void **area)
#define WRITER_DEFAULT_PRIO
absolute default priority of writer task
bool socan_close(socan_hdl h)
socan_rc socan_write_inhibit(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data, unsigned long *inhibit_time)
socan_rc socan_set_user_area(unsigned char port, unsigned short cob, void *ptr)
char * socan_str_rc(socan_rc rc)
bool socan_realtime_setup(bool use_rt_priority, bool require_rt_priority, int reader_priority, int writer_priority)
socan_rc socan_port_bitrate(unsigned char port, unsigned int *bitrate)
#define MAX_WQ_MESSAGES
max. number of CAN objects in writer queue
socan_rc socan_del_obj(unsigned char port, unsigned short cob)
socan_rc socan_read(socan_hdl hdl, unsigned char port, unsigned short cob, void *data)
int socan_errprintlevel(int level)
#define MAX_QR_MESSAGES
max. number of CAN objects in reader queue
socan_rc socan_obj_ts(unsigned char port, unsigned short cob, unsigned long *ts)
socan_rc socan_use_queue(unsigned char port, unsigned short cob)
socan_rc socan_readnow(socan_hdl hdl, unsigned char port, unsigned short cob, void *data)
socan_rc socan_set_inhibit(unsigned char port, unsigned short cob, unsigned long inhibit_time)
#define READER_DEFAULT_PRIO
absolute default priority of reader task
socan_rc socan_write(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data)
socan_rc socan_free_user_area(unsigned char port, unsigned short cob)
struct sq_elm sq_elm
type of a single element in the 'squeue' queue
int socan_add_port(const char *devicename)
bool socan_rc_is_error(socan_rc rc)
int socan_tracelevel(int level)
socan_hdl socan_open(void)
socan_rc socan_port_device(unsigned char port, char **dev)
socan_rc socan_queue_read(socan_hdl hdl, unsigned char *port, unsigned short *cob, void *data)
socan_rc socan_ts_to_str(unsigned long ts, char *buf, int buflen)
socan_rc socan_add_obj(socan_hdl hdl, unsigned char port, unsigned short cob, unsigned char length, unsigned int tmo_ms, socan_obj_type type)
socan_module_state
state of the socan module
socan_rc socan_writelater(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data)
socan_rc socan_obj_info(socan_hdl hdl, unsigned char port, unsigned short cob, unsigned char *length, unsigned int *tmo_ms, socan_obj_type *type)
socan_rc socan_new_user_area(unsigned char port, unsigned short cob, unsigned int size, void **area)
c header file for socan object layer library.
#define SOCAN_FRAME_LENGTH
type of a single element in the 'squeue' queue