[{"data":1,"prerenderedAt":554},["ShallowReactive",2],{"navigation":3,"\u002Fplatforms\u002Ftcp":116,"\u002Fplatforms\u002Ftcp-surround":549},[4,27,53,74,108,112],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,14,18,22],{"title":11,"path":12,"stem":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction",{"title":15,"path":16,"stem":17},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation",{"title":19,"path":20,"stem":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start",{"title":23,"path":24,"stem":25},"Example app and development","\u002Fgetting-started\u002Fdevelopment","1.getting-started\u002F4.development",false,{"title":28,"icon":29,"path":30,"stem":31,"children":32,"page":26},"Guides","i-lucide-book-open","\u002Fguides","2.guides",[33,37,41,45,49],{"title":34,"path":35,"stem":36},"JavaScript API","\u002Fguides\u002Fjavascript-api","2.guides\u002F1.javascript-api",{"title":38,"path":39,"stem":40},"AT commands, exchange and CMUX","\u002Fguides\u002Fat-commands","2.guides\u002F2.at-commands",{"title":42,"path":43,"stem":44},"Rust","\u002Fguides\u002Frust","2.guides\u002F3.rust",{"title":46,"path":47,"stem":48},"Permissions","\u002Fguides\u002Fpermissions","2.guides\u002F4.permissions",{"title":50,"path":51,"stem":52},"Parsers","\u002Fguides\u002Fparsers","2.guides\u002F5.parsers",{"title":54,"icon":55,"path":56,"stem":57,"children":58,"page":26},"API reference","i-lucide-file-code","\u002Freference","3.reference",[59,63,67,71],{"title":60,"path":61,"stem":62},"SerialPort","\u002Freference\u002Fserial-port","3.reference\u002F1.serial-port",{"title":64,"path":65,"stem":66},"Types","\u002Freference\u002Ftypes","3.reference\u002F2.types",{"title":68,"path":69,"stem":70},"Tauri commands","\u002Freference\u002Fcommands","3.reference\u002F3.commands",{"title":46,"path":72,"stem":73},"\u002Freference\u002Fpermissions","3.reference\u002F4.permissions",{"title":75,"icon":76,"path":77,"stem":78,"children":79,"page":26},"Platforms","i-lucide-monitor-smartphone","\u002Fplatforms","4.platforms",[80,84,88,92,96,100,104],{"title":81,"path":82,"stem":83},"Overview","\u002Fplatforms\u002Foverview","4.platforms\u002F1.overview",{"title":85,"path":86,"stem":87},"Desktop","\u002Fplatforms\u002Fdesktop","4.platforms\u002F2.desktop",{"title":89,"path":90,"stem":91},"Android (USB)","\u002Fplatforms\u002Fandroid","4.platforms\u002F3.android",{"title":93,"path":94,"stem":95},"iOS","\u002Fplatforms\u002Fios","4.platforms\u002F4.ios",{"title":97,"path":98,"stem":99},"Serial over TCP","\u002Fplatforms\u002Ftcp","4.platforms\u002F5.tcp",{"title":101,"path":102,"stem":103},"Bluetooth LE (BLE)","\u002Fplatforms\u002Fble","4.platforms\u002F6.ble",{"title":105,"path":106,"stem":107},"DTR \u002F RTS on open","\u002Fplatforms\u002Fdtr-rts","4.platforms\u002F7.dtr-rts",{"title":109,"path":110,"stem":111},"Migration guide","\u002Fmigration","5.migration",{"title":113,"path":114,"stem":115},"Changelog","\u002Fchangelog","9.changelog",{"id":117,"title":97,"body":118,"description":542,"extension":543,"generated":26,"links":544,"meta":545,"navigation":546,"path":98,"seo":547,"stem":99,"__hash__":548},"docs\u002F4.platforms\u002F5.tcp.md",{"type":119,"value":120,"toc":539},"minimark",[121,138,162,289,326,331,340,434,517,523,535],[122,123,124,125,129,130,133,134,137],"p",{},"Any path of the form ",[126,127,128],"code",{},"tcp:\u002F\u002Fhost:port"," talks raw bytes to a TCP serial bridge:\n",[126,131,132],{},"ser2net"," (raw mode), ESP-Link, Moxa\u002FUSR device servers, or ",[126,135,136],{},"socat",":",[139,140,145],"pre",{"className":141,"code":142,"language":143,"meta":144,"style":144},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","socat TCP-LISTEN:4000,reuseaddr,fork FILE:\u002Fdev\u002FttyUSB0,raw,echo=0,b115200\n","bash","",[126,146,147],{"__ignoreMap":144},[148,149,152,155,159],"span",{"class":150,"line":151},"line",1,[148,153,136],{"class":154},"sBMFI",[148,156,158],{"class":157},"sfazB"," TCP-LISTEN:4000,reuseaddr,fork",[148,160,161],{"class":157}," FILE:\u002Fdev\u002FttyUSB0,raw,echo=0,b115200\n",[139,163,167],{"className":164,"code":165,"language":166,"meta":144,"style":144},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const port = new SerialPort({ path: \"tcp:\u002F\u002F192.168.1.50:4000\", baudRate: 115200 });\nawait port.open();\nawait port.watch({ onData: console.log });\n","ts",[126,168,169,232,253],{"__ignoreMap":144},[148,170,171,175,179,183,186,190,193,196,200,202,205,208,211,214,217,219,223,226,229],{"class":150,"line":151},[148,172,174],{"class":173},"spNyl","const",[148,176,178],{"class":177},"sTEyZ"," port ",[148,180,182],{"class":181},"sMK4o","=",[148,184,185],{"class":181}," new",[148,187,189],{"class":188},"s2Zo4"," SerialPort",[148,191,192],{"class":177},"(",[148,194,195],{"class":181},"{",[148,197,199],{"class":198},"swJcz"," path",[148,201,137],{"class":181},[148,203,204],{"class":181}," \"",[148,206,207],{"class":157},"tcp:\u002F\u002F192.168.1.50:4000",[148,209,210],{"class":181},"\"",[148,212,213],{"class":181},",",[148,215,216],{"class":198}," baudRate",[148,218,137],{"class":181},[148,220,222],{"class":221},"sbssI"," 115200",[148,224,225],{"class":181}," }",[148,227,228],{"class":177},")",[148,230,231],{"class":181},";\n",[148,233,235,239,242,245,248,251],{"class":150,"line":234},2,[148,236,238],{"class":237},"s7zQu","await",[148,240,241],{"class":177}," port",[148,243,244],{"class":181},".",[148,246,247],{"class":188},"open",[148,249,250],{"class":177},"()",[148,252,231],{"class":181},[148,254,256,258,260,262,265,267,269,272,274,277,279,282,285,287],{"class":150,"line":255},3,[148,257,238],{"class":237},[148,259,241],{"class":177},[148,261,244],{"class":181},[148,263,264],{"class":188},"watch",[148,266,192],{"class":177},[148,268,195],{"class":181},[148,270,271],{"class":198}," onData",[148,273,137],{"class":181},[148,275,276],{"class":177}," console",[148,278,244],{"class":181},[148,280,281],{"class":177},"log ",[148,283,284],{"class":181},"}",[148,286,228],{"class":177},[148,288,231],{"class":181},[290,291,292,303],"ul",{},[293,294,295,296,299,300,302],"li",{},"When the bridge closes the connection you get ",[126,297,298],{},"onDisconnect",", like an unplug.\nTCP keepalive is on (first probe after 10 s idle, then every 5 s; 3 probes on\nLinux, Android, macOS and iOS, the system's 10 on Windows), so a bridge that\nvanished without closing (power cut, Wi-Fi drop) also ends in ",[126,301,298],{}," after\nabout 25 s of silence (about 60 s on Windows) instead of the port timing out\nforever. If the system rejects a keepalive option the port still opens (a warning\nis logged), just without that detection.",[293,304,305,306,309,310,313,314,317,318,321,322,325],{},"Baud rate, parity and modem lines are kept locally and not sent; configure the\nserial side on the bridge (RFC 2217 is not implemented). The modem-line setters\nsucceed and the getters return fixed values (CTS\u002FDSR\u002FDCD on, RI off). From Rust,\n",[126,307,308],{},"SerialManager::supports_modem_lines(path)"," is ",[126,311,312],{},"false"," for ",[126,315,316],{},"tcp:\u002F\u002F"," and ",[126,319,320],{},"ble:\u002F\u002F","\npaths (and CMUX channels ",[126,323,324],{},"…#dlci=N",", where line calls fail), so code that needs\nreal RTS\u002FCTS can refuse them.",[327,328,330],"h2",{"id":329},"restricting-which-bridges-the-webview-may-open","Restricting which bridges the webview may open",[122,332,333,334,336,337,137],{},"By default any ",[126,335,128],{}," can be opened. To limit what the frontend can reach,\nlist the allowed addresses in ",[126,338,339],{},"tauri.conf.json",[139,341,345],{"className":342,"code":343,"language":344,"meta":144,"style":144},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"plugins\": {\n    \"serialplugin-config\": {\n      \"tcpAllowlist\": [\"192.168.1.50:4000\", \"bridge.local:23\"]\n    }\n  }\n}\n","json",[126,346,347,352,367,381,416,422,428],{"__ignoreMap":144},[148,348,349],{"class":150,"line":151},[148,350,351],{"class":181},"{\n",[148,353,354,357,360,362,364],{"class":150,"line":234},[148,355,356],{"class":181},"  \"",[148,358,359],{"class":173},"plugins",[148,361,210],{"class":181},[148,363,137],{"class":181},[148,365,366],{"class":181}," {\n",[148,368,369,372,375,377,379],{"class":150,"line":255},[148,370,371],{"class":181},"    \"",[148,373,374],{"class":154},"serialplugin-config",[148,376,210],{"class":181},[148,378,137],{"class":181},[148,380,366],{"class":181},[148,382,384,387,390,392,394,397,399,402,404,406,408,411,413],{"class":150,"line":383},4,[148,385,386],{"class":181},"      \"",[148,388,389],{"class":221},"tcpAllowlist",[148,391,210],{"class":181},[148,393,137],{"class":181},[148,395,396],{"class":181}," [",[148,398,210],{"class":181},[148,400,401],{"class":157},"192.168.1.50:4000",[148,403,210],{"class":181},[148,405,213],{"class":181},[148,407,204],{"class":181},[148,409,410],{"class":157},"bridge.local:23",[148,412,210],{"class":181},[148,414,415],{"class":181},"]\n",[148,417,419],{"class":150,"line":418},5,[148,420,421],{"class":181},"    }\n",[148,423,425],{"class":150,"line":424},6,[148,426,427],{"class":181},"  }\n",[148,429,431],{"class":150,"line":430},7,[148,432,433],{"class":181},"}\n",[290,435,436,452,478,489,506],{},[293,437,438,439,442,443,445,446,448,449,451],{},"With the key set, ",[126,440,441],{},"open()"," from JavaScript fails for a ",[126,444,316],{}," address not in the\nlist; an empty list blocks every ",[126,447,316],{},". Local and ",[126,450,320],{}," ports are not\naffected.",[293,453,454,455,458,459,461,462,465,466,469,470,473,474,477],{},"The whole ",[126,456,457],{},"host:port"," text after ",[126,460,316],{}," is compared with each entry as written,\nignoring ASCII case only. Nothing is normalized, so ",[126,463,464],{},"10.0.0.5:04000",", ",[126,467,468],{},"[::1]:23","\nagainst an expanded IPv6 form, ",[126,471,472],{},"name.:23"," (trailing dot), ",[126,475,476],{},"user@host:23"," or extra\nwhitespace are refused unless listed exactly: list the strings your app opens. A\nlisted DNS name trusts the resolver: every address it returns is tried.",[293,479,480,481,484,485,488],{},"Rust code using ",[126,482,483],{},"SerialManager"," \u002F ",[126,486,487],{},"api::SerialPort"," directly is not restricted.",[293,490,491,492,494,495,498,499,502,503,505],{},"The key is ",[126,493,374],{},", not ",[126,496,497],{},"serialplugin",": ",[126,500,501],{},"plugins.serialplugin"," must\nstay unset (the plugin takes no typed config there in 4.x). A malformed\n",[126,504,389],{}," fails app start-up rather than allowing everything.",[293,507,508,509,513,514,516],{},"Use ",[510,511,512],"strong",{},"one client per bridge",". A serial line has a single reader: with a forking\nbridge and two clients, each reply goes to whichever connection reads first.\n",[126,515,132],{}," allows one connection per port by default.",[122,518,519,520,522],{},"The example app on iOS and Android, talking to a Quectel M26 modem through\n",[126,521,136],{}," on the host:",[122,524,525,531],{},[526,527],"img",{"alt":528,"src":529,"width":530},"iOS simulator: ATI over tcp:\u002F\u002F to a Quectel M26","\u002Fscreenshots\u002Fios-tcp-quectel.png",300,[526,532],{"alt":533,"src":534,"width":530},"Android emulator: ATI and AT+CSQ over tcp:\u002F\u002F to a Quectel M26","\u002Fscreenshots\u002Fandroid-tcp-quectel.png",[536,537,538],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":144,"searchDepth":234,"depth":255,"links":540},[541],{"id":329,"depth":234,"text":330},"tcp:\u002F\u002Fhost:port paths to a TCP serial bridge on every platform.","md",null,{},true,{"title":97,"description":542},"tm1knOBiTbcNtL1GsGs2_dS9X9Uk76CCJPQKVT9NlwQ",[550,552],{"title":93,"path":94,"stem":95,"description":551,"children":-1},"What works on iOS and why there are no local ports.",{"title":101,"path":102,"stem":103,"description":553,"children":-1},"ble:\u002F\u002F paths to Nordic UART Service devices behind the ble feature (desktop, iOS, Android).",1794158000996]