Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
Arquivo: cpclib.c Projeto: uqs/avalon
/**
 * 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, &sectionList[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;
}