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r„d|_n&| jtjkrŽd|_n| jtjkr˜d|_n| jtjkr¢d	|_ntd
 | j¡ƒ‚| jtj kr¸tj!|_"d|_#n@| jtj$krÆtj%|_"d|_#n2| jtj&krÔtj'|_"d|_#n$| jtj(krâtj)|_"d|_#n| jtj*krðt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�r‚td | j5j@¡ƒ‚| j5jA�r�td | j5jA¡ƒ‚tjB|_8d|_<| jC�r tjD|_En| jF�r§tjGntjH|_E| jC|_I| jJ|_K| jJ|_Ld|_Md|_Nd|_OtjP|_QtjR|_St T| j t |¡¡�sÜt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r¥t | jj¡ t ¡ }t ¡ }t | j	t
 |¡t
 |¡¡s0td t
 ¡ ¡ƒ‚| jdkr;t|j|ƒn|}|dkržt
 |¡}t ¡ }t | j	||t
 |¡t
 | j¡¡}|spt ¡ tjtjfvrptd t
 ¡ ¡ƒ‚t | j	t
 | j¡t
 |¡d¡}|s’t ¡ tjkr’t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|ƒ}|r‰t ¡ }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 r€t|ƒ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   