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.ZCOMé   é   z\\.\r   zcould not open port {!r}: {!r}é   é   T)&Z_portr   Úis_openÚnameÚupperÚ
startswithÚintÚ
ValueErrorr   Z
CreateFileZGENERIC_READZGENERIC_WRITEZOPEN_EXISTINGÚFILE_ATTRIBUTE_NORMALZFILE_FLAG_OVERLAPPEDr   ZINVALID_HANDLE_VALUEÚformatZportstrÚctypesÚWinErrorZ
OVERLAPPEDr   ZCreateEventÚhEventr   Ú	SetupCommÚCOMMTIMEOUTSÚ_orgTimeoutsZGetCommTimeoutsÚbyrefÚ_reconfigure_portÚ	PurgeCommÚPURGE_TXCLEARÚPURGE_TXABORTÚPURGE_RXCLEARÚPURGE_RXABORTÚ_close)r   Z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rt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   r-   Z_timeoutZMAXDWORDZReadIntervalTimeoutÚmaxr%   ZReadTotalTimeoutConstantZ_inter_byte_timeoutÚ_write_timeoutZWriteTotalTimeoutConstantÚSetCommTimeoutsr)   r/   ZSetCommMaskZEV_ERRZDCBZGetCommStateZ	_baudrateZBaudRateZ	_bytesizeÚserialZFIVEBITSZByteSizeZSIXBITSZ	SEVENBITSZ	EIGHTBITSr&   r(   Z_parityZPARITY_NONEZNOPARITYZParityZfParityZPARITY_EVENZ
EVENPARITYZ
PARITY_ODDZ	ODDPARITYZPARITY_MARKZ
MARKPARITYZPARITY_SPACEZSPACEPARITYZ	_stopbitsZSTOPBITS_ONEZ
ONESTOPBITZStopBitsZSTOPBITS_ONE_POINT_FIVEZONE5STOPBITSZSTOPBITS_TWOZTWOSTOPBITSZfBinaryZ_rs485_modeZ_rtsctsZRTS_CONTROL_HANDSHAKEZfRtsControlÚ
_rts_stateZRTS_CONTROL_ENABLEZRTS_CONTROL_DISABLEZfOutxCtsFlowZrts_level_for_txZrts_level_for_rxZdelay_before_txZdelay_before_rxZloopbackZRTS_CONTROL_TOGGLEZ_dsrdtrZDTR_CONTROL_HANDSHAKEZfDtrControlÚ
_dtr_stateZDTR_CONTROL_ENABLEZDTR_CONTROL_DISABLEZfOutxDsrFlowZ_xonxoffZfOutXZfInXZfNullZ
fErrorCharZfAbortOnErrorZXONZXonCharZXOFFZXoffCharZSetCommStater*   )r   ZtimeoutsZcomDCBr   r   r   r0   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   r=   r.   r   Úcancel_readZCloseHandler+   r   Úcancel_write©r   r   r   r   r6   å   s   



ôzSerial._closec                 C   s   | j r|  ¡  d| _ dS dS )z
Close portFN)r!   r6   rC   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   r)   r/   r   r(   r*   Ú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   rF   zReadFile failed ({!r})Tz!GetOverlappedResult failed ({!r})N)r!   r   r   Z
ResetEventr   r+   rG   rH   rI   r   r)   r/   r   r(   r*   ZtimeoutÚminrJ   Zcreate_string_bufferZReadFileÚGetLastErrorÚERROR_SUCCESSÚERROR_IO_PENDINGÚGetOverlappedResultÚERROR_OPERATION_ABORTEDÚrawÚvalueÚbytes)
r   ÚsizerL   rM   ÚnÚbufÚrcZread_okZ	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   rG   Z	WriteFiler   Úlenr)   r/   r   r<   rQ   rR   rS   r   r(   r*   rT   rU   rW   r   ZERROR_INVALID_USER_BUFFERZERROR_NOT_ENOUGH_MEMORY)r   ÚdatarZ   Z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ÚsleeprC   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   r1   r   r4   r5   rC   r   r   r   Úreset_input_buffer_  s   zSerial.reset_input_bufferc                 C   rf   )zs        Clear output buffer, aborting the current output and discarding all
        that is in the buffer.
        N)r!   r   r   r1   r   r2   r3   rC   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   Z_break_stater   ZSetCommBreakr   ZClearCommBreakrC   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)r?   r   ÚEscapeCommFunctionr   ZSETRTSZCLRRTSrC   r   r   r   Ú_update_rts_statew  ó   zSerial._update_rts_statec                 C   rj   )z-Set terminal status line: Data Terminal ReadyN)r@   r   rk   r   ZSETDTRZCLRDTRrC   r   r   r   Ú_update_dtr_state~  rm   zSerial._update_dtr_statec                 C   s.   | j stƒ ‚t ¡ }t | jt |¡¡ |jS r   )	r!   r   r   rG   ZGetCommModemStatusr   r)   r/   rW   )r   Ústatr   r   r   Ú_GetCommModemStatus…  s
   zSerial._GetCommModemStatusc                 C   ó   t j|  ¡ @ dkS )z(Read terminal status line: Clear To Sendr   )r   Z	MS_CTS_ONrp   rC   r   r   r   ÚctsŒ  ó   z
Serial.ctsc                 C   rq   )z)Read terminal status line: Data Set Readyr   )r   Z	MS_DSR_ONrp   rC   r   r   r   Údsr‘  rs   z
Serial.dsrc                 C   rq   )z)Read terminal status line: Ring Indicatorr   )r   Z
MS_RING_ONrp   rC   r   r   r   Úri–  rs   z	Serial.ric                 C   rq   )z)Read terminal status line: Carrier Detectr   )r   Z
MS_RLSD_ONrp   rC   r   r   r   Úcd›  rs   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   r,   r   )r   Zrx_sizeZ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   rk   r   ZSETXONZSETXOFF)r   Zenabler   r   r   Úset_output_flow_control«  s
   zSerial.set_output_flow_controlc                 C   rE   )z0Return how many bytes the in the outgoing bufferrF   )r   rG   rH   rI   r   r)   r/   r   r(   r*   ZcbOutQuerK   r   r   r   rb   ¹  rO   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   rG   rT   r   r)   r/   rQ   rS   ZERROR_IO_INCOMPLETEZ
CancelIoEx)r   Z
overlappedr\   Úerrr   r   r   Ú_cancel_overlapped_ioÂ  s   üþzSerial._cancel_overlapped_ioc                 C   ó   |   | j¡ dS )ry   N)r{   r   rC   r   r   r   rA   Ï  ó   zSerial.cancel_readc                 C   r|   )zBCancel a blocking write operation, may be called from other threadN)r{   r   rC   r   r   r   rB   Ó  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&   r(   r>   r   Ú	exclusiveÚ__set__)r   r~   r   r   r   r~   ×  s   zSerial.exclusive)r   )r    N)T)#Ú__name__Ú
__module__Ú__qualname__Ú__doc__Z	BAUDRATESr   r7   r0   r6   rD   ÚpropertyrN   r]   ra   re   rg   rh   ri   rl   rn   rp   rr   rt   ru   rv   rw   rx   rb   r{   rA   rB   r   r~   ÚsetterÚ__classcell__r   r   r   r   r	      sJ    A 

)%		





	
r	   )Z
__future__r   r)   rc   r>   r   Zserial.serialutilr   r   r   r   r   r	   r   r   r   r   Ú<module>   s   