wifi-setup.sh 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418
  1. #!/bin/sh
  2. ## script to setup uci wireless configuration for use with wifimanager utility
  3. . /usr/share/libubox/jshn.sh
  4. ### global variables
  5. # options
  6. bVerbose=0
  7. bJson=0
  8. bBase64=0
  9. bError=0
  10. #commands
  11. bCmd=0
  12. bCmdAdd=0
  13. bCmdEdit=0
  14. bCmdDisable=0
  15. bCmdEnable=0
  16. bCmdRemove=0
  17. bCmdClear=0 # for clearing saved network entries
  18. bCmdReset=0 # for overwriting wireless config with factory file
  19. bCmdPriority=0
  20. bCmdList=0
  21. bCmdInfo=0
  22. bCmdDebug=0
  23. #parameters
  24. bApNetwork=0
  25. #############################
  26. ##### Print Usage ###########
  27. usage () {
  28. _Print "Functionality:"
  29. _Print " Configure WiFi networks on the Omega"
  30. _Print ""
  31. _Print "Interactive Usage:"
  32. _Print "$0"
  33. _Print " Accepts user input"
  34. _Print ""
  35. _Print ""
  36. _Print "Command Line Usage:"
  37. _Print "$0 [options] <command> <parameters>"
  38. _Print ""
  39. _Print ""
  40. _Print "Available Commands:"
  41. _Print " add "
  42. _Print "Functionality: Add a new WiFi network to the Omega's settings"
  43. _Print "Usage: $0 add -ssid <ssid> -encr <encryption type> -password <password>"
  44. _Print "Valid encryption types [psk2, psk, wep, none]"
  45. _Print ""
  46. _Print " edit "
  47. _Print "Functionality: Edit the information of a configured WiFi network"
  48. _Print "Usage: $0 edit -ssid <ssid> -encr <encryption type> -password <password>"
  49. _Print ""
  50. _Print " remove "
  51. _Print "Functionality: Remove an existing WiFi network from the Omega's settings"
  52. _Print "Usage: $0 remove -ssid <ssid>"
  53. _Print ""
  54. _Print " priority "
  55. _Print "Functionality: Move a WiFi network up or down in the priority list when attempting to connect"
  56. _Print "Usage: $0 priority -ssid <ssid> -move <up|down>"
  57. _Print " up: increase the priority"
  58. _Print " down: decrease the priority"
  59. _Print " top: make highest priority network"
  60. _Print ""
  61. _Print " list "
  62. _Print "Functionality: Display a JSON-formatted list of all configured networks"
  63. _Print "Usage: $0 list"
  64. _Print ""
  65. _Print " info "
  66. _Print "Functionality: Display a JSON-formatted table of all info for specified network"
  67. _Print "Usage: $0 info -ssid <ssid>"
  68. _Print ""
  69. _Print " clear "
  70. _Print "Functionality: Clear all saved network configurations"
  71. _Print "Usage: $0 clear"
  72. _Print ""
  73. #_Print " reset "
  74. #_Print "Functionality: Completely reset wireless network configuration to factory settings"
  75. #_Print "Usage: $0 reset"
  76. #_Print ""
  77. _Print ""
  78. _Print "Command Line Options:"
  79. _Print " -v Increase output verbosity"
  80. _Print " -j Set all output to JSON"
  81. _Print " -ap Set any commands above to refer to an AP network"
  82. _Print " -b64 Input arguments are base64 encoded"
  83. _Print ""
  84. }
  85. #############################
  86. ##### General Functions #####
  87. # initialize the json
  88. _Init () {
  89. if [ $bJson == 1 ]; then
  90. # json setup
  91. json_init
  92. fi
  93. }
  94. # prints a message, taking json output into account
  95. # $1 - the message to print
  96. # $2 - the json index string
  97. _Print () {
  98. if [ $bJson == 0 ]; then
  99. echo "$1"
  100. else
  101. json_add_string "$2" "$1"
  102. fi
  103. }
  104. # set an error flag
  105. _SetError () {
  106. bError=1
  107. }
  108. # close and print the json
  109. _Close () {
  110. if [ $bJson == 1 ]; then
  111. # print the error status
  112. local output=$((!$bError))
  113. json_add_boolean "success" $output
  114. # print the json
  115. json_dump
  116. fi
  117. }
  118. # decode a base64 encoded string
  119. # $1 - base64 encoded string
  120. # returns decoded string
  121. _base64Decode () {
  122. local string="$1"
  123. string=$(echo "$string" | base64 -d)
  124. echo "$string"
  125. }
  126. ########################################
  127. ### UCI Searching Functions
  128. ########################################
  129. # find total number of configured wifi networks
  130. # returns value via echo
  131. _FindNumNetworks () {
  132. local count=0
  133. # find the first network
  134. local network=$(uci -q get wireless.\@wifi-config[$count])
  135. # loop through all configured networks
  136. while [ "$network" == "wifi-config" ]
  137. do
  138. # add to the count
  139. count=$(($count + 1))
  140. # continue the loop
  141. network=$(uci -q get wireless.\@wifi-config[$count])
  142. done
  143. # return the count number
  144. echo $count
  145. }
  146. # find a network's array number by the ssid
  147. # $1 - ssid to look for
  148. # returns value via echo
  149. # -1: if not found
  150. # all others: valid value found
  151. _FindNetworkBySsid () {
  152. local id=-1
  153. local count=0
  154. local ssidKey="$1"
  155. # ensure argument is present
  156. if [ "$ssidKey" != "" ]; then
  157. # find the first network
  158. local network=$(uci -q get wireless.\@wifi-config[$count])
  159. # loop through all configured networks
  160. while [ "$network" == "wifi-config" ]
  161. do
  162. # find the ssid
  163. local ssid=$(uci -q get wireless.\@wifi-config[$count].ssid)
  164. if [ "$ssid" == "$ssidKey" ]; then
  165. id=$count
  166. break
  167. fi
  168. # continue the loop
  169. count=$(($count + 1))
  170. network=$(uci -q get wireless.\@wifi-config[$count])
  171. done
  172. fi
  173. # return the count number
  174. echo $id
  175. }
  176. # find a networks SSID from the id
  177. # returns value via echo
  178. # $1 - network id
  179. _FindNetworkSsid () {
  180. if [ $bApNetwork == 1 ]; then
  181. local ssidName=$(uci -q get wireless.\@wifi-iface[$1].ssid)
  182. #local ssidName=$(uci -q get wireless.ap.ssid) # confirm the fix
  183. else
  184. local ssidName=$(uci -q get wireless.\@wifi-config[$1].ssid)
  185. fi
  186. echo $ssidName
  187. }
  188. ########################################
  189. ### UCI Interaction Functions
  190. ########################################
  191. # commit changes to wireless config
  192. UciCommitWireless () {
  193. uci commit wireless
  194. }
  195. # add a wireless.wifi-config section
  196. UciAddWifiConfigSection () {
  197. uci add wireless wifi-config > /dev/null
  198. }
  199. # get a wireless.wifi-config section based on it's index number
  200. # input:
  201. # $1 - index
  202. # output:
  203. # if section found: "wifi-config"
  204. # no section found: ""
  205. UciCheckWifiConfigIndex () {
  206. local index=$1
  207. local config=""
  208. if [ $index -ge 0 ]; then
  209. config=$(uci -q get wireless.\@wifi-config[$index])
  210. fi
  211. echo "$config"
  212. }
  213. # populate a wireless.wifi-config section
  214. # input:
  215. # $1 - index
  216. # $2 - ssid
  217. # $3 - encryption
  218. # $4 - password
  219. # $5 - bssid (optional)
  220. UciPopulateWifiConfigSection () {
  221. local index="$1"
  222. local ssid="$2"
  223. local encryption="$3"
  224. local password="$4"
  225. local bssid="$5"
  226. # set the network key based on the encryption
  227. case "$encryption" in
  228. psk2|psk)
  229. uci set wireless.\@wifi-config[$index].key="$password"
  230. ;;
  231. wep)
  232. uci set wireless.\@wifi-config[$index].key=1
  233. uci set wireless.\@wifi-config[$index].key1="$password"
  234. ;;
  235. none|*)
  236. # empty value for open networks
  237. uci set wireless.\@wifi-config[$index].key=''
  238. ;;
  239. esac
  240. # set the ssid and encryption type
  241. uci set wireless.\@wifi-config[$index].ssid="$ssid"
  242. uci set wireless.\@wifi-config[$index].encryption="$encrypt"
  243. # set the bssid
  244. if [ "$bssid" != "" ]; then
  245. uci set wireless.\@wifi-config[$index].bssid="$bssid"
  246. fi
  247. # commit the changes
  248. UciCommitWireless
  249. # TODO: ensure the above is required
  250. }
  251. # delete a wireless.wifi-config section
  252. # input:
  253. # $1 - index
  254. # $2 - ssid
  255. UciDeleteWifiConfigSection () {
  256. local index=$1
  257. local ssid=$2
  258. # remove the section
  259. uci delete wireless.\@wifi-config[$index]
  260. # commit the changes
  261. UciCommitWireless
  262. }
  263. # reorder a wireless.wifi-config section
  264. # input:
  265. # $1 - index
  266. # $2 - ssid
  267. # $3 - desired order number in uci config
  268. # $4 - priority number in terms of other networks (optional)
  269. UciReorderWifiConfigSection () {
  270. local index=$1
  271. local ssid=$2
  272. local priority=$3
  273. local humanPriority=$4
  274. # check that this wifi-config exists
  275. local config=$(UciCheckWifiConfigIndex $index)
  276. if [ "$config" != "" ]; then
  277. # print a message
  278. if [ "$humanPriority" != "" ]; then
  279. _Print "> Shifting '$ssid' priority to $humanPriority" "output"
  280. else
  281. _Print "> Shifting '$ssid' priority" "output"
  282. fi
  283. # perform the reorder
  284. uci reorder wireless.\@wifi-config[$index]=$priority
  285. # commit the changes
  286. UciCommitWireless
  287. fi
  288. }
  289. # output a JSON object of specified network
  290. # $1 - network id
  291. # $2 - ssid
  292. UciJsonOutputWifiNetworkInfo () {
  293. local id=$1
  294. local ssid=$2
  295. local connectedNetwork=""
  296. local staDisabled="1"
  297. # find the currently connected network
  298. staDisabled=$(UciGetWifiIfaceDisabled "sta")
  299. if [ "$staDisabled" == "0" ]; then
  300. connectedNetwork=$(UciGetWifiIfaceOption "sta" "ssid")
  301. fi
  302. # check that this wifi-config exists
  303. local config=$(UciCheckWifiConfigIndex $id)
  304. if [ "$config" != "" ]; then
  305. # find the data
  306. local ssidRd=$(uci -q get wireless.\@wifi-config[$id].ssid)
  307. local modeRd=$(uci -q get wireless.\@wifi-config[$id].mode)
  308. local encrRd=$(uci -q get wireless.\@wifi-config[$id].encryption)
  309. local authRd=$(uci -q get wireless.\@wifi-config[$id].authentication)
  310. local passwordRd=$(uci -q get wireless.\@wifi-config[$id].key)
  311. local bssidRd=$(uci -q get wireless.\@wifi-config[$id].bssid)
  312. # check if this network is currently connected
  313. if [ "$connectedNetwork" == "$ssidRd" ]; then
  314. json_add_boolean "enabled" 1
  315. else
  316. json_add_boolean "enabled" 0
  317. fi
  318. if [ "$encrRd" == "wep" ]; then
  319. passwordRd=$(uci -q get wireless.\@wifi-config[$id].key$passwordRd)
  320. fi
  321. # create and populate object for this network
  322. _Print "$ssidRd" "ssid"
  323. _Print "$encrRd" "encryption"
  324. _Print "$passwordRd" "password"
  325. if [ "$bssidRd" != "" ]; then
  326. _Print "$bssidRd" "bssid"
  327. fi
  328. else
  329. $bError=1
  330. fi
  331. }
  332. # output a JSON list of all configured networks
  333. UciJsonOutputAllNetworks () {
  334. local count=0
  335. # create the results array
  336. json_add_array results
  337. # find the first network
  338. local config=$(UciCheckWifiConfigIndex $count)
  339. # loop through all configured networks
  340. while [ "$config" == "wifi-config" ]
  341. do
  342. # create an object for this network
  343. json_add_object
  344. # populate the object
  345. UciJsonOutputWifiNetworkInfo $count
  346. # close the object
  347. json_close_object
  348. # continue the loop
  349. count=$(($count + 1))
  350. config=$(UciCheckWifiConfigIndex $count)
  351. done
  352. # finish the array
  353. json_close_array
  354. # print the json
  355. if [ $bJson == 0 ]; then
  356. json_dump | sed 's/,/,\n /g' | sed 's/{ "/{\n\n "/g' | sed 's/}/\n\}/g' | sed 's/\[/\[\n/g' | sed 's/\]/\n\]/g'
  357. fi
  358. }
  359. # output a JSON object of AP network
  360. UciJsonOutputWifiApInfo () {
  361. # create the results array
  362. json_add_array results
  363. # create an object for the AP network
  364. json_add_object
  365. ## populate with AP info
  366. # find the data
  367. local ssidRd=$(uci -q get wireless.ap.ssid)
  368. local modeRd=$(uci -q get wireless.ap.mode)
  369. local encrRd=$(uci -q get wireless.ap.encryption)
  370. local authRd=$(uci -q get wireless.ap.authentication)
  371. local passwordRd=$(uci -q get wireless.ap.key)
  372. local bDisabledRd=$(uci -q get wireless.ap.disabled)
  373. local ipAddr=$(uci -q get network.wlan.ipaddr)
  374. if [ "$bDisabledRd" == "0" ]; then
  375. json_add_boolean "enabled" 1
  376. else
  377. json_add_boolean "enabled" 0
  378. fi
  379. if [ "$encrRd" == "wep" ]; then
  380. passwordRd=$(uci -q get wireless.ap.key$passwordRd)
  381. fi
  382. # create and populate object for this network
  383. _Print "$ssidRd" "ssid"
  384. _Print "$encrRd" "encryption"
  385. _Print "$passwordRd" "password"
  386. _Print "$ipAddr" "ip"
  387. # close the object
  388. json_close_object
  389. # close the array
  390. json_close_array
  391. # print the json
  392. if [ $bJson == 0 ]; then
  393. json_dump | sed 's/,/,\n /g' | sed 's/{ "/{\n\n "/g' | sed 's/}/\n\}/g' | sed 's/\[/\[\n/g' | sed 's/\]/\n\]/g'
  394. fi
  395. }
  396. ### wifi-iface ###
  397. # check wifi-iface interface input
  398. # $1 - 'ap' or 'sta'
  399. UciCheckWifiIfaceInput () {
  400. local iface=$1
  401. local bIfaceError=0
  402. # check if iface is an allowed input
  403. if [ "$iface" != "ap" ] &&
  404. [ "$iface" != "sta" ];
  405. then
  406. bIfaceError=1
  407. fi
  408. echo $bIfaceError
  409. }
  410. # enable or disable a wifi iface
  411. # $1 - 'ap' or 'sta' (assuming that this has been checked)
  412. # $2 - enable (1) or disable (0)
  413. UciSetWifiIfaceEnable () {
  414. local iface=$1
  415. local bEnable=$2
  416. # wifi-iface needs 'disabled' parameter - invert the enable
  417. local bDisabled=$((!$bEnable))
  418. # set the enable/disable
  419. uci set wireless.$iface.disabled="$bDisabled"
  420. # commit the changes
  421. UciCommitWireless
  422. # TODO: ensure the above is required
  423. }
  424. # set wifi-device mode
  425. #
  426. UciSetWifiDeviceMode () {
  427. local mode="$1"
  428. # set the device mode
  429. uci set wireless.radio0.device_mode="$mode"
  430. # commit the changes
  431. UciCommitWireless
  432. }
  433. # populate a wireless.wifi-config section
  434. # input:
  435. # $1 - iface
  436. # $2 - ssid
  437. # $3 - encryption
  438. # $4 - password
  439. UciPopulateWifiIfaceSection () {
  440. local iface=$1
  441. local ssid=$2
  442. local encryption=$3
  443. local password=$4
  444. # check if iface is an allowed input
  445. local bInvalidInput=$(UciCheckWifiIfaceInput $iface)
  446. if [ $bInvalidInput -eq 0 ]; then
  447. # set the network key based on the encryption
  448. case "$encryption" in
  449. psk2|psk)
  450. uci set wireless.$iface.key="$password"
  451. ;;
  452. wep)
  453. uci set wireless.$iface.key=1
  454. uci set wireless.$iface.key1="$password"
  455. ;;
  456. none|*)
  457. # add a 'NONE' value as a placeholder for open networks
  458. # the config parser in wifimanager expects non-empty values for existing configurations
  459. uci set wireless.$iface.key='none'
  460. ;;
  461. esac
  462. # set the ssid and encryption type
  463. uci set wireless.$iface.ssid="$ssid"
  464. uci set wireless.$iface.encryption="$encrypt"
  465. # commit the changes
  466. UciCommitWireless
  467. fi
  468. }
  469. # from a wireless.wifi-iface section, get the value of an option
  470. # input:
  471. # $1 - iface
  472. # $2 - option
  473. # output:
  474. # if section found: <option value>
  475. # no section found: ""
  476. UciGetWifiIfaceOption () {
  477. local iface=$1
  478. local option="$2"
  479. local value=""
  480. # check if iface is an allowed input
  481. local bInvalidInput=$(UciCheckWifiIfaceInput $iface)
  482. if [ $bInvalidInput -eq 0 ]; then
  483. value=$(uci -q get wireless.$iface.$option)
  484. fi
  485. echo "$value"
  486. }
  487. # get a wireless.wifi-iface section's 'disabled' option's value
  488. # input:
  489. # $1 - iface
  490. # output:
  491. # 0 or 1
  492. UciGetWifiIfaceDisabled () {
  493. local iface=$1
  494. local disabled="1"
  495. disabled=$(UciGetWifiIfaceOption "$iface" "disabled")
  496. echo "$disabled"
  497. }
  498. ########################################
  499. ### Wifi Network Modification Functions
  500. ########################################
  501. # Ensure network key meets length requirements based on the encryption type
  502. # input:
  503. # $1 - encryption
  504. # $2 - password
  505. # output:
  506. # if key is ok: 0
  507. # if key is not ok: 1
  508. _CheckPasswordLength () {
  509. local encryption=$1
  510. local password=$2
  511. local bKeyError=0
  512. keyLength=${#password}
  513. # perform the check
  514. case "$encryption" in
  515. psk2|psk)
  516. if [ "$keyLength" -lt 8 ] ||
  517. [ "$keyLength" -gt 64 ]; then
  518. _Print "> ERROR: Password length does not match encryption type. WPA2 passwords must be between 8 and 64 characters." "error"
  519. bKeyError=1
  520. exit
  521. fi
  522. ;;
  523. wep)
  524. if [ "$keyLength" -lt 5 ]; then
  525. _Print "> ERROR: Password length does not match encryption type. Please enter a valid password." "error"
  526. bKeyError=1
  527. exit
  528. fi
  529. ;;
  530. none|*)
  531. # nothing
  532. bKeyError=0
  533. ;;
  534. esac
  535. echo $bKeyError
  536. }
  537. # Add a uci section for a wifi network
  538. # $1 - interface number #TODO: likely don't need this LAZAR
  539. # $2 - ssid
  540. # $3 - encryption type
  541. # $4 - password
  542. # $5 - bssid (optional)
  543. AddWifiNetwork () {
  544. local id="$1"
  545. local ssid="$2"
  546. local encrypt="$3"
  547. local password="$4"
  548. local bssid="$5"
  549. local bNew=0
  550. # check the network password
  551. bError=$(_CheckPasswordLength $encrypt "$password")
  552. if [ $bError == 0 ]; then
  553. # add new wifi-config section if required
  554. local config=$(UciCheckWifiConfigIndex $id)
  555. if [ "$config" != "wifi-config" ]; then
  556. UciAddWifiConfigSection
  557. bNew=1
  558. fi
  559. # populate the wifi-config section
  560. UciPopulateWifiConfigSection $id "$ssid" "$encrypt" "$password" "$bssid"
  561. fi
  562. }
  563. # Edit a uci section for a wifi network
  564. # $1 - interface number #TODO: likely don't need this LAZAR
  565. # $2 - ssid
  566. # $3 - encryption type
  567. # $4 - password
  568. # $5 - bssid (optional)
  569. EditWifiNetwork () {
  570. local id=$1
  571. local ssid=$2
  572. local encrypt=$3
  573. local password=$4
  574. local bssid=$5
  575. local bNew=0
  576. # check the network password
  577. bError=$(_CheckPasswordLength $encrypt "$password")
  578. # TODO: LAZAR: add a search based on the ssid
  579. if [ $bError == 0 ]; then
  580. # add new wifi-config section if required
  581. local config=$(UciCheckWifiConfigIndex $id)
  582. if [ "$config" != "wifi-config" ]; then
  583. _Print "> ERROR: Cannot modify network, it does not exist in the database." "error"
  584. else
  585. # populate the wifi-config section
  586. UciPopulateWifiConfigSection $id "$ssid" "$encrypt" "$password" "$bssid"
  587. fi
  588. fi
  589. }
  590. # Enable or Disable a wifi interface
  591. # $1 - 'ap' or 'sta'
  592. # $2 - enable (1) or disable (0)
  593. SetWifiIfaceEnable () {
  594. local iface=$1
  595. local bEnable=$2
  596. # check if iface is an allowed input
  597. local bInvalidInput=$(UciCheckWifiIfaceInput $iface)
  598. if [ $bInvalidInput -eq 0 ]; then
  599. UciSetWifiIfaceEnable $iface $bEnable
  600. fi
  601. }
  602. # Set the device mode
  603. # $1 - 'ap', 'sta', or 'apsta'
  604. SetWifiDeviceMode () {
  605. local mode="$1"
  606. # check if valid input
  607. if [ "$mode" == "ap" ] ||
  608. [ "$mode" == "sta" ] ||
  609. [ "$mode" == "apsta" ];
  610. then
  611. UciSetWifiDeviceMode "$mode"
  612. fi
  613. }
  614. # Remove a wifi-config section that defines a wifi network
  615. # $1 - interface number #TODO: likely don't need this LAZAR
  616. # $2 - ssid
  617. RemoveWifiNetwork () {
  618. local id=$1
  619. local ssid=$2
  620. # check the argument
  621. if [ $id -ge 0 ]; then
  622. # ensure that iface exists
  623. local config=$(UciCheckWifiConfigIndex $id)
  624. if [ "$config" == "wifi-config" ]; then
  625. _Print "> Removing '$ssid' network from database" "output"
  626. UciDeleteWifiConfigSection $id "$ssid"
  627. fi
  628. fi
  629. }
  630. # change the priority of a network (by changing the uci wireless section order)
  631. # $1 - network section id
  632. # $2 - network ssid
  633. # $3 - argument for moving the network
  634. SetWifiNetworkPriority () {
  635. local id=$1
  636. local ssid=$2
  637. local argument=$3
  638. #### wireless config file breakdown:
  639. ## SECTION order
  640. ## wireless.radio0 0
  641. ## wireless.ap 1
  642. ## wireless.sta 2
  643. ## wireless.@wifi-config[0] 3 - highest priority for a network
  644. ## wireless.@wifi-config[n] n+3 - lowest priority for a network
  645. # define the highest priority
  646. local topPriority=3
  647. # find the lowest priority
  648. local bottomPriority=$(($(_FindNumNetworks) - 1 + $topPriority))
  649. # find the network's current priority
  650. local currPriority=$(($id + $topPriority))
  651. # find the shift in priority
  652. if [ "$argument" == "up" ]; then
  653. desiredPriority=$(($currPriority - 1))
  654. elif [ "$argument" == "down" ]; then
  655. desiredPriority=$(($currPriority + 1))
  656. elif [ "$argument" == "top" ]; then
  657. desiredPriority=$topPriority
  658. fi
  659. ## find the new human-readable priority
  660. local hmnPriority=$(($desiredPriority - $topPriority))
  661. # check that shift is valid
  662. if [ $desiredPriority -lt $topPriority ] ||
  663. [ $desiredPriority -gt $bottomPriority ] ||
  664. [ $currPriority -lt $topPriority ];
  665. then
  666. _Print "> ERROR: Invalid priority shift requested" "error"
  667. _SetError
  668. else
  669. UciReorderWifiConfigSection $id "$ssid" $desiredPriority $hmnPriority
  670. fi
  671. }
  672. # clear all configured wifi networks
  673. ClearAllWifiNetworks () {
  674. _Print "Clearing all stored network entries." "info"
  675. local count=0
  676. # find the first network
  677. local config=$(UciCheckWifiConfigIndex $count)
  678. # loop through all configured networks
  679. while [ "$config" == "wifi-config" ]
  680. do
  681. # remove the network
  682. UciDeleteWifiConfigSection $count
  683. # grab the next configured network
  684. # don't increment count, loop will exit when there are no more networks left
  685. config=$(UciCheckWifiConfigIndex $count)
  686. done
  687. # reset the STA paramters and disable it
  688. UciPopulateWifiIfaceSection "sta" "yourssid" "psk2" "yourpassword"
  689. UciSetWifiIfaceEnable "sta" 0
  690. _Print "Restarting WiFi driver and disconnecting from current network."
  691. _Print "This will end all wireless ssh sessions!"
  692. # reset the wifi adapter with the new settings
  693. wifi
  694. }
  695. # reset all wireless and network settings to that of factory
  696. ResetNetworkSettings () {
  697. _Print "Reseting all wireless network settings to factory state." "info"
  698. cp /rom/etc/config/wireless /etc/config/wireless
  699. cp /rom/etc/config/network /etc/config/network
  700. # find the hostname
  701. local name=$(uci -q get system.\@system[0].hostname)
  702. uci set wireless.ap.ssid="$name"
  703. UciCommitWireless
  704. _Print "Restarting WiFi driver and disconnecting from current network."
  705. _Print "This will end all wireless ssh sessions!"
  706. # reset the wifi adapter with the new settings
  707. wifi
  708. }
  709. # collect information about the wifi and network configuration
  710. #
  711. CollectDebugInfo () {
  712. local dbgFile="/tmp/wifidebug.log"
  713. echo "================ WIFI DEBUG LOG ================" > $dbgFile
  714. echo "== `date` ==" >> $dbgFile
  715. echo "" >> $dbgFile
  716. CollectCommandOutput "ifconfig" "$dbgFile"
  717. CollectCommandOutput "iwconfig" "$dbgFile"
  718. CollectCommandOutput "uci show wireless" "$dbgFile"
  719. if [ $bVerbose -eq 1 ]; then
  720. CollectCommandOutput "iwpriv ra0 get_site_survey" "$dbgFile"
  721. fi
  722. _Print "Collected WiFi and network debug information in $dbgFile file"
  723. }
  724. # append output from a specific command into a file
  725. # arg1 - command to run
  726. # arg2 - output file
  727. CollectCommandOutput () {
  728. local cmd="$1"
  729. local outfile="$2"
  730. local tmp=$(mktemp)
  731. echo "================ $cmd ================" >> $outfile
  732. eval $cmd &> $tmp
  733. cat $tmp >> $outfile
  734. echo "" >> $outfile
  735. rm -rf $tmp
  736. }
  737. ########################################
  738. ### User Input Functions
  739. ########################################
  740. # Normalize the authentication input
  741. # modifies the global auth variable
  742. _NormalizeEncryptInput () {
  743. case "$encrypt" in
  744. WPA1PSKWPA2PSK|WPA2PSK|wpa2|psk2|WPA2|PSK2|wpa-mixed)
  745. encrypt="psk2"
  746. ;;
  747. WPA1PSK|WPAPSK|wpa|psk|WPA|PSK)
  748. encrypt="psk"
  749. ;;
  750. wep|WEP)
  751. encrypt="wep"
  752. ;;
  753. none|*)
  754. encrypt="none"
  755. ;;
  756. esac
  757. }
  758. # read WPA settings from json data
  759. # TODO: find out if this is still needed
  760. _UserInputJsonReadNetworkAuthPsk () {
  761. local bFoundType1=0
  762. local bFoundType2=0
  763. local type=""
  764. # check the wpa object
  765. json_get_type type wpa
  766. # read the wpa object
  767. if [ "$type" == "array" ]
  768. then
  769. # select the wpa object
  770. json_select wpa
  771. # find all the values
  772. json_get_values values
  773. # read all elements
  774. for value in $values
  775. do
  776. # parse value
  777. if [ $value == 1 ]
  778. then
  779. bFoundType1=1
  780. elif [ $value == 2 ]
  781. then
  782. bFoundType2=1
  783. fi
  784. done
  785. # return to encryption object
  786. json_select ..
  787. # select the authentication type based on the wpa values that were found
  788. if [ $bFoundType1 == 1 ]
  789. then
  790. auth="psk"
  791. fi
  792. if [ $bFoundType2 == 1 ]
  793. then
  794. # wpa2 overrides wpa
  795. auth="psk2"
  796. fi
  797. fi
  798. }
  799. # read network encryption type from json data from iwinfo scan
  800. _UserInputJsonReadNetworkAuth () {
  801. # select the encryption object
  802. local index=$1
  803. json_load "$RESP"
  804. json_get_type type results
  805. json_select results
  806. json_get_keys keys
  807. # read the wifi scan object object
  808. if [ "$type" == "array" ] &&
  809. [ "$keys" != "" ];
  810. then
  811. # select the specific wifi network
  812. json_select $index
  813. # read the authentication object type
  814. # json_get_var auth_type encryption # old backwards mapping
  815. json_get_var encrypt encryption
  816. else
  817. # results object is not an array and there are no keys
  818. # OLD COMMENT: no encryption: open network
  819. encrypt="none"
  820. fi
  821. }
  822. # manually read network authentication from user
  823. _UserInputReadNetworkAuth () {
  824. # present user with authentication options
  825. echo ""
  826. echo "Select network authentication type:"
  827. echo "1) WPA2"
  828. echo "2) WPA"
  829. echo "3) WEP"
  830. echo "4) None"
  831. echo ""
  832. echo -n "Selection: "
  833. read input
  834. # assume default encryption type for all authentication modes
  835. case "$input" in
  836. 1)
  837. encrypt="psk2"
  838. ;;
  839. 2)
  840. encrypt="psk"
  841. ;;
  842. 3)
  843. encrypt="wep"
  844. ;;
  845. 4) # no encryption, no key
  846. encrypt="none"
  847. key="none"
  848. ;;
  849. esac
  850. }
  851. # scan wifi networks, display for user, allow them to pick one
  852. # when function completes successfully, the following global variables will be populated:
  853. # * ssid
  854. # * encrypt
  855. _UserInputScanWifi () {
  856. # run the scan command and get the response
  857. RESP=$(ubus call onion wifi-scan '{"device":"ra0"}')
  858. # read the json response
  859. json_load "$RESP"
  860. # check that array is returned
  861. json_get_type type results
  862. # find all possible keys
  863. json_select results
  864. json_get_keys keys
  865. if [ "$type" == "array" ] &&
  866. [ "$keys" != "" ];
  867. then
  868. echo ""
  869. echo "Select Wifi network:"
  870. # loop through the keys
  871. for key in $keys
  872. do
  873. # select the array element
  874. json_select $key
  875. # find the ssid
  876. json_get_var cur_ssid ssid
  877. if [ "$cur_ssid" == "" ]
  878. then
  879. cur_ssid="[hidden]"
  880. fi
  881. echo "$key) $cur_ssid"
  882. # return to array top
  883. json_select ..
  884. done
  885. # read the input
  886. echo ""
  887. echo -n "Selection: "
  888. read input;
  889. # get the selected ssid
  890. json_select $input
  891. json_get_var ssid ssid
  892. if [ "$ssid" == "" ]; then
  893. _Print "> ERROR: specified ssid not in the database" "error"
  894. bError=1
  895. exit
  896. fi
  897. echo "Network: $ssid"
  898. # detect the authentication type
  899. _UserInputJsonReadNetworkAuth "$input"
  900. #echo "Authentication type: $auth"
  901. # print encryption type
  902. echo "Encryption type: $encrypt"
  903. else
  904. wifi
  905. bScanFailed=1
  906. echo "> ERROR: Scan failed, try again"
  907. fi
  908. }
  909. # main function to read user input
  910. # when function completes successfully, the following global variables will be populated:
  911. # * ssid
  912. # * encrypt
  913. # * password
  914. _UserInputMain () {
  915. bScanFailed=0
  916. echo "Onion Omega Wifi Setup"
  917. echo ""
  918. echo "Select from the following:"
  919. echo "1) Scan for Wifi networks"
  920. echo "2) Type network info"
  921. echo "q) Exit"
  922. echo ""
  923. echo -n "Selection: "
  924. read input
  925. # choice between scanning
  926. if [ $input == 1 ]
  927. then
  928. # perform the scan and select network
  929. echo "Scanning for wifi networks..."
  930. _UserInputScanWifi
  931. elif [ $input == 2 ]
  932. then
  933. # manually read the network name
  934. echo -n "Enter network name: "
  935. read ssid;
  936. # read the authentication type
  937. _UserInputReadNetworkAuth
  938. else
  939. echo "Bye!"
  940. exit
  941. fi
  942. # read the network password
  943. if [ "$encrypt" != "none" ] &&
  944. [ $bScanFailed == 0 ];
  945. then
  946. echo -n "Enter password: "
  947. read password
  948. fi
  949. echo ""
  950. }
  951. ########################################
  952. ### Parse Arguments
  953. ########################################
  954. # parse arguments
  955. while [ "$1" != "" ]
  956. do
  957. case "$1" in
  958. # options
  959. -v|--v|-verbose|verbose)
  960. bVerbose=1
  961. shift
  962. ;;
  963. -j|--j|-json|--json|json)
  964. bJson=1
  965. shift
  966. ;;
  967. -ap|--ap|accesspoint|-accesspoint|--accesspoint)
  968. bApNetwork=1
  969. shift
  970. ;;
  971. -b64|--b64|-base64|--base64|base64)
  972. bBase64=1
  973. shift
  974. ;;
  975. # commands
  976. -add|add)
  977. bCmd=1
  978. bCmdAdd=1
  979. shift
  980. ;;
  981. -edit|edit)
  982. bCmd=1
  983. bCmdEdit=1
  984. shift
  985. ;;
  986. -disable|disable)
  987. bCmd=1
  988. bCmdDisable=1
  989. shift
  990. ;;
  991. -enable|enable)
  992. bCmd=1
  993. bCmdEnable=1
  994. shift
  995. ;;
  996. -remove|remove)
  997. bCmd=1
  998. bCmdRemove=1
  999. shift
  1000. ;;
  1001. -priority|priority)
  1002. bCmd=1
  1003. bCmdPriority=1
  1004. shift
  1005. ;;
  1006. -list|list)
  1007. bCmd=1
  1008. bCmdList=1
  1009. bJson=1
  1010. shift
  1011. ;;
  1012. -info|info)
  1013. bCmd=1
  1014. bCmdInfo=1
  1015. bJson=1
  1016. shift
  1017. ;;
  1018. -clear|clear)
  1019. bCmd=1
  1020. bCmdClear=1
  1021. shift
  1022. ;;
  1023. -reset|reset)
  1024. bCmd=1
  1025. bCmdReset=1
  1026. shift
  1027. ;;
  1028. -debug|debug)
  1029. bCmd=1
  1030. bCmdDebug=1
  1031. shift
  1032. ;;
  1033. -h|--h|help|-help|--help)
  1034. usage
  1035. exit
  1036. ;;
  1037. # parameters
  1038. -ssid|ssid)
  1039. shift
  1040. ssid="$1"
  1041. shift
  1042. ;;
  1043. -password|password)
  1044. shift
  1045. password="$1"
  1046. shift
  1047. ;;
  1048. -encr|encr)
  1049. shift
  1050. encrypt="$1"
  1051. shift
  1052. ;;
  1053. -move|move)
  1054. shift
  1055. priorityMove=$1
  1056. shift
  1057. ;;
  1058. -bssid|bssid)
  1059. shift
  1060. bssid="$1"
  1061. shift
  1062. ;;
  1063. *)
  1064. echo "ERROR: Invalid Argument: $1"
  1065. usage
  1066. exit
  1067. ;;
  1068. esac
  1069. done
  1070. ########################################
  1071. ########################################
  1072. ### Main Program
  1073. ########################################
  1074. ## user input ##
  1075. if [ $bCmd == 0 ]; then
  1076. # grab input from the user
  1077. _UserInputMain
  1078. # now globals ssid, encrypt, and password are populated
  1079. # enable the add command if user input was successful (ssid and auth are defined)
  1080. if [ "$ssid" != "" ] &&
  1081. [ "$encrypt" != "" ];
  1082. then
  1083. bCmdAdd=1
  1084. fi
  1085. fi
  1086. ## json init
  1087. _Init
  1088. # base64 decode of parameter arguments
  1089. if [ $bBase64 == 1 ]; then
  1090. ssid=$(_base64Decode "$ssid")
  1091. password=$(_base64Decode "$password")
  1092. encrypt=$(_base64Decode "$encrypt")
  1093. priorityMove=$(_base64Decode "$priorityMove")
  1094. bssid=$(_base64Decode "$bssid")
  1095. fi
  1096. ## parameter processing
  1097. if [ $bApNetwork == 1 ]; then
  1098. networkType="ap"
  1099. id="ap"
  1100. else
  1101. networkType="sta"
  1102. # check if network already exists in configuration
  1103. id=$(_FindNetworkBySsid "$ssid")
  1104. fi
  1105. if [ "$encrypt" != "" ]; then
  1106. _NormalizeEncryptInput
  1107. fi
  1108. ## commands
  1109. if [ $bCmdAdd == 1 ]; then
  1110. # if it doesn't already exist, add a new section
  1111. if [ $id == -1 ]; then
  1112. id=$(_FindNumNetworks)
  1113. fi
  1114. # add the network entry
  1115. AddWifiNetwork $id "$ssid" "$encrypt" "$password" "$bssid"
  1116. # enable the sta interface
  1117. UciSetWifiIfaceEnable "sta" 1
  1118. # set device mode to enable sta
  1119. SetWifiDeviceMode "apsta"
  1120. elif [ $bCmdEdit == 1 ]; then
  1121. if [ $bApNetwork == 1 ]; then
  1122. # edit the ap network
  1123. UciPopulateWifiIfaceSection "$networkType" "$ssid" "$encrypt" "$password"
  1124. bCmdAdd=1 # ensure wifi gets called to make sure changes get applied
  1125. else
  1126. # edit the network entry
  1127. EditWifiNetwork $id "$ssid" "$encrypt" "$password" "$bssid"
  1128. fi
  1129. elif [ $bCmdDisable == 1 ]; then
  1130. # disable the network
  1131. SetWifiIfaceEnable $networkType 0
  1132. elif [ $bCmdEnable == 1 ]; then
  1133. # enable the network
  1134. SetWifiIfaceEnable $networkType 1
  1135. elif [ $bCmdRemove == 1 ]; then
  1136. # only remove existing networks
  1137. if [ $id != -1 ]; then
  1138. RemoveWifiNetwork $id "$ssid"
  1139. fi
  1140. elif [ $bCmdPriority == 1 ]; then
  1141. # only move existing network
  1142. if [ $id != -1 ]; then
  1143. SetWifiNetworkPriority $id "$ssid" "$priorityMove"
  1144. fi
  1145. elif [ $bCmdList == 1 ]; then
  1146. if [ $bApNetwork == 1 ]; then
  1147. UciJsonOutputWifiApInfo
  1148. else
  1149. UciJsonOutputAllNetworks
  1150. fi
  1151. # remove error message
  1152. id=0
  1153. elif [ $bCmdInfo == 1 ]; then
  1154. UciJsonOutputWifiNetworkInfo $id "$ssid"
  1155. # remove error message (will be printed in json)
  1156. #id=0 #TODO: confirm this is not needed
  1157. elif [ $bCmdClear == 1 ]; then
  1158. ClearAllWifiNetworks
  1159. # remove error message
  1160. id=0
  1161. elif [ $bCmdReset == 1 ]; then
  1162. ResetNetworkSettings
  1163. # remove error message
  1164. id=0
  1165. elif [ $bCmdDebug == 1 ]; then
  1166. CollectDebugInfo
  1167. # remove error message
  1168. id=0
  1169. fi # command if else statement
  1170. # check that network was found
  1171. if [ $id == -1 ]; then
  1172. _Print "> ERROR: specified ssid not in the database" "error"
  1173. _SetError
  1174. fi
  1175. if [ $bError == 0 ]; then
  1176. if [ $bCmdAdd == 1 ] ||
  1177. [ $bCmdDisable == 1 ] ||
  1178. [ $bCmdEnable == 1 ] ||
  1179. [ $bCmdRemove == 1 ] ||
  1180. # bCmdClear and bCmdReset are not considered because all wifi options will be reset
  1181. # bCmdDebug is not considered since it just gathers data
  1182. [ $bCmdPriority == 1 ];
  1183. then
  1184. _Print "> Restarting wifimanager for changes to take effect" "status"
  1185. wifi
  1186. fi
  1187. fi
  1188. ## json finish
  1189. _Close