int can_cpc_close(can_cpc_device_p dev) { if (!CPC_CANExit(dev->handle, 0) && !CPC_CloseChannel(dev->handle)) { dev->name[0] = 0; dev->fd = -1; } else return CAN_CPC_ERROR_CLOSE; return CAN_CPC_ERROR_NONE; }
/** * Open given CAN channel * @param ucChannel channel name or device fiel */ int CPC_OpenChannel(char *ucChannel) { static unsigned int firstCall = 1; CPC_MSG_T msg; unsigned int slot, i; int retval, fd; #ifdef _CPC_CONF_INI char *sectionList[32]; char valueBuffer[50]; int sectionCount; int minor = 0; int tmp = 0; int found = 0; unsigned char configIrq = 0; unsigned int irqNr; #endif int intf = 0; char *devFile = NULL; // Initialize internal structures on first call if (firstCall) { for (i = 0; i < CAN_MAX_DEVICE; i++) { CPC_SJA1000_PARAMS_T *p = &CPCInitParams[i].canparams.cc_params.sja1000; CPCHandlerCnt[i] = 0; CPCInitParams[i].chanparams.fd = -1; CPCInitParams[i].canparams.cc_type = SJA1000; p->acc_code0 = p->acc_code1 = p->acc_code2 = p->acc_code3 = 0x55; p->acc_mask0 = p->acc_mask1 = p->acc_mask2 = p->acc_mask3 = 0xFF; p->mode = p->btr0 = p->btr1 = p->outp_contr = 0x00; CPCHandlerCnt[i] = 0; } firstCall = 0; } // Find free slot for (slot = 0; slot < CAN_MAX_DEVICE; slot++) { if (CPCInitParams[slot].chanparams.fd == -1) break; } if (slot >= CAN_MAX_DEVICE) return CPC_ERR_NO_FREE_CHANNEL; #ifdef _CPC_CONF_INI // Get section list from cpcconf.ini tmp = sectionCount = ini_get_section_list(CPC_CONF_INI_PATH, §ionList[0], 32); // cpcconf.ini not found if (sectionCount <= 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: File '%s' not found or empty\n", __PRETTY_FUNCTION__, CPC_CONF_INI_PATH); return CPC_ERR_NO_INIFILE_PRESENT; } retval = 0; // Iterate over every section and try to find ucChannel for (--sectionCount; sectionCount >= 0; sectionCount--) { if (strcmp(ucChannel, sectionList[sectionCount]) == 0) { // ucChannel found now search InterfaceType to determine the right settings */ if (!ini_get_key_value(sectionList[sectionCount], "InterfaceType", CPC_CONF_INI_PATH, valueBuffer, sizeof(valueBuffer))) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: 'InterfaceType' was not found in" "'%s::%s'\n", __PRETTY_FUNCTION__, CPC_CONF_INI_PATH, sectionList[sectionCount]); retval = CPC_ERR_WRONG_PARAMETERS; break; } if (BE_DEBUG) printf("CPCLIB[%s]: Channel '%s' and interface '%s' found\n", __PRETTY_FUNCTION__, ucChannel, valueBuffer); found = 1; intf = _CPC_InterfaceStrToNumber(valueBuffer); // Check if interface type is known switch (intf) { case CPCCARD: /* CPC-ECO Card */ minor = _CPC_DetermineDeviceFile(ucChannel, intf); if (minor < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: ERROR _CPC_DetermineDeviceFile()" " returned %d\n", __PRETTY_FUNCTION__, minor); retval = CPC_ERR_NO_MATCHING_CHANNEL; break; } sprintf(valueBuffer, "/dev/cpc_card%d", minor); devFile = valueBuffer; break; case CPCXT200: case CPCXT1000: /* CPC-XT Card */ minor = _CPC_DetermineDeviceFile(ucChannel, intf); if (minor < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: ERROR _CPC_DetermineDeviceFile()" " returned %d\n", __PRETTY_FUNCTION__, minor); retval = CPC_ERR_NO_MATCHING_CHANNEL; break; } sprintf(valueBuffer, "/dev/cpc_xt%d", minor); devFile = valueBuffer; configIrq = 1; break; case CPCPCI: /* CPC-PCI Card */ minor = _CPC_DetermineDeviceFile(ucChannel, intf); if (minor < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: ERROR _CPC_DetermineDeviceFile()" " returned %d\n", __PRETTY_FUNCTION__, minor); retval = CPC_ERR_NO_MATCHING_CHANNEL; break; } sprintf(valueBuffer, "/dev/cpc_pci%d", minor); devFile = valueBuffer; break; case CPCUSB: /* CPC-USB device */ minor = _CPC_DetermineDeviceFile(ucChannel, intf); if (minor < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: ERROR _CPC_DetermineDeviceFile()" " returned %d\n", __PRETTY_FUNCTION__, minor); retval = CPC_ERR_NO_MATCHING_CHANNEL; break; } sprintf(valueBuffer, "/dev/usb/cpc_usb%d", minor); devFile = valueBuffer; break; case CPCECO: /* CPC-ECO device */ minor = _CPC_DetermineDeviceFile(ucChannel, intf); if (minor < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: ERROR _CPC_DetermineDeviceFile()" " returned %d\n", __PRETTY_FUNCTION__, minor); retval = CPC_ERR_NO_MATCHING_CHANNEL; break; } sprintf(valueBuffer, "/dev/cpc_eco%d", minor); devFile = valueBuffer; break; case ETHERCAN: /* Remote EtherCAN Interface */ { char ip[32], port[10]; if (ini_get_key_value(sectionList[sectionCount], "IpAddress", CPC_CONF_INI_PATH, ip, sizeof(ip))) { sprintf(valueBuffer, "%s:", ip); if (ini_get_key_value(sectionList[sectionCount], "IpPort", CPC_CONF_INI_PATH, port, sizeof(port))) { strcat(valueBuffer, port); devFile = valueBuffer; break; } } retval = CPC_ERR_WRONG_PARAMETERS; } break; #ifdef SOCKETCAN_SUPPORT case SOCKETCAN: { char iface[16]; if (ini_get_key_value(sectionList[sectionCount], "NetworkInterface", CPC_CONF_INI_PATH, iface, sizeof(iface))) { strcpy(valueBuffer, iface); devFile = valueBuffer; break; } retval = CPC_ERR_WRONG_PARAMETERS; } break; #endif case NONE: default: if (BE_INFORMATIVE) printf("CPCLIB[%s]: Unsupported interface '%s'\n", __PRETTY_FUNCTION__, valueBuffer); retval = CPC_ERR_NO_MATCHING_INTERFACE; break; } break; } } // For backward compatibility we provide the old device-file style access #ifndef _CPC_LIB_COMPAT_MODE if (!found) retval = CPC_ERR_NO_MATCHING_INTERFACE; #else // If the given entry was not found we assume it is a device file or ip address if (!found) devFile = ucChannel; #endif if (retval != 0) { for (--tmp; tmp >= 0; tmp--) free(sectionList[tmp]); return retval; } #else devFile = ucChannel; #endif if(intf == ETHERCAN) { if ((fd = setupEtherCANConnection(slot, devFile)) < 0) { if (BE_INFORMATIVE) perror(devFile); return CPC_ERR_CHANNEL_NOT_ACTIVE; } #ifdef SOCKETCAN_SUPPORT } else if(intf == SOCKETCAN) { if ((fd = socketcan_SetupConnection(slot, devFile)) < 0) { if (BE_INFORMATIVE) perror(devFile); return CPC_ERR_CHANNEL_NOT_ACTIVE; } #endif } else { if ((fd = open(devFile, O_RDWR)) >= 0) { CPCLibParams[slot].read = read; CPCLibParams[slot].write = write; } else { return CPC_ERR_CHANNEL_NOT_ACTIVE; } } if (BE_DEBUG) printf("CPCLIB[%s]: Device %s (%s) opened with handle: %d, fd: %d!\n", __PRETTY_FUNCTION__, devFile, ucChannel, slot, fd); CPCInitParams[slot].chanparams.fd = fd; // Reset device CPC_CANExit(slot, DO_NOT_CONFIRM); CPC_ClearCMDQueue(slot, DO_NOT_CONFIRM); CPC_ClearMSGQueue(slot); #ifndef __uClinux__ #ifdef _CPC_CONF_INI if (configIrq) { if (!ini_get_key_value(ucChannel, "IrqNr", CPC_CONF_INI_PATH, valueBuffer, sizeof(valueBuffer))) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: Could find IRQ number\n", __PRETTY_FUNCTION__); CPC_CloseChannel(slot); return CPC_ERR_WRONG_PARAMETERS; } irqNr = atoi(valueBuffer); msg.type = CPC_CMD_T_OPEN_CHAN; msg.length = 2; msg.msg.generic[0] = (unsigned char) irqNr; retval = CPCLibParams[slot].write(CPCInitParams[slot].chanparams.fd, (void *) &msg, sizeof(CPC_MSG_T)); if (retval < 0) { if (BE_INFORMATIVE) printf("CPCLIB[%s]: Could not configure IRQ line\n", __PRETTY_FUNCTION__); CPC_CloseChannel(slot); return CPC_ERR_NO_RESOURCES; } } #endif #endif return slot; }