o
    +a_<O                     @   s`   d dl mZ d dlZd dlZd dlmZ d dlZd dlmZmZm	Z	m
Z
mZ G dd deZdS )    )absolute_importN)win32)
SerialBaseSerialExceptionto_bytesPortNotOpenErrorSerialTimeoutExceptionc                       s  e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	e
dd Zd;ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Ze
d"d# Ze
d$d% Ze
d&d' Ze
d(d) Zd<d,d-Zd=d/d0Ze
d1d2 Zd3d4 Zd5d6 Zd7d8 Zej j!d9d: Z   Z"S )>Serialz5Serial port implementation for Win32 based on ctypes.)2   K   n            i,  iX  i  i  i`	  i  i%  i K  i   i   i  c                    s,   d | _ d | _d | _tt| j|i | d S N)_port_handle_overlapped_read_overlapped_writesuperr	   __init__)selfargskwargs	__class__ 4/usr/lib/python3/dist-packages/serial/serialwin32.pyr      s   zSerial.__init__c              	   C   s  | j du r	td| jrtd| j}z| dr)t|dd dkr)d| }W n	 ty3   Y nw t	|tj
tjB ddtjtjtjB d| _| jtjkr]d| _td	| jt zMt | _tdd
dd| j_t | _tdddd| j_t| jdd t | _t| jt| j |   t | jtj!tj"B tj#B tj$B  W n   z	| %  W d| _    Y d| _ d| _dS )zx        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        Nz.Port must be configured before it can be used.zPort is already open.COM      z\\.\r   zcould not open port {!r}: {!r}      T)&_portr   is_opennameupper
startswithint
ValueErrorr   
CreateFileGENERIC_READGENERIC_WRITEOPEN_EXISTINGFILE_ATTRIBUTE_NORMALFILE_FLAG_OVERLAPPEDr   INVALID_HANDLE_VALUEformatportstrctypesWinError
OVERLAPPEDr   CreateEventhEventr   	SetupCommCOMMTIMEOUTS_orgTimeoutsGetCommTimeoutsbyref_reconfigure_port	PurgeCommPURGE_TXCLEARPURGE_TXABORTPURGE_RXCLEARPURGE_RXABORT_close)r   portr   r   r   open#   sf   
"







zSerial.openc                 C   s  | j stdt }| jdu rn| jdkrtj|_ntt| jd d|_	| jdkr;| j
dur;tt| j
d d|_| jdu rAn| jdkrKtj|_ntt| jd d|_t| j t| t| j tj t }t| j t| | j|_| jtjkrd|_n&| jtjkrd|_n| jtjkrd|_n| jtjkrd	|_ntd
| j| jtj krtj!|_"d|_#n@| jtj$krtj%|_"d|_#n2| jtj&krtj'|_"d|_#n$| jtj(krtj)|_"d|_#n| jtj*krtj+|_"d|_#ntd| j| j,tj-krtj.|_/n | j,tj0krtj1|_/n| j,tj2krtj3|_/ntd| j,d|_4| j5du rF| j6r6tj7|_8n| j9r=tj:ntj;|_8| j6|_<nQ| j5j=sTtd| j5j=| j5j>rbtd| j5j>| j5j?durrtd| j5j?| j5j@durtd| j5j@| j5jArtd| j5jAtjB|_8d|_<| jCrtjD|_En| jFrtjGntjH|_E| jC|_I| jJ|_K| jJ|_Ld|_Md|_Nd|_OtjP|_QtjR|_StT| j t|stdtU dS )z,Set communication parameters on opened port.z'Can only operate on a valid port handleNr   i  r             r   z%Unsupported number of data bits: {!r}zUnsupported parity mode: {!r}z%Unsupported number of stop bits: {!r}zQUnsupported value for RS485Settings.rts_level_for_tx: {!r} (only True is allowed)zRUnsupported value for RS485Settings.rts_level_for_rx: {!r} (only False is allowed)zPUnsupported value for RS485Settings.delay_before_tx: {!r} (only None is allowed)zPUnsupported value for RS485Settings.delay_before_rx: {!r} (only None is allowed)zJUnsupported value for RS485Settings.loopback: {!r} (only False is allowed)zCCannot configure port, something went wrong. Original message: {!r})Vr   r   r   r8   _timeoutMAXDWORDReadIntervalTimeoutmaxr'   ReadTotalTimeoutConstant_inter_byte_timeout_write_timeoutWriteTotalTimeoutConstantSetCommTimeoutsr2   r;   SetCommMaskEV_ERRDCBGetCommState	_baudrateBaudRate	_bytesizeserialFIVEBITSByteSizeSIXBITS	SEVENBITS	EIGHTBITSr(   r0   _parityPARITY_NONENOPARITYParityfParityPARITY_EVEN
EVENPARITY
PARITY_ODD	ODDPARITYPARITY_MARK
MARKPARITYPARITY_SPACESPACEPARITY	_stopbitsSTOPBITS_ONE
ONESTOPBITStopBitsSTOPBITS_ONE_POINT_FIVEONE5STOPBITSSTOPBITS_TWOTWOSTOPBITSfBinary_rs485_mode_rtsctsRTS_CONTROL_HANDSHAKEfRtsControl
_rts_stateRTS_CONTROL_ENABLERTS_CONTROL_DISABLEfOutxCtsFlowrts_level_for_txrts_level_for_rxdelay_before_txdelay_before_rxloopbackRTS_CONTROL_TOGGLE_dsrdtrDTR_CONTROL_HANDSHAKEfDtrControl
_dtr_stateDTR_CONTROL_ENABLEDTR_CONTROL_DISABLEfOutxDsrFlow_xonxofffOutXfInXfNull
fErrorCharfAbortOnErrorXONXonCharXOFFXoffCharSetCommStater3   )r   timeoutscomDCBr   r   r   r<   d   s   















