📄 usbacmlib.c
字号:
{ UINT16 actLen; if (pSioChan == NULL) return ERROR; if (usbdVendorSpecific (usbdHandle, pSioChan->nodeId, USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_INTERFACE, request, pSioChan->configuration, (pSioChan->ifaceCommClass << 8 | pSioChan->ifaceCommAltSetting), count, pBuf, &actLen) != OK) { return ERROR; } return OK; }/***************************************************************************** usbAcmHwOptsSet - set hardware options** This routine sets up the modem according to the specified option* argument. If the hardware cannot support a particular option value, then* it should ignore that portion of the request.** USB modems supports more features than what are provided by the SIO model.* It is suggested that to take full advantage of these features, user shall* make use of the additional ioctl requests provided.** RETURNS: OK upon success, or EIO for invalid arguments.*/LOCAL int usbAcmHwOptsSet ( USB_ACM_SIO_CHAN * pChan, /* channel */ uint_t newOpts /* new options */ ) { BOOL hdweFlowCtrl= TRUE; BOOL rcvrEnable = TRUE; LINE_CODE oldLineCode; if (pChan == NULL || newOpts & 0xffffff00) return EIO; /* do nothing if options already set */ if ((uint_t)pChan->options == newOpts) return OK; oldLineCode = pChan->lineCode; /* decode individual request elements */ switch (newOpts & CSIZE) { case CS5: pChan->lineCode.noOfDataBits = 5; break; case CS6: pChan->lineCode.noOfDataBits = 6; break; case CS7: pChan->lineCode.noOfDataBits = 7; break; default: case CS8: pChan->lineCode.noOfDataBits = 8; break; } if (newOpts & STOPB) pChan->lineCode.noOfStopBits = USB_ACM_STOPBITS_2; else pChan->lineCode.noOfStopBits = USB_ACM_STOPBITS_1; switch (newOpts & (PARENB|PARODD)) { case PARENB|PARODD: pChan->lineCode.parityType = USB_ACM_PARITY_ODD; break; case PARENB: pChan->lineCode.parityType = USB_ACM_PARITY_EVEN; break; case PARODD: /* invalid mode, not normally used. */ break; default: case 0: pChan->lineCode.parityType = USB_ACM_PARITY_NONE; break; } /* TODO : set the H/W Flow control some how */ if (newOpts & CLOCAL) { /* clocal disables hardware flow control */ hdweFlowCtrl = FALSE; } if ((newOpts & CREAD) == 0) rcvrEnable = FALSE; USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Setting HW options \n", 0, 0, 0, 0, 0, 0); if (usbAcmCtrlCmdSend (pChan, USB_ACM_REQ_LINE_CODING_SET, (UINT8 *)(&pChan->lineCode), sizeof(pChan->lineCode)) == ERROR) { pChan->lineCode = oldLineCode; return ERROR; } pChan->options = newOpts; return (OK); }/***************************************************************************** usbAcmIoctl - special device control** This routine handles the IOCTL messages from the user. It supports commands * to get/set baud rate, mode( only INT mode), hardware options(parity, * number of data bits). ** This driver works only in the interrupt mode. Attempts to place the driver* in polled mode result in ERROR.** SIO_HUP is not implemented. Instead, user can issue a "ATH" AT command* to the modem to hangup the line.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/int usbAcmIoctl ( SIO_CHAN * pChan, /* Channel to control */ int request, /* IOCTL request */ void * pArg /* pointer to an argument */ ) { pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN)pChan; int arg = (int)pArg; UINT16 tempValue = 0; if (pSioChan == NULL) return ERROR; USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : 0x%0x request \n", request, 0, 0, 0, 0, 0); switch (request) { case USB_ACM_SIO_MODE_SET: /* * Set driver operating mode: interrupt or polled. * NOTE: This driver supports only SIO_MODE_INT. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : MODE_SET request for %s mode \n", (UINT)((arg == SIO_MODE_INT)?"Interrupt":"Polled"), 0, 0, 0, 0, 0); if (arg != SIO_MODE_INT) return EIO; pSioChan->mode = arg; return OK; case USB_ACM_SIO_MODE_GET: /* Return current driver operating mode for channel */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : MODE_GET request \n", 0, 0, 0, 0, 0, 0); *((int *) arg) = pSioChan->mode; return OK; case USB_ACM_SIO_AVAIL_MODES_GET: /* Return modes supported by driver. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : GET_ALL_MODES request \n", 0, 0, 0, 0, 0, 0); *((int *) arg) = SIO_MODE_INT; return OK; case USB_ACM_SIO_OPEN: /* Channel is always open. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : OPEN request \n", 0, 0, 0, 0, 0, 0); return OK; case USB_ACM_SIO_BAUD_SET: /* * like unix, a baud request for 0 is really a request to * hangup. In usb modems, hangup is achieved by sending an * AT command "ATH" than this way. We return ERROR here. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : SET_BAUD of %d request \n", arg, 0, 0, 0, 0, 0); if (arg == 0) /*return usbAcmHup (pSioChan);*/ return EIO; /* * Set the baud rate. Return EIO for an invalid baud rate, or * OK on success. */ if (arg < USB_ACM_BAUD_MIN || arg > USB_ACM_BAUD_MAX) { USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : %dbaud exceeds range \n", arg, 0, 0, 0, 0, 0); return (EIO); } tempValue = pSioChan->lineCode.baudRate; pSioChan->lineCode.baudRate = arg; if (usbAcmCtrlCmdSend (pSioChan, USB_ACM_REQ_LINE_CODING_SET, (UINT8 *)(&pSioChan->lineCode), sizeof(pSioChan->lineCode)) == ERROR) { pSioChan->lineCode.baudRate = tempValue; USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : SET_BAUD of %d request failed \n", arg, 0, 0, 0, 0, 0); return EIO; } return OK; case USB_ACM_SIO_BAUD_GET: USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : GET_BAUD of %d request \n", 0, 0, 0, 0, 0, 0); *(UINT *)arg = pSioChan->lineCode.baudRate; return OK; case USB_ACM_SIO_HW_OPTIONS_SET: /* * Optional command to set the hardware options (as defined * in sioLib.h). * Return OK, or ENOSYS if this command is not implemented. * Note: several hardware options are specified at once. * This routine should set as many as it can and then return * OK. The SIO_HW_OPTS_GET is used to find out which options * were actually set. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : SET_HW_OPTS request \n", 0, 0, 0, 0, 0, 0); return usbAcmHwOptsSet (pSioChan, arg); case USB_ACM_SIO_HW_OPTIONS_GET: /* * Optional command to get the hardware options (as defined * in sioLib.h). Return OK or ENOSYS if this command is not * implemented. Note: if this command is unimplemented, it * will be assumed that the driver options are CREAD | CS8 * (e.g., eight data bits, one stop bit, no parity, ints enabled). */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : GET_HW_OPTS request \n", 0, 0, 0, 0, 0, 0); *(UINT *) arg = pSioChan->options; return OK; case USB_ACM_SIO_HUP: /* * As mentioned before, hang-up is achieved by sending an AT * command. */ USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : hangUp request \n", 0, 0, 0, 0, 0, 0); return ENOSYS; case USB_ACM_SIO_FEATURE_SET: return ENOSYS; case USB_ACM_SIO_FEATURE_GET: return ENOSYS; case USB_ACM_SIO_FEATURE_CLEAR: return ENOSYS; case USB_ACM_SIO_LINE_CODING_SET: /* * The USB way of setting line parameters */ if (usbAcmCtrlCmdSend (pSioChan, USB_ACM_REQ_LINE_CODING_SET, (UINT8 *)(arg), sizeof(pSioChan->lineCode)) == ERROR) { return ERROR; } pSioChan->lineCode = *(LINE_CODE *)arg; return OK; case USB_ACM_SIO_LINE_CODING_GET: /* * USB way of retreving parameters */ memcpy ((UINT8 *)arg, (UINT8 *) &pSioChan->lineCode, sizeof (pSioChan->lineCode)); case USB_ACM_SIO_CTRL_LINE_STATE_SET: return ENOSYS; case USB_ACM_SIO_SEND_BREAK: return ENOSYS; case USB_ACM_SIO_MAX_BUF_SIZE_GET: *(UINT *)arg = pSioChan->outBfrLen; return OK; default: USB_ACM_LOG (USB_ACM_DEBUG_IOCTL, "Ioctl : 0x%0x UnKnown request \n", request, 0, 0, 0, 0, 0); return ENOSYS; } return OK; }/***************************************************************************** usbAcmOpen - Start the Modem communications.** RETURNS: OK on success, or ERROR if listening fails*/LOCAL STATUS usbAcmOpen ( SIO_CHAN * pChan /* pointer to channel */ ) { pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN)pChan; if (pSioChan == NULL) return ERROR; /* Start listening for normal data */ if (listenForInput(pSioChan) == ERROR) { USB_ACM_LOG (USB_ACM_DEBUG_OPEN, "listenForInput() Failed....", 0, 0, 0, 0, 0, 0); return ERROR; } return OK; }/***************************************************************************** usbAcmTxStartup - start the transmition.** This function uses the initiateOutput for the transmission.** RETURNS: OK on success, or EIO if output initiation fails** NOMANUAL*/int usbAcmTxStartup ( SIO_CHAN * pChan /* channel to start */ ) { pUSB_ACM_SIO_CHAN pSioChan = (pUSB_ACM_SIO_CHAN)pChan; int status = OK; if (initiateOutput (pSioChan) != OK) { logMsg("InitiateOutput failed \n",0,0,0,0,0,0); status = EIO; } return status; }/***************************************************************************** usbAcmPollOutput - output a character in polled mode** The USB modem driver supports only interrupt-mode operation. Therefore,* this function always returns the error ENOSYS.** RETURNS: ENOSYS*/LOCAL int usbAcmPollOutput ( SIO_CHAN *pChan, char outChar ) { return ENOSYS; }/***************************************************************************** usbAcmPollInput - poll the device for input** The USB modem driver supports only interrupt-mode operation. Therefore,* this function always returns the error ENOSYS.** RETURNS: ENOSYS*/LOCAL int usbAcmPollInput ( SIO_CHAN *pChan, char *thisChar ) { return ENOSYS; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -