3 M]WV@sddlZddlZddlZddlZddlZddlmZddlmZej ddye Wne k rre Z e ZYnXddZGdd d eZejd krddlZddlZGd d d eZGd ddeZnDejdkrddlZddlZddlZGdddeZnedjejGdddeZGdddeZGdddeZGdddeZ GdddeZ!Gddde!Z"GdddeZ#Gd d!d!eZ$Gd"d#d#eZ%eee d$Z&ee!e"e#e$e%d%Z'd&d'Z(Gd(d)d)eZ)d.d+d,Z*e+d-kre*dS)/N)comports) hexlify_codeccCs|dkrtjSdS)NZhexlify)r getregentry)cr/usr/lib/python3.6/miniterm.pysrcCs.t|}|dkr"djtd|St|SdS)z)generate a readable description for a key z Ctrl+{:c}@N)ordformatrepr) characterZ ascii_coderrrkey_descriptionsrc@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS) ConsoleBasez8OS abstraction for console (input/output codec, no echo)cCs*tjdkrtjj|_ntj|_tj|_dS)Nr)rr)sys version_infostdoutbuffer byte_outputoutput)selfrrr__init__,s  zConsoleBase.__init__cCsdS)z.Set console to read single characters, no echoNr)rrrrsetup3szConsoleBase.setupcCsdS)z Restore default console settingsNr)rrrrcleanup6szConsoleBase.cleanupcCsdS)z"Read a single key from the consoleNr)rrrrgetkey9szConsoleBase.getkeycCs|jj||jjdS)zWrite bytes (already encoded)N)rwriteflush)rZ byte_stringrrr write_bytes=s zConsoleBase.write_bytescCs|jj||jjdS)z Write stringN)rrr)rtextrrrrBs zConsoleBase.writecCsdS)zCancel getkey operationNr)rrrrcancelGszConsoleBase.cancelcCs |j|S)N)r)rrrr __enter__NszConsoleBase.__enter__cOs |jdS)N)r)rargskwargsrrr__exit__RszConsoleBase.__exit__N) __name__ __module__ __qualname____doc__rrrrrrr!r"r%rrrrr)srntc@s(eZdZdZddZddZddZdS) Outz$file-like wrapper that uses os.writecCs ||_dS)N)fd)rr,rrrr]sz Out.__init__cCsdS)Nr)rrrrr`sz Out.flushcCstj|j|dS)N)osrr,)rsrrrrcsz Out.writeN)r&r'r(r)rrrrrrrr+Zsr+cs4eZdZfddZddZddZddZZS) Consolecstt|jtjjj|_tjjj|_ tjjj dtjjj dt j dttjjd|_t j dttjjdt_|jt_d|j_dS)NizUTF-8replace)superr/rctypeswindllkernel32ZGetConsoleOutputCP _saved_ocpZ GetConsoleCP _saved_icpSetConsoleOutputCP SetConsoleCPcodecs getwriterr+rrfilenorstderrencoding)r) __class__rrrgszConsole.__init__cCs$tjjj|jtjjj|jdS)N)r2r3r4r7r5r8r6)rrrr__del__sszConsole.__del__cCsHxBtj}|tdkrtdS|tdtdfkrrr/fs  r/posixcs<eZdZfddZddZddZddZd d ZZS) r/csrtt|jtjj|_tj\|_ |_ t j |j|_ tj|jtjdkrftjtjjtj|_ntj|_dS)Nrr)rr)r1r/rrstdinr;r,r-pipepipe_rpipe_wtermios tcgetattroldatexitregisterrrr9 getreaderr= enc_stdin)r)r>rrrs   zConsole.__init__cCsbtj|j}|dtj@tj@tj@|d<d|dtj<d|dtj<tj|jtj |dS)Nrr) rMrNr,ZICANONZECHOZISIGZVMINZVTIME tcsetattrZTCSANOW)rnewrrrrs  $z Console.setupcCs^tj|j|jgggd\}}}|j|kr:tj|jddS|jjd}|tdkrZtd}|S)NrT)selectrSrKr-readrD)rZready_rrrrrs   zConsole.getkeycCstj|jddS)Nx)r-rrL)rrrrr!szConsole.cancelcCstj|jtj|jdS)N)rMrVr,Z TCSAFLUSHrO)rrrrrszConsole.cleanup) r&r'r(rrrr!rrGrr)r>rr/s   z9Sorry no implementation for your platform ({}) available.c@s(eZdZdZddZddZddZdS) Transformz&do-nothing: forward all data unchangedcCs|S)ztext received from serial portr)rr rrrrxsz Transform.rxcCs|S)ztext to be sent to serial portr)rr rrrtxsz Transform.txcCs|S)z(text to be sent but displayed on consoler)rr rrrechoszTransform.echoN)r&r'r(r)r_r`rarrrrr^sr^c@seZdZdZddZdS)CRLFzENTER sends CR+LFcCs |jddS)N z )r0)rr rrrr`szCRLF.txN)r&r'r(r)r`rrrrrbsrbc@s eZdZdZddZddZdS)CRzENTER sends CRcCs |jddS)N rc)r0)rr rrrr_szCR.rxcCs |jddS)Nrcre)r0)rr rrrr`szCR.txN)r&r'r(r)r_r`rrrrrdsrdc@seZdZdZdS)LFzENTER sends LFN)r&r'r(r)rrrrrfsrfc@sBeZdZdZeddedDZejddddd ZeZ d S) NoTerminalz0remove typical terminal control codes from inputccs&|]}t|dkr|d|fVqdS)z  i$N)rD).0r]rrr szNoTerminal.r i!$i%$)rXcCs |j|jS)N) translateREPLACEMENT_MAP)rr rrrr_sz NoTerminal.rxN) r&r'r(r)dictrangerlupdater_rarrrrrgs rgc@s8eZdZdZeddedDZejddddd S) NoControlsz%Remove all control codes, incl. CR+LFccs|]}|d|fVqdS)i$Nr)rhr]rrrriszNoControls.r i#$i!$i%$)r rXrjN)r&r'r(r)rmrnrlrorrrrrps rpc@seZdZdZddZeZdS) PrintablezMShow decimal code for all non-ASCII characters and replace most control codescCsg}x|D]x}d|ko dkns.|dkr:|j|q |dkrZ|jtdt|q |jdddjt|D|jdq Wdj|S) N z  i$css"|]}tdt|dVqdS)i 0N)rDr )rhdrrrriszPrintable.rx..z{:d})appendrDr extendr join)rr rrrrrr_s   z Printable.rxN)r&r'r(r)r_rarrrrrqs rqc@s(eZdZdZddZddZddZdS) Colorizez,Apply different colors for received and echocCsd|_d|_dS)Nzz) input_color echo_color)rrrrr szColorize.__init__cCs |j|S)N)r|)rr rrrr_sz Colorize.rxcCs |j|S)N)r})rr rrrrasz Colorize.echoN)r&r'r(r)rr_rarrrrr{ sr{c@s eZdZdZddZddZdS)DebugIOzPrint what is sent and receivedcCs$tjjdjt|tjj|S)Nz [RX:{}] )rr<rr r r)rr rrrr_s z DebugIO.rxcCs$tjjdjt|tjj|S)Nz [TX:{}] )rr<rr r r)rr rrrr`!s z DebugIO.txN)r&r'r(r)r_r`rrrrr~sr~)crlfZcrZlf)ZdirectdefaultZ nocontrolZ printableZcolorizedebugc Cstjjdg}xBtttdD].\}\}}}tjjdj||||j|q"Wxdtd}y:t |d}d|kot |knstjjdwVWnt k rYn X||}|SdS)z Show a list of ports and ask the user for a choice. To make selection easier on systems with long device names, also allow the input of an index. z --- Available ports: rTz--- {:2}: {:20} {} z#--- Enter port index or full name: rz--- Invalid index! N) rr<r enumeratesortedrr rw raw_inputintlen ValueError)ZportsnportZdescZhwidindexrrr ask_for_port<s     rc@seZdZdZddffddZddZdd Zd d Zd d Zd$ddZ ddZ ddZ d%ddZ d&ddZ ddZddZddZdd Zd!d"Zd#S)'Minitermz Terminal application. Copy data from serial port to console and vice versa. Handle special keys from the console to show menu etc. FrcCsht|_||_||_d|_d|_d|_||_||_|j d|_ d|_ d|_ d|_ d|_d|_d|_dS)NFzUTF-8)r/consoleserialrarawinput_encodingoutput_encodingeolfiltersupdate_transformationsexit_charactermenu_characteralive _reader_alivereceiver_thread rx_decoderZ tx_decoder)rserial_instancerarrrrrr[s zMiniterm.__init__cCs.d|_tj|jdd|_d|j_|jjdS)zStart reader threadTr_)targetnameN)r threadingThreadreaderrdaemonstart)rrrr _start_readermszMiniterm._start_readercCs*d|_t|jdr|jj|jjdS)z6Stop reader thread only, wait for clean exit of threadF cancel_readN)rhasattrrrrry)rrrr _stop_readerus  zMiniterm._stop_readercCs@d|_|jtj|jdd|_d|j_|jj|jj dS)zstart worker threadsTr`)rrN) rrrrwritertransmitter_threadrrrr)rrrrr|s  zMiniterm.startcCs d|_dS)zset flag to stop worker threadsFN)r)rrrrstopsz Miniterm.stopcCs2|jj|s.t|jdr$|jj|jjdS)z$wait for worker threads to terminaterN)rryrrrr)rZ transmit_onlyrrrrys    z Miniterm.joincCs|jjdS)N)rclose)rrrrrszMiniterm.closecCs@t|jgdd|jD}dd|D|_tt|j|_dS)zFtake list of transformation classes and instantiate them for rx and txcSsg|] }t|qSr)TRANSFORMATIONS)rhfrrr sz3Miniterm.update_transformations..cSsg|] }|qSrr)rhtrrrrsN)EOL_TRANSFORMATIONSrrtx_transformationslistreversedrx_transformations)rZtransformationsrrrrs zMiniterm.update_transformationsr0cCs||_tj|||_dS)zset encoding for received dataN)rr9getincrementaldecoderr)rr=errorsrrrset_rx_encodingszMiniterm.set_rx_encodingcCs||_tj|||_dS)z!set encoding for transmitted dataN)rr9getincrementalencoder tx_encoder)rr=rrrrset_tx_encodingszMiniterm.set_tx_encodingc CsNtjjdj|jdtjjdj|jjr,dnd|jjr:dnd|jjrHdndyLtjjdj|jjrhdnd|jj rvdnd|jj rdnd|jj rdndWntj k rYnXtjjdj|jj rdndtjjdj|jjrdndtjjd j|jtjjd j|jtjjd j|jjtjjd jd j|jdS)z$Write current settings to sys.stderrzK --- Settings: {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} )pz&--- RTS: {:8} DTR: {:8} BREAK: {:8} activeinactivez---- CTS: {:8} DSR: {:8} RI: {:8} CD: {:8} z--- software flow control: {} z--- hardware flow control: {} z--- serial input encoding: {} z--- serial output encoding: {} z --- EOL: {} z--- filters: {} rrN)rr<rr rrtsdtrbreak_conditionZctsZdsrZriZcdSerialExceptionxonxoffrtsctsrrrupperryr)rrrrdump_port_settingss(    zMiniterm.dump_port_settingsc Csytxn|jrp|jrp|jj|jjp d}|r|jr<|jj|q|jj |}x|j D]}|j |}qPW|jj |qWWn(tj k rd|_|jjYnXdS)zloop and copy serial->consolerTFN)rrrr[Z in_waitingrrrrdecoderr_rrr!)rdatar transformationrrrrs   zMiniterm.readercCsd}yx|jry|jj}Wntk r4d}YnX|js>P|rR|j|d}q||jkrbd}q||jkrx|jPq|}x|jD]}|j |}qW|j j |j j ||jr|}x|jD]}|j|}qW|jj |qWWnd|_YnXdS)z Loop and copy console->serial until self.exit_character character is found. When self.menu_character is found, interpret the next key locally. FTN)rrrKeyboardInterrupthandle_menu_keyrrrrr`rrrencodera)rZ menu_activerr rZ echo_textrrrrs:      zMiniterm.writercCs||jks||jkr>|jj|jj||jr:|jj|nZ|dkr:tj jdtj j |jtj j j d}|r,yvt|dP}tj jdj|x6|jd}|sP|jj||jj tj jdqWWdQRXtj jd j|Wn8tk r*}ztj jd j||WYdd}~XnXWdQRXn^|d krXtj j|jn@|d kr|jj |j_tj jd j|jjrdndn|dkr|jj |j_tj jdj|jjrdndn|dkr |jj |j_tj jdj|jjrdndn|dkrB|j |_tj jdj|jr6dndnV|dkrtj jdtj jdjddttjDtj jdjdj|j|jtj j jj}WdQRX|rx>|D](}|tkrtj jdjt|PqW||_|jtj jdjdj|jnz|dkrtt }|j!|j"d }|t#|krRd!}|||_"tj jd"j|j"j$|jn|d#krt5k r:}z tj jd,j|| j6WYdd}~Xn(X|jj6| |_tj jd-j|jj0|j7n*|d.krtj jd/tj j |jp|jj8} yt9tj j j&|j_8Wn>t:k r}z tj jd0j|| |j_8WYdd}~Xn X|j-WdQRXn|d1kr.tj;|j_<|j-nj|d2krNtj=|j_<|j-nJ|d3krntj>|j_?|j-n*|d4krtj@|j_?|j-n |d5krtjA|j_?|j-n|d6krtjB|j_?|j-n|d7krtjC|j_?|j-n|d8krtjD|j_E|j-n|d9kr$tjF|j_E|j-nt|d:krBtjG|j_E|j-nV|d;krb|dk|j_I|j-ntj jd?jtJ|dS)@z"Implement a simple menu / settingsz --- File to upload: z rbz--- Sending file {} --- i.Nz --- File {} sent --- z"--- ERROR opening file {}: {} --- zhH?z--- RTS {} --- rrz--- DTR {} --- z--- BREAK {} --- z--- local echo {} --- z --- Available Filters: rccss|]\}}dj||VqdS)z--- {:<10} = {.__doc__}N)r )rhkvrrrri$sz+Miniterm.handle_menu_key..z$ --- Enter new filter name(s) [{}]: rrz--- unknown filter: {}z--- filters: {}  rTrz--- EOL: {} --- z# --- Enter new encoding name [{}]: z--- invalid encoding name: {} z--- serial input encoding: {} z--- serial output encoding: {}  ZpPT) do_not_openz#--- ERROR opening new port: {} --- z--- Port changed to: {} --- ZbBz --- Baudrate: z#--- ERROR setting baudrate: {} --- 87ZeEZoOZmMZsSZnN123ZxXXZrRRz!--- unknown menu character {} -- )Krrrrrrrarrr<rrIreadlinerstripopenr r[IOError get_help_textrrrryrritemsrlowersplitr rrrrrrrrstripr9lookup LookupErrorrrrrrrrrZgetSettingsDictserial_for_urlZapplySettingsDict ExceptionrrbaudraterrZ EIGHTBITSZbytesizeZ SEVENBITSZ PARITY_EVENparityZ PARITY_ODDZ PARITY_MARKZ PARITY_SPACEZ PARITY_NONEZ STOPBITS_ONEZstopbitsZ STOPBITS_TWOZSTOPBITS_ONE_POINT_FIVErrr)rrfilenamerblockeZ new_filtersZmodesrZ new_encodingrZsettingsZ new_serialZbackuprrrrs&       4  $ $ $  "                                                            zMiniterm.handle_menu_keycCsZdjttddt|jt|jtdtdtdtdtdtd td td td d S)zreturn the help textaQ --- pySerial ({version}) - miniterm - help --- --- {exit:8} Exit program --- {menu:8} Menu escape key, followed by: --- Menu keys: --- {menu:7} Send the menu character itself to remote --- {exit:7} Send the exit character itself to remote --- {info:7} Show info --- {upload:7} Upload file (prompt will be shown) --- {repr:7} encoding --- {filter:7} edit filters --- Toggles: --- {rts:7} RTS {dtr:7} DTR {brk:7} BREAK --- {echo:7} echo {eol:7} EOL --- --- Port settings ({menu} followed by the following): --- p change port --- 7 8 set data bits --- N E O S M change parity (None, Even, Odd, Space, Mark) --- 1 2 3 set stop bits (1, 2, 1.5) --- b change baud rate --- x X disable/enable software flow control --- r R disable/enable hardware flow control VERSIONzunknown versionrrrrrrrrr) versionexitZmenurrZbrkrainfoZuploadr filterr)r getattrrrrr)rrrrrszMiniterm.get_help_textN)F)r0)r0)r&r'r(r)rrrrrryrrrrrrrrrrrrrrUs"    &$r%c Csddl}|jdd}|jddd|d|jd dtd |d |jd }|jd dddddgddddd|jddddd|jddddd|jdtd|d |jd!td"|d |jd#dd$dd|jd%}|jd&d'dd(dd|jd)d*d+d,d-d.|jd/d0d1d2d3gd4|jd5d6d7d8gd9dd:d8d|jd;ddtd?d@dAdB|jdCtd?dDdEdB|jdF}|jdGdHddIdd|jdJddKdd|j}|j|jkr|jdL|j rdM|j krt j j dNt j j dOj dPdQttjDt j j dOt jdR|j }ndSg}x|jdks>|jdTkry t|_Wn,tk rvt j j dO|jdUYnX|js|jdVytj|j|j|j|j|jdWdX} t| dYsdR| _|jdk r|jst j j dZj|jrd[nd\|j| _|j dk r2|js*t j j d]j|j r"d[nd\|j | _ | j!Wndtj"k r} zDt j j d^jt#|j| |j$rv|j%st jdRndT|_WYdd} ~ XnXPq&Wt&| |j'|j(j)|d_} t*|j| _+t*|j| _,|j-| _-| j.|j/| j0|j/|jsFt j j d`j| jdat j j dbjt1| j+t1| j,t1| j,t1dc| j2y| j dWWntk rrYnX|jst j j dd| j | j3dS)ezCommand line tool, entry pointrNz9Miniterm - A simple terminal program for the serial port.) descriptionr?z(serial port name ('-' to show port list))nargshelprrz#set baud rate, default: %(default)s)rtyperrz port settingsz--parityNEOSMcSs|jS)N)r)rrrrrszmain..z*set parity, one of {N E O S M}, default: N)choicesrrrz--rtscts store_truez)enable RTS/CTS flow control (default off)F)actionrrz --xonxoffz*enable software flow control (default off)z--rtsz2set initial RTS line state (possible values: 0, 1))rrrz--dtrz2set initial DTR line state (possible values: 0, 1)z--askz"ask again for port when open failsz data handlingz-ez--echozenable local echo (default off)z --encodingserial_port_encodingZCODECzXset the encoding for the serial port (e.g. hexlify, Latin1, UTF-8), default: %(default)szUTF-8)destmetavarrrz-fz--filterrwNAMEzadd text transformation)rr rrz--eolrdrfrbcSs|jS)N)r)rrrrrszend of line modez--rawz)Do no apply any encodings/transformationsZhotkeysz --exit-charZNUMzWUnicode of special character that is used to exit the application, default: %(default)sr)rr rrz --menu-charz_Unicode code of special character that is used to control miniterm (menu), default: %(default)srZ diagnosticsz-qz--quietzsuppress non-error messagesz --developzshow Python traceback on errorz.--exit-char can not be the same as --menu-charrzAvailable filters: rccss|]\}}dj||VqdS)z{:<10} = {.__doc__}N)r )rhrrrrrriMszmain..rTr-z"user aborted and port is not givenzport is not givenT)rrrrrz--- forcing DTR {} rrz--- forcing RTS {} zcould not open port {}: {} )rarrzP--- Miniterm on {p.name} {p.baudrate},{p.bytesize},{p.parity},{p.stopbits} --- )rz6--- Quit: {} | Menu: {} | Help: {} followed by {} --- z --- exit --- )4argparseArgumentParser add_argumentrZadd_argument_group parse_argsZ menu_charZ exit_charerrorrrr<rryrrrrrrrrrrrrrrZtimeoutrquietr rrrr ZdevelopZaskrrarrrDrrrrr rrrr) Z default_portZdefault_baudrateZ default_rtsZ default_dtrrparsergroupr#rrrZminitermrrrmains^                            r__main__)NrNN),r9r-rrrZserial.tools.list_portsrZ serial.toolsrrQr NameErrorinputchrrDrobjectrrrCr2r+r/rPrMrZNotImplementedErrorr platformr^rbrdrfrgrprqr{r~rrrrrr&rrrr sh    -  ! &  t [