#!/usr/bin/wish
#
# This tool allows connecting a mobile phone using bluetooth DUN
# (dial-up networking) as serial port for PPP communication.
#


# base application settings / standard configuration
set dev_hci "hci0"
set dev_rfcomm "rfcomm7"
set mobile "00:00:00:00:00:00"
set rfchannel "3"
global env
#if ($env(XDG_CONFIG)} { set HOME_CONFIG "$env(HOME)/$env(XDG_CONFIG)" } else
set HOME_CONFIG "$env(HOME)/.config"


# set window defaults
wm title . "Bluetooth mobile dialup (GPRS/UMTS) via DUN"
option add *tearOff 0

 # add menu entries
 . configure -menu [menu .menu -bd 1]
 .menu add cascade -menu [menu .menu.b -bd 1] -label "Bluetooth"
 .menu add cascade -menu [menu .menu.m -bd 1] -label "Mobile"
 .menu add cascade -menu [menu .menu.p -bd 1] -label "PPP dialup"
 .menu add cascade -menu [menu .menu.s -bd 1] -label "Setup/Fixes"
 .menu add cascade -menu [menu .menu.h -bd 1] -label "Help"
 .menu.b add cascade -label "use hardware adapter" -menu [menu .menu.hw -bd 0]
 .menu.b add command -label "Exit" -command {exit} -background gray
 .menu.m add command -label "Select device..." -command {select_device}
 .menu.m add command -label "Bind/Connect for DUN" -command {connect} -background yellow
 .menu.m add command -label "Release /dev/$dev_rfcomm" -command {exec gksudo rfcomm release $dev_rfcomm ; print "\nReleased.\n"}
 .menu.m add cascade -label "Other Services" -menu [menu .menu.sdp -bd 1]
 .menu.p add command -label "call NetworkManager" -command {exec nm-connection-editor&}
 .menu.p add command -label "call Gnome-PPP" -command {exec gnome-ppp&}
 .menu.p add command -label "call KPPP" -command {exec kppp&}
 .menu.p add command -label "call GPPPON" -command {exec gpppon&}
 .menu.p add cascade -label "WVDIAL" -menu [menu .menu.wvdial -bd 1] -background green
 .menu.p add cascade -label "pon" -menu [menu .menu.pon -bd 1]
 .menu.p add command -label "-" -command {print ""}
 .menu.p add command -label "disconnect PPP" -command "exec poff -a ; gksudo rfcomm release $dev_rfcomm" -background gray
 .menu.s add command -label "load kernel drivers" -command {print "\n-- modprobe bluetooth -- \n[exec gksudo modprobe bluetooth & gksudo modprobe btusb & gksudo modprobe l2cap & gksudo modprobe rfcomm]\n"}
 .menu.s add command -label "-" -command {print ""}
 .menu.s add command -label "list bluetooth devices in range" -command {print "\n-- hcitool scan -- \n[exec hcitool scan]\n"}
 .menu.s add command -label "scan for DUN devices" -command {print "\n-- sdptool search DUN -- \n[exec sdptool search DUN]\n"}
 .menu.s add command -label "get info on selected device" -command {print "\n-- hcitool info -- \n[exec gksudo hcitool info $mobile]\n"}
 .menu.s add command -label "hci0 capabilities" -command {print "\n-- hciconfig -a -- \n[exec hciconfig -a $dev_hci]\n"}
 .menu.s add command -label "-" -command {print ""}
 .menu.s add command -label "install bluetooth base" -command {print "\n-- bluetooth -- \n[exec apturl apt:bluetooth | pkgcon install bluetooth]\n"}
 .menu.s add command -label "install bluez-utils" -command {print "\n-- bluez-utils -- \n[exec apturl apt:bluez & apturl apt:bluez-gnome | pkcon install bluez-utils & pkgcon install bluez-gnome]\n"}
 .menu.s add command -label "install gnome-bluetooth" -command {print "\n-- bluetooth -- \n[exec apturl apt:gnome-bluetooth | pkgcon install gnome-bluetooth]\n"}
 .menu.s add command -label "install ppp" -command {exec apturl apt:ppp | pkgcon install ppp}
 .menu.s add command -label "install wvdial" -command {exec apturl apt:wvdial | pkgcon install wvdial}
 .menu.s add cascade -label "setup wvdial providers" -menu [menu .menu.wvsetup]
 .menu.s add command -label "-" -command {print ""}
 .menu.s add command -label "/etc/init.d/bluetooth restart" -command {print "\n[exec /etc/init.d/bluetooth restart]\n" }
 .menu.s add command -label "/etc/init.d/bluez-utils restart" -command {print "\n[exec /etc/init.d/bluez-utils restart]\n" }
 .menu.s add command -label "bluetooth applet" -command {exec bluetooth-applet &}
 .menu.s add command -label "-" -command {print ""}
 .menu.s add command -label "Bluetooth PIN utility fix" -command {exec gksudo -- passkey-agent --default /usr/bin/bluez-pin &}
 .menu.s add command -label "Bluetooth PIN config file" -command {print "\n\nEdit the 'passkey' line...\n" ; exec gksudo gedit /etc/bluetooth/hcid.conf &}
 .menu.s add command -label "Dialup privileges for user $env(USER)" -command "exec gksudo adduser $env(USER) dip"
 .menu.s add cascade -label "save current DUN connection" -menu [menu .menu.p.save -bd 1]
 # cu -l /dev/rfcomm0 -s 57600
 .menu.h add command -label "README" -command {readme}
 .menu.h add command -label "https://help.ubuntu.com/community/CategoryBluetooth" -command {exec firefox https://help.ubuntu.com/community/CategoryBluetooth &}
 .menu.h add command -label "http://wiki.ubuntuusers.de/Bluetooth/Mobile" -command {exec firefox http://wiki.ubuntuusers.de/Bluetooth/Mobile &}
 .menu.h add command -label "http://www.gentoo.org/doc/en/bluetooth-guide.xml" -command {exec firefox http://www.gentoo.org/doc/en/bluetooth-guide.xml &}
 .menu.h add command -label "http://www.spiration.co.uk/post/1307/" -command {exec firefox http://www.spiration.co.uk/post/1307/ &}
 .menu.h add command -label "about" -command {tk_dialog .new About "version 0.1 of bluedial.tcl, meant for establishing a DUN connection over bluetooth" "" 0 "ok"}
 .menu.hw add radiobutton -label "hci0 (default)" -variable dev_hci -value "hci0"
 .menu.hw add command -label "rescan devices" -command "hcitool_dev"
 .menu.p.save add cascade -label "as system setting into" -menu [menu .menu.p.save.sys]
 .menu.p.save.sys add cascade -label "/etc/bluetooth/rfcomm.conf" -menu [menu .menu.p.save.sys.really]
 .menu.p.save.sys.really add command -label "yes really, save" -command "save_rfcomm_conf"
 .menu.sdp add cascade -label "PAN" -menu [menu .menu.pan -bd 1]
# pand -s -r NAP -M
# pand --service NAP -b 11:11:11:11:11:11
#  pand --service NAP -Q
# ifconfig bnep0 10.0.0.1 netmask 255.255.255.0 up
 
 
 # add window elements 
 grid [label .devlabel -text "mobile phone:"] -column 0 -row 0
 grid [entry .devname -textvariable mobile -bd 1] -column 1 -row 0
 grid [button .scan -text "scan" -command "select_device" -background orange -bd 1] -column 2 -row 0
 grid [button .connect -text "connect" -command "connect" -background yellow -bd 1] -column 3 -row 0
 grid [button .dial -text "dial" -command "dial" -background green -bd 1] -column 4 -row 0
 grid [button .exit -text "exit" -command "exit" -bd 1] -column 5 -row 0
     
 # input/output window
 grid [text .t -background "dark blue" -foreground white -bd 1] -columnspan 6 -row 1
 .t tag configure bold -font "arial 14 bold" -relief raised


# scans for new devices
# 
proc hcitool_dev {} {
  print "\n-- hcitool dev --\n"
  set hci ""
  foreach e [exec hcitool dev] {
     if {$e == "Devices:"} {
        #
     } elseif {[string length $hci]} {
        print "\t$hci\t$e\n"
        .menu.hw add radiobutton -label "$hci ($e)" -variable dev_hci -value "$hci"
        set hci ""
     } else {
        set hci "$e"
     }
  }
}


#
#
proc select_device {} {
   global mobile
   print "\nscanning for devices...\n-- hcitool scan --\n"
   set devs [exec hcitool scan]
   print $devs
   # make select window out of result
   toplevel .selwin
   pack [button .selwin.x -text "$mobile" -command {destroy .selwin}] -in .selwin
   set n 0
   set m ""
   if {[regexp {(\w+:\w+:\w+:\w+:\w+:\w+)\s+(\w+)} $devs -> hw name]} {
      set n [expr $n + 1]   
      pack [button .selwin.btn -text "$name ($hw)" -command "set mobile $hw ; destroy .selwin" ] -in .selwin
   }
}


proc select_dun {} {
   print "\nscanning for devices...\n-- sdptool search DUN --\n"
   set duns [exec sdptool search DUN]
   
   #sudo /usr/bin/rfcomm bind 0 01:23:45:67:89:AB 4 

}


proc connect {} {
   global mobile
   global dev_rfcomm
   global rfchannel
   global .t
   if {$mobile != "00:00:00:00:00:00"} {
   
      # search channel
      print "\n-- sdptool search DUN $mobile --\n"
      set res [exec sdptool search DUN $mobile]
      #print $res
      if {[regexp {Channel:\s+([0-9]+)} $res -> rfchannel]} {
         print "found DUN profile on channel $rfchannel\n"
      } else {
         set rfchannel 3
         print "\nWARNING: using predefined channel $rfchannel\n"
      }
      
      # bind
      print "\n-- rfcomm bind $dev_rfcomm $mobile $rfchannel ... --\n";
      set res [exec gksudo rfcomm bind $dev_rfcomm $mobile $rfchannel]
      print $res
      print "\nMobile phone is now bound to "
      .t insert end "/dev/$dev_rfcomm" "bold"
      print "\nYou can start a PPP daemon on there now.\n"
      
      # save current device
      global HOME_CONFIG
      exec echo $mobile > $HOME_CONFIG/bluedial
      
   } else {
      print "\n\nYou must select a mobile first. Use the scan function.\n"
   }
}
  
  
proc print {output} {
   global .t
   .t insert end $output
   .t see end
}

proc save_rfcomm_conf {} {
   global dev_rfcomm
   global mobile
   global rfchannel
   exec gksudo -- sh -c "echo \"\n\n# written by bluedial.tcl:\n$dev_rfcomm {\n bind yes;\n device $mobile;\n channel $rfchannel;\n #comment ppp;\n}\n\" >> /etc/bluetooth/rfcomm.conf"
#  rfcomm7 {
#    bind yes;
#    device 00:00:00:00:00:00;
#    channel 3;
#  }
}

proc readme {} {
   global .t
   .t insert end {
 ---------------------------------------------------------------------------

 README
 ======

 The 'bluedial' tool is basically a wrapper around:
  - hcitool
  - sdptool
  - rfcomm
 and provides a few utility shortcuts to get a quick start with Bluetooth on
 Linux. Its primary purpose is setting dial up networking (PPP over DUN)
 with a mobile phone connection (GRPS, EDGE, UMTS). It can however be used
 for other functions. (Establishing a serial connection for Wammu/gnokii.)

}
}



 # some other startup code
 # 
 if {[file exists "/dev/$dev_rfcomm"]} { print "\nNOTE: Currently there is still a device connected on /dev/$dev_rfcomm.\nIf it's stale, use Mobile > Release first.\n" }

 # read defaults?
 if {[file exists $HOME_CONFIG/bluedial]} {
    set mobile [exec cat $HOME_CONFIG/bluedial]
 }
 
 # add wvdial entries
 if {[file exists /etc/wvdial.conf]} {
    set last 0
    foreach e [exec grep Dialer /etc/wvdial.conf] {
       if {$last} {
          set e [regsub {\]} $e ""]
          if {$e != "Default"} {
             .menu.wvdial add command -label "$e" -command "exec wvdial $e"
          }
          set last 0
       } else {
          set last 1
       }
    }
 }
 
 # add ppp entries
 if {[file exists /etc/ppp/peers/]} {
    foreach e [exec ls /etc/ppp/peers/] {
       .menu.pon add command -label "$e" -command "pon $e"
    }
 }
 
 