zSerial._reconfigure_portc                 C   s   | j dur>t| j | j | jdur |   t| jj d| _| jdur3| 	  t| jj d| _t| j  d| _ dS dS )zinternal close port helperN)
r   r   rP   r9   r   cancel_readCloseHandler6   r   cancel_writer   r   r   r   rB      s   



zSerial._closec                 C   s   | j r|   d| _ dS dS )z
Close portFN)r#   rB   r   r   r   r   close   s   
zSerial.closec                 C   D   t  }t  }t | jt|t|stdt	 |j
S )z9Return the number of bytes currently in the input buffer.ClearCommError failed ({!r}))r   DWORDCOMSTATClearCommErrorr   r2   r;   r   r0   r3   cbInQuer   flagscomstatr   r   r   
in_waiting   
   zSerial.in_waitingr    c           
   	   C   sX  | j st |dkrt| jj t }t }t| j	t
|t
|s0tdt
 | jdkr;t|j|n|}|dkrt
|}t }t| j	||t
|t
| j}|spt tjtjfvrptdt
 t| j	t
| jt
|d}|st tjkrtdt
 |jd|j }	t|	S t }	t|	S t }	t|	S )z        Read size bytes from the serial port. If a timeout is set it may
        return less characters as requested. With no timeout it will block
        until the requested number of bytes is read.
        r   r   zReadFile failed ({!r})Tz!GetOverlappedResult failed ({!r})N)r#   r   r   
ResetEventr   r6   r   r   r   r   r2   r;   r   r0   r3   timeoutminr   create_string_bufferReadFileGetLastErrorERROR_SUCCESSERROR_IO_PENDINGGetOverlappedResultERROR_OPERATION_ABORTEDrawvaluebytes)
r   sizer   r   nbufrcread_ok	result_okreadr   r   r   r     sH   


zSerial.readc                 C   s  | j st t|}|rt }t| j|t|t	|| j
}| jdkr_|s:t tjtjfvr:tdt t| j| j
t	|d t tjkrQ|jS |jt|kr\td|jS |rdtjnt }|tjtjtjfv rtdS |tjtjfv rt|S tdt dS )z2Output the given byte string over the serial port.r   zWriteFile failed ({!r})TzWrite timeout)r#   r   r   r   r   	WriteFiler   lenr2   r;   r   rN   r   r   r   r   r0   r3   r   r   r   r   ERROR_INVALID_USER_BUFFERERROR_NOT_ENOUGH_MEMORY)r   datar   success	errorcoder   r   r   write/  s0    

zSerial.writec                 C   s   | j rtd | j sdS dS )zb        Flush of file like objects. In this case, wait until all data
        is written.
        g?N)out_waitingtimesleepr   r   r   r   flushT  s   
zSerial.flushc                 C   &   | j st t| jtjtjB  dS )z9Clear input buffer, discarding all that is in the buffer.N)r#   r   r   r=   r   r@   rA   r   r   r   r   reset_input_buffer_  s   zSerial.reset_input_bufferc                 C   r   )zs        Clear output buffer, aborting the current output and discarding all
        that is in the buffer.
        N)r#   r   r   r=   r   r>   r?   r   r   r   r   reset_output_buffere  s   zSerial.reset_output_bufferc                 C   s2   | j st | jrt| j dS t| j dS )zBSet break: Controls TXD. When active, to transmitting is possible.N)r#   r   _break_stater   SetCommBreakr   ClearCommBreakr   r   r   r   _update_break_staten  s
   zSerial._update_break_statec                 C   .   | j rt| jtj dS t| jtj dS )z)Set terminal status line: Request To SendN)rx   r   EscapeCommFunctionr   SETRTSCLRRTSr   r   r   r   _update_rts_statew     zSerial._update_rts_statec                 C   r   )z-Set terminal status line: Data Terminal ReadyN)r   r   r   r   SETDTRCLRDTRr   r   r   r   _update_dtr_state~  r   zSerial._update_dtr_statec                 C   s.   | j st t }t| jt| |jS r   )	r#   r   r   r   GetCommModemStatusr   r2   r;   r   )r   statr   r   r   _GetCommModemStatus  s
   zSerial._GetCommModemStatusc                 C      t j|  @ dkS )z(Read terminal status line: Clear To Sendr   )r   	MS_CTS_ONr   r   r   r   r   cts     z
Serial.ctsc                 C   r   )z)Read terminal status line: Data Set Readyr   )r   	MS_DSR_ONr   r   r   r   r   dsr  r   z
Serial.dsrc                 C   r   )z)Read terminal status line: Ring Indicatorr   )r   
MS_RING_ONr   r   r   r   r   ri  r   z	Serial.ric                 C   r   )z)Read terminal status line: Carrier Detectr   )r   
MS_RLSD_ONr   r   r   r   r   cd  r   z	Serial.cdr!   Nc                 C   s    |du r|}t | j|| dS )z        Recommend a buffer size to the driver (device driver can ignore this
        value). Must be called after the port is opened.
        N)r   r7   r   )r   rx_sizetx_sizer   r   r   set_buffer_size  s   zSerial.set_buffer_sizeTc                 C   s8   | j st |rt| jtj dS t| jtj dS )a*          Manually control flow - when software flow control is enabled.
        This will do the same as if XON (true) or XOFF (false) are received
        from the other device and control the transmission accordingly.
        WARNING: this function is not portable to different platforms!
        N)r#   r   r   r   r   SETXONSETXOFF)r   enabler   r   r   set_output_flow_control  s
   zSerial.set_output_flow_controlc                 C   r   )z0Return how many bytes the in the outgoing bufferr   )r   r   r   r   r   r2   r;   r   r0   r3   cbOutQuer   r   r   r   r     r   zSerial.out_waitingc                 C   sX   t  }t | jt|t|d}|s(t  t jt jfv r*t 	| j| dS dS dS )ACancel a blocking read operation, may be called from other threadFN)
r   r   r   r   r2   r;   r   r   ERROR_IO_INCOMPLETE
CancelIoEx)r   
overlappedr   errr   r   r   _cancel_overlapped_io  s   zSerial._cancel_overlapped_ioc                 C      |  | j dS )r   N)r   r   r   r   r   r   r        zSerial.cancel_readc                 C   r   )zBCancel a blocking write operation, may be called from other threadN)r   r   r   r   r   r   r     r   zSerial.cancel_writec                 C   s.   |dur|st d|tjj| | dS )z$Change the exclusive access setting.Nz.win32 only supports exclusive access (not: {}))r(   r0   rX   r   	exclusive__set__)r   r   r   r   r   r     s   zSerial.exclusive)r    )r!   N)T)#__name__
__module____qualname____doc__	BAUDRATESr   rD   r<   rB   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   setter__classcell__r   r   r   r   r	      sJ    A 

)%		





	
r	   )
__future__r   r2   r   rX   r   serial.serialutilr   r   r   r   r   r	   r   r   r   r   <module>   s   