static void awaitAction (long int timeout) { AsyncWaitData *wd = getWaitData(); if (wd) { const CallbackExecuterEntry *cbx = callbackExecuterTable; CallbackExecuterParameters parameters = { .tsd = wd->tsd, .timeout = timeout }; wd->waitDepth += 1; logMessage(LOG_CATEGORY(ASYNC_EVENTS), "begin: level %u: timeout %ld", wd->waitDepth, timeout); while (cbx->execute) { if (cbx->execute(¶meters)) break; cbx += 1; } logMessage(LOG_CATEGORY(ASYNC_EVENTS), "end: level %u: %s", wd->waitDepth, cbx->action); wd->waitDepth -= 1; } else { logMessage(LOG_CATEGORY(ASYNC_EVENTS), "waiting: %ld", timeout); approximateDelay(timeout); } }
int serialPutAttributes (SerialDevice *serial, const SerialAttributes *attributes) { if (attributes->speed.bps < (0X1 << 3)) { unsigned char byte = attributes->bios.byte; logMessage(LOG_CATEGORY(SERIAL_IO), "put attributes: port=%d byte=0X%02X", serialGetPort(serial), byte); serialBiosCommand(serial, _COM_INIT, byte); } else { SerialBiosConfiguration lcr = attributes->bios; lcr.fields.bps = 0; logMessage(LOG_CATEGORY(SERIAL_IO), "put attributes: port=%d lcr=0X%02X divisor=%u", serialGetPort(serial), lcr.byte, attributes->speed.divisor); { int wasEnabled = disable(); serialWritePort(serial, UART_PORT_LCR, (lcr.byte | UART_FLAG_LCR_DLAB)); serialWritePort(serial, UART_PORT_DLL, (attributes->speed.divisor & 0XFF)); serialWritePort(serial, UART_PORT_DLH, (attributes->speed.divisor >> 8)); serialWritePort(serial, UART_PORT_LCR, lcr.byte); if (wasEnabled) enable(); } } return 1; }
int usbClaimInterface (UsbDevice *device, unsigned char interface) { UsbDeviceExtension *devx = device->extension; int detached = 0; int result; logMessage(LOG_CATEGORY(USB_IO), "claiming interface: %u", interface); while (1) { char driver[0X100]; result = usb_claim_interface(devx->handle, interface); if (result >= 0) return 1; if (result != -EBUSY) break; if (detached) break; #ifdef LIBUSB_HAS_GET_DRIVER_NP result = usb_get_driver_np(devx->handle, interface, driver, sizeof(driver)); if (result < 0) #endif /* LIBUSB_HAS_GET_DRIVER_NP */ { strcpy(driver, "unknown"); } logMessage(LOG_WARNING, "USB interface in use: %u (%s)", interface, driver); if (strcmp(driver, "usbfs") == 0) { result = -EBUSY; break; } #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP logMessage(LOG_CATEGORY(USB_IO), "detaching kernel driver: %u (%s)", interface, driver); result = usb_detach_kernel_driver_np(devx->handle, interface); if (result >= 0) { logMessage(LOG_CATEGORY(USB_IO), "detached kernel driver: %u (%s)", interface, driver); detached = 1; continue; } result = -EBUSY; #endif /* LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP */ break; } errno = -result; logSystemError("USB interface claim"); return 0; }
ssize_t usbControlTransfer ( UsbDevice *device, uint8_t direction, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, void *buffer, uint16_t length, int timeout ) { UsbDeviceExtension *devx = device->extension; if (usbOpenUsbfsFile(devx)) { union { struct usbdevfs_ctrltransfer transfer; UsbSetupPacket setup; } arg; memset(&arg, 0, sizeof(arg)); arg.setup.bRequestType = direction | recipient | type; arg.setup.bRequest = request; putLittleEndian16(&arg.setup.wValue, value); putLittleEndian16(&arg.setup.wIndex, index); putLittleEndian16(&arg.setup.wLength, length); arg.transfer.data = buffer; arg.transfer.timeout = timeout; usbLogSetupPacket(&arg.setup); if (direction == UsbControlDirection_Output) { if (length) logBytes(LOG_CATEGORY(USB_IO), "control output", buffer, length); } { int count = ioctl(devx->usbfsFile, USBDEVFS_CONTROL, &arg); if (count != -1) { if (direction == UsbControlDirection_Input) { logBytes(LOG_CATEGORY(USB_IO), "control input", buffer, length); } return count; } logSystemError("USB control transfer"); } } return -1; }
int asyncExecuteAlarmCallback (AsyncAlarmData *ad, long int *timeout) { if (ad) { Queue *alarms = ad->alarmQueue; if (alarms) { Element *element = processQueue(alarms, testInactiveAlarm, NULL); if (element) { AlarmEntry *alarm = getElementItem(element); TimeValue now; long int milliseconds; getMonotonicTime(&now); milliseconds = millisecondsBetween(&now, &alarm->time); if (milliseconds <= 0) { AsyncAlarmCallback *callback = alarm->callback; const AsyncAlarmCallbackParameters parameters = { .now = &now, .data = alarm->data }; logSymbol(LOG_CATEGORY(ASYNC_EVENTS), callback, "alarm starting"); alarm->active = 1; if (callback) callback(¶meters); alarm->active = 0; if (alarm->reschedule) { adjustTimeValue(&alarm->time, alarm->interval); getMonotonicTime(&now); if (compareTimeValues(&alarm->time, &now) < 0) alarm->time = now; requeueElement(element); } else { alarm->cancel = 1; } if (alarm->cancel) deleteElement(element); return 1; } if (milliseconds < *timeout) { *timeout = milliseconds; logSymbol(LOG_CATEGORY(ASYNC_EVENTS), alarm->callback, "next alarm: %ld", *timeout); } } } } return 0; }
/* Opens a connection with BrlAPI's server */ static int brl_construct(BrailleDisplay *brl, char **parameters, const char *device) { brlapi_connectionSettings_t settings; settings.host = parameters[PARM_HOST]; settings.auth = parameters[PARM_AUTH]; CHECK((brlapi_openConnection(&settings, &settings)>=0), out); logMessage(LOG_CATEGORY(BRAILLE_DRIVER), "Connected to %s using %s", settings.host, settings.auth); CHECK((brlapi_enterTtyModeWithPath(NULL, 0, NULL)>=0), out0); logMessage(LOG_CATEGORY(BRAILLE_DRIVER), "Got tty successfully"); CHECK((brlapi_getDisplaySize(&brl->textColumns, &brl->textRows)==0), out1); logMessage(LOG_CATEGORY(BRAILLE_DRIVER), "Found out display size: %dx%d", brl->textColumns, brl->textRows); displaySize = brl->textColumns * brl->textRows; brl->hideCursor = 1; prevData = malloc(displaySize); CHECK((prevData!=NULL), out1); memset(prevData, 0, displaySize); prevText = malloc(displaySize * sizeof(wchar_t)); CHECK((prevText!=NULL), out2); wmemset(prevText, WC_C(' '), displaySize); prevShown = 0; prevCursor = BRL_NO_CURSOR; restart = 0; logMessage(LOG_CATEGORY(BRAILLE_DRIVER), "Memory allocated, returning 1"); return 1; out2: free(prevData); out1: brlapi_leaveTtyMode(); out0: brlapi_closeConnection(); out: logMessage(LOG_CATEGORY(BRAILLE_DRIVER), "Something went wrong, returning 0"); return 0; }
int usbGetLanguage ( UsbDevice *device, uint16_t *language, int timeout ) { UsbDescriptor descriptor; ssize_t size = usbGetDescriptor(device, UsbDescriptorType_String, 0, 0, &descriptor, timeout); if (size != -1) { if (size >= 4) { *language = getLittleEndian16(descriptor.string.wData[0]); logMessage(LOG_CATEGORY(USB_IO), "USB language: %02X", *language); return 1; } else { logMessage(LOG_ERR, "USB language code string too short: %"PRIssize, size); errno = EIO; } } else { logMessage(LOG_ERR, "USB language code string read error"); } return 0; }
static void handleSpeechMessage (volatile SpeechDriverThread *sdt, SpeechMessage *msg) { logSpeechMessage(msg, "handling"); if (msg) { switch (msg->type) { case MSG_REQUEST_FINISHED: setIntegerResponse(sdt, msg->arguments.requestFinished.result); sendSpeechRequest(sdt); break; case MSG_SPEECH_FINISHED: { volatile SpeechSynthesizer *spk = sdt->speechSynthesizer; SetSpeechFinishedMethod *setFinished = spk->setFinished; if (setFinished) setFinished(spk); break; } case MSG_SPEECH_LOCATION: { volatile SpeechSynthesizer *spk = sdt->speechSynthesizer; SetSpeechLocationMethod *setLocation = spk->setLocation; if (setLocation) setLocation(spk, msg->arguments.speechLocation.location); break; } default: logMessage(LOG_CATEGORY(SPEECH_EVENTS), "unimplemented message: %u", msg->type); break; } free(msg); } }
int usbClaimInterface (UsbDevice *device, unsigned char interface) { UsbDeviceExtension *devx = device->extension; logMessage(LOG_CATEGORY(USB_IO), "claiming interface: %u", interface); if (usbOpenUsbfsFile(devx)) { int disconnected = 0; while (1) { unsigned int arg = interface; if (ioctl(devx->usbfsFile, USBDEVFS_CLAIMINTERFACE, &arg) != -1) return 1; if (errno != EBUSY) break; if (disconnected) break; if (!usbDisconnectInterface(device, interface)) { errno = EBUSY; break; } disconnected = 1; } logSystemError("USB interface claim"); } return 0; }
int serialSetFlowControl (SerialDevice *serial, SerialFlowControl flow) { logMessage(LOG_CATEGORY(SERIAL_IO), "set flow control: 0X%02X", flow); flow = serialPutFlowControl(&serial->pendingAttributes, flow); #ifdef HAVE_POSIX_THREADS if (flow & SERIAL_FLOW_INPUT_CTS) { flow &= ~SERIAL_FLOW_INPUT_CTS; serial->pendingFlowControlProc = serialFlowControlProc_inputCTS; } else { serial->pendingFlowControlProc = NULL; } { int state = !!serial->pendingFlowControlProc; if (!serialPutModemState(&serial->pendingAttributes, state)) { logMessage(LOG_WARNING, "unsupported serial modem state: %d", state); } } #endif /* HAVE_POSIX_THREADS */ if (!flow) return 1; logMessage(LOG_WARNING, "unsupported serial flow control: 0X%02X", flow); return 0; }
int usbHidGetReportSize ( const unsigned char *items, size_t length, unsigned char identifier, size_t *size ) { UsbHidReportDescription description; *size = 0; if (usbHidFillReportDescription(items, length, identifier, &description)) { if (description.defined & USB_HID_ITEM_BIT(UsbHidItemType_ReportCount)) { if (description.defined & USB_HID_ITEM_BIT(UsbHidItemType_ReportSize)) { uint32_t bytes = ((description.reportCount * description.reportSize) + 7) / 8; logMessage(LOG_CATEGORY(USB_IO), "HID report size: %02X = %"PRIu32, identifier, bytes); *size = 1 + bytes; return 1; } else { logMessage(LOG_WARNING, "HID report size not defined: %02X", identifier); } } else { logMessage(LOG_WARNING, "HID report count not defined: %02X", identifier); } } else { logMessage(LOG_WARNING, "HID report not found: %02X", identifier); } return 0; }
void usbLogEndpointData ( UsbEndpoint *endpoint, const char *label, const void *data, size_t size ) { logBytes(LOG_CATEGORY(USB_IO), "endpoint %02X %s", data, size, endpoint->descriptor->bEndpointAddress, label); }
int serialSetStopBits (SerialDevice *serial, SerialStopBits bits) { logMessage(LOG_CATEGORY(SERIAL_IO), "set stop bits: %u", bits); if (serialPutStopBits(&serial->pendingAttributes, bits)) return 1; logMessage(LOG_WARNING, "unsupported serial stop bit count: %d", bits); return 0; }
static void logRouting (const char *format, ...) { va_list arguments; va_start(arguments, format); vlogMessage(LOG_CATEGORY(CURSOR_ROUTING), format, &arguments); va_end(arguments); }
int serialSetParity (SerialDevice *serial, SerialParity parity) { logMessage(LOG_CATEGORY(SERIAL_IO), "set parity: %u", parity); if (serialPutParity(&serial->pendingAttributes, parity)) return 1; logMessage(LOG_WARNING, "unsupported serial parity: %d", parity); return 0; }
int serialSetDataBits (SerialDevice *serial, unsigned int bits) { logMessage(LOG_CATEGORY(SERIAL_IO), "set data bits: %u", bits); if (serialPutDataBits(&serial->pendingAttributes, bits)) return 1; logMessage(LOG_WARNING, "unsupported serial data bit count: %d", bits); return 0; }
int serialPutSpeed (SerialAttributes *attributes, SerialSpeed speed) { logMessage(LOG_CATEGORY(SERIAL_IO), "put speed: bps=%u divisor=%u", speed.bps, speed.divisor); attributes->speed = speed; attributes->bios.fields.bps = attributes->speed.bps; return 1; }
int usbResetDevice (UsbDevice *device) { logMessage(LOG_CATEGORY(USB_IO), "reset device"); UsbDeviceExtension *devx = device->extension; int result = usb_reset(devx->handle); if (result >= 0) return 1; errno = -result; logSystemError("USB device reset"); return 0; }
static void usbLogLineCoding_CDC_ACM (const USB_CDC_ACM_LineCoding *lineCoding) { char log[0X80]; STR_BEGIN(log, sizeof(log)); STR_PRINTF("CDC ACM line coding:"); { // baud (bits per second) uint32_t baud = getLittleEndian32(lineCoding->dwDTERate); STR_PRINTF(" Baud:%" PRIu32, baud); } { // number of data bits STR_PRINTF(" Data:%u", lineCoding->bDataBits); } { // number of stop bits const char *bits; #define USB_CDC_ACM_STOP(value,name) \ case USB_CDC_ACM_STOP_##value: bits = #name; break; switch (lineCoding->bCharFormat) { USB_CDC_ACM_STOP(1 , 1 ) USB_CDC_ACM_STOP(1_5, 1.5) USB_CDC_ACM_STOP(2 , 2 ) default: bits = "?"; break; } #undef USB_CDC_ACM_STOP STR_PRINTF(" Stop:%s", bits); } { // type of parity const char *parity; #define USB_CDC_ACM_PARITY(value,name) \ case USB_CDC_ACM_PARITY_##value: parity = #name; break; switch (lineCoding->bParityType) { USB_CDC_ACM_PARITY(NONE , none ) USB_CDC_ACM_PARITY(ODD , odd ) USB_CDC_ACM_PARITY(EVEN , even ) USB_CDC_ACM_PARITY(MARK , mark ) USB_CDC_ACM_PARITY(SPACE, space) default: parity = "?"; break; } #undef USB_CDC_ACM_PARITY STR_PRINTF(" Parity:%s", parity); } STR_END; logMessage(LOG_CATEGORY(USB_IO), "%s", log); }
int usbClearHalt (UsbDevice *device, unsigned char endpointAddress) { logMessage(LOG_CATEGORY(USB_IO), "clear halt: %02X", endpointAddress); UsbDeviceExtension *devx = device->extension; int result = usb_clear_halt(devx->handle, endpointAddress); if (result >= 0) return 1; errno = -result; logSystemError("USB endpoint clear"); return 0; }
ssize_t usbControlTransfer ( UsbDevice *device, uint8_t direction, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, void *buffer, uint16_t length, int timeout ) { UsbDeviceExtension *devx = device->extension; UsbSetupPacket setup; int result; usbMakeSetupPacket(&setup, direction, recipient, type, request, value, index, length); if (direction == UsbControlDirection_Output) { if (length) logBytes(LOG_CATEGORY(USB_IO), "control output", buffer, length); } result = usb_control_msg(devx->handle, setup.bRequestType, setup.bRequest, getLittleEndian16(setup.wValue), getLittleEndian16(setup.wIndex), buffer, getLittleEndian16(setup.wLength), timeout); if (result >= 0) { if (direction == UsbControlDirection_Input) { logBytes(LOG_CATEGORY(USB_IO), "control input", buffer, result); } return result; } errno = -result; logSystemError("USB control transfer"); return -1; }
int usbReleaseInterface (UsbDevice *device, unsigned char interface) { UsbDeviceExtension *devx = device->extension; int result; logMessage(LOG_CATEGORY(USB_IO), "releasing interface: %u", interface); result = usb_release_interface(devx->handle, interface); if (result >= 0) return 1; errno = -result; logSystemError("USB interface release"); return 0; }
int usbSetConfiguration (UsbDevice *device, unsigned char configuration) { UsbDeviceExtension *devx = device->extension; int result; logMessage(LOG_CATEGORY(USB_IO), "setting configuration: %u", configuration); result = usb_set_configuration(devx->handle, configuration); if (result >= 0) return 1; errno = -result; logSystemError("USB configuration set"); return 0; }
int usbReleaseInterface (UsbDevice *device, unsigned char interface) { UsbDeviceExtension *devx = device->extension; logMessage(LOG_CATEGORY(USB_IO), "releasing interface: %u", interface); if (usbOpenUsbfsFile(devx)) { unsigned int arg = interface; if (ioctl(devx->usbfsFile, USBDEVFS_RELEASEINTERFACE, &arg) != -1) return 1; if (errno == ENODEV) return 1; logSystemError("USB interface release"); } return 0; }
int usbSetConfiguration (UsbDevice *device, unsigned char configuration) { UsbDeviceExtension *devx = device->extension; logMessage(LOG_CATEGORY(USB_IO), "setting configuration: %u", configuration); if (usbOpenUsbfsFile(devx)) { unsigned int arg = configuration; if (ioctl(devx->usbfsFile, USBDEVFS_SETCONFIGURATION, &arg) != -1) return 1; logSystemError("USB configuration set"); } return 0; }
static int usbToErrno (enum libusb_error error) { switch (error) { case LIBUSB_ERROR_IO: return EIO; case LIBUSB_ERROR_INVALID_PARAM: return EINVAL; case LIBUSB_ERROR_ACCESS: return EACCES; case LIBUSB_ERROR_NO_DEVICE: return ENODEV; case LIBUSB_ERROR_NOT_FOUND: return ENOENT; case LIBUSB_ERROR_BUSY: return EBUSY; case LIBUSB_ERROR_TIMEOUT: return EAGAIN; #ifdef EMSGSIZE case LIBUSB_ERROR_OVERFLOW: return EMSGSIZE; #endif /* EMSGSIZE */ case LIBUSB_ERROR_PIPE: return EPIPE; case LIBUSB_ERROR_INTERRUPTED: return EINTR; case LIBUSB_ERROR_NO_MEM: return ENOMEM; case LIBUSB_ERROR_NOT_SUPPORTED: return ENOSYS; default: logMessage(LOG_CATEGORY(USB_IO), "unsupported libusb1 error code: %d", error); case LIBUSB_ERROR_OTHER: return EIO; } }
int serialConnectDevice (SerialDevice *serial, const char *device) { if ((serial->package.port = grub_serial_find(device))) { serial->package.byte = SERIAL_NO_BYTE; if (serialPrepareDevice(serial)) { logMessage(LOG_CATEGORY(SERIAL_IO), "device opened: %s", device); return 1; } } else { logMessage(LOG_ERR, "cannot find serial device: %s", device); errno = ENOENT; } return 0; }
int usbSetAlternative ( UsbDevice *device, unsigned char interface, unsigned char alternative ) { UsbDeviceExtension *devx = device->extension; int result; logMessage(LOG_CATEGORY(USB_IO), "setting alternative: %u[%u]", interface, alternative); result = usb_set_altinterface(devx->handle, alternative); if (result >= 0) return 1; errno = -result; logSystemError("USB alternative set"); return 0; }
int serialConnectDevice (SerialDevice *serial, const char *device) { if ((serial->fileDescriptor = open(device, O_RDWR|O_NOCTTY|O_NONBLOCK)) != -1) { serial->package.deviceIndex = -1; { char *truePath; if ((truePath = _truename(device, NULL))) { char *com; { char *c = truePath; while (*c) { *c = toupper(*c); c += 1; } } if ((com = strstr(truePath, "COM"))) { serial->package.deviceIndex = atoi(com+3) - 1; } free(truePath); } } if (serial->package.deviceIndex >= 0) { if (serialPrepareDevice(serial)) { logMessage(LOG_CATEGORY(SERIAL_IO), "device opened: %s: fd=%d", device, serial->fileDescriptor); return 1; } } else { logMessage(LOG_ERR, "could not determine serial device number: %s", device); } close(serial->fileDescriptor); } else { logMessage(LOG_ERR, "cannot open serial device: %s: %s", device, strerror(errno)); } return 0; }
int serialSetBaud (SerialDevice *serial, unsigned int baud) { const SerialBaudEntry *entry = serialGetBaudEntry(baud); if (entry) { logMessage(LOG_CATEGORY(SERIAL_IO), "set baud: %u", baud); if (serialPutSpeed(&serial->pendingAttributes, entry->speed)) { return 1; } else { logMessage(LOG_WARNING, "unsupported serial baud: %d", baud); } } else { logMessage(LOG_WARNING, "undefined serial baud: %d", baud); } return 0; }