Friday, July 18, 2014

Setting up a MediaTek Ralink WiFi Adapter in Raspbmc 3.12.21-Raspberry PI [mt7601]

ADVERTISEMENT
Pi with 802.11n dongle
One of the best use of raspberry pi is a media server based on xbmc (Raspbmc from Sam) or OpenElec. It is even more cool to keep it wireless with a wifi adapter. I got hold of a small WiFi adapter (see figure) USB Wifi Micro Adapter Dongle 802.11n Plug and Play or Leoxsys LEO-NANO150N USB Adapter. The only marking on the adapter was 802.11n and it failed to work with the Raspbmc/raspberry pi as there are no drivers included in the distro at this moment. A Google search took me to the mediatek website and got the source code for drivers.
Mediatec Wifi dongle on Raspbmc

Drivers in Linux system are either integrated in to the kernel or are loaded later in the form of kernel modules. So the solution was to compile the driver source and insert the modules. But it is important that the module should be compile specifically for the kernel which is running/ you need to update the kernel. As raspbmc is an optimized version of the kernel to give you the best out of the raspberry pi, we need to compile the module specifically for the kernel.


Summarizing the steps which worked for me

1) Check if the USB adapter is recognized

 [email protected]:~$ sudo lsusb  

Bus 001 Device 004: ID 148f:7601 Ralink Technology, Corp.

ID 148f:7601 indicate that the device is there

2)


 [email protected]:~$ sudo lsmod | grep mt7601  

if you dont have the drivers this shoulnt show anything

3) Check the kernel version (The latest release at the time of this post was 3.12.21)

 [email protected]:~$ uname -r  

3.12.21

4) Now either  get the kernel source (for raspbmc) and driver source (for mediatec) and compile it or use the compiled binaries for mt7601 for 3.12.21, raspbmc

 wget https://www.dropbox.com/s/aelf5iebxpnuboz/release.tar.gz --no-check-certificate  
 tar xvf release.tar.gz  
 cd release/3_12_21/3.0.0.3  
 sudo cp *.ko /lib/modules/3.12.21/kernel/drivers/net/wireless/  
 sudo depmod -a  
 sudo modprobe mt7601Usta  
 sudo mkdir -p /etc/Wireless/RT2870STA  
 sudo cp RT2870STA.dat /etc/Wireless/RT2870STA  

and connect the wifi dongle and reboot.
Now the lights should appear on the adapter
Note: You can also use the version 3.0.0.4 of the driver. I also included the driver for kernel 3.12.24

5) after reboot 

 [email protected]:~$ ifconfig  

This should show an adpter r0 in the list of network devices, if everything went fine. Else do a

 sudo modprobe mt7601Usta  

and see if it spits up any errors also have a look at dmesg | tail -n 30

6) Rename ra0 to wlan0

 sudo nano /etc/udev/rules.d/70-persistent-net.rules  

and add the following to the bottom of the file

 ACTION=="add", SUBSYSTEM=="net", ATTR{type}=="1", KERNEL=="ra*", NAME="wlan0"  

7) Reboot and set the wireless network as usual from raspbmc settings


  [email protected]: sudo reboot  


Note: My old model of pi (with less RAM and black audio jack) may need a powered usb hub for stable operation! while the new Rev.B (violet audio jack) works without any hub

Note2: If still there is trouble setting up the network-manager ( Where scanning the SSID works well, but fails with setting it up)  there is a fix which works with dbus)

I used the python script (given below) to set the Network manager. Set the SSID and Passphrase and run the script to connect to the access point.

Save the script below into a file (ssh in to the pi and type nano setupwifi.py and paste the code below and execute it by typing  sudo python setupwifi.py. Remember to update the ssid and password in the script )

#!/usr/bin/python

# This script shows how to connect to a WPA protected WiFi network
# by communicating through D-Bus to NetworkManager 0.9.
#
# Reference URLs:
# http://projects.gnome.org/NetworkManager/developers/
# http://projects.gnome.org/NetworkManager/developers/settings-spec-08.html

import dbus
import time

SEEKED_SSID = "yourssidname"
SEEKED_PASSPHRASE = "supersecret"
INTERFACE_NAME = "wlan0"

if __name__ == "__main__":
    bus = dbus.SystemBus()
    # Obtain handles to manager objects.
    manager_bus_object = bus.get_object("org.freedesktop.NetworkManager",
                                        "/org/freedesktop/NetworkManager")
    manager = dbus.Interface(manager_bus_object,
                             "org.freedesktop.NetworkManager")
    manager_props = dbus.Interface(manager_bus_object,
                                   "org.freedesktop.DBus.Properties")

    # Enable Wireless. If Wireless is already enabled, this does nothing.
    was_wifi_enabled = manager_props.Get("org.freedesktop.NetworkManager",
                                         "WirelessEnabled")
    if not was_wifi_enabled:
        print "Enabling WiFi and sleeping for 10 seconds ..."
        manager_props.Set("org.freedesktop.NetworkManager", "WirelessEnabled",
                          True)
        # Give the WiFi adapter some time to scan for APs. This is absolutely
        # the wrong way to do it, and the program should listen for
        # AccessPointAdded() signals, but it will do.
        time.sleep(10)

    # Get path to the 'wlan0' device. If you're uncertain whether your WiFi
    # device is wlan0 or something else, you may utilize manager.GetDevices()
    # method to obtain a list of all devices, and then iterate over these
    # devices to check if DeviceType property equals NM_DEVICE_TYPE_WIFI (2).
    device_path = manager.GetDeviceByIpIface(INTERFACE_NAME)
    print "wlan path: ", device_path

    # Connect to the device's Wireless interface and obtain list of access
    # points.
    device = dbus.Interface(bus.get_object("org.freedesktop.NetworkManager",
                                           device_path),
                            "org.freedesktop.NetworkManager.Device.Wireless")
    accesspoints_paths_list = device.GetAccessPoints()

    # Identify our access point. We do this by comparing our desired SSID
    # to the SSID reported by the AP.
    our_ap_path = None
    for ap_path in accesspoints_paths_list:
        ap_props = dbus.Interface(
            bus.get_object("org.freedesktop.NetworkManager", ap_path),
            "org.freedesktop.DBus.Properties")
        ap_ssid = ap_props.Get("org.freedesktop.NetworkManager.AccessPoint",
                               "Ssid")
        # Returned SSID is a list of ASCII values. Let's convert it to a proper
        # string.
        str_ap_ssid = "".join(chr(i) for i in ap_ssid)
        print ap_path, ": SSID =", str_ap_ssid
        if str_ap_ssid == SEEKED_SSID:
            our_ap_path = ap_path
            break

    if not our_ap_path:
        print "AP not found :("
        exit(2)
    print "Our AP: ", our_ap_path

    # At this point we have all the data we need. Let's prepare our connection
    # parameters so that we can tell the NetworkManager what is the passphrase.
    connection_params = {
        "802-11-wireless": {
            "security": "802-11-wireless-security",
        },
        "802-11-wireless-security": {
            "key-mgmt": "wpa-psk",
            "psk": SEEKED_PASSPHRASE
        },
    }

    # Establish the connection.
    settings_path, connection_path = manager.AddAndActivateConnection(
        connection_params, device_path, our_ap_path)
    print "settings_path =", settings_path
    print "connection_path =", connection_path

    # Wait until connection is established. This may take a few seconds.
    NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
    print """Waiting for connection to reach """ \
          """NM_ACTIVE_CONNECTION_STATE_ACTIVATED state ..."""
    connection_props = dbus.Interface(
        bus.get_object("org.freedesktop.NetworkManager", connection_path),
        "org.freedesktop.DBus.Properties")
    state = 0
    while True:
        # Loop forever until desired state is detected.
        #
        # A timeout should be implemented here, otherwise the program will
        # get stuck if connection fails.
        #
        # IF PASSWORD IS BAD, NETWORK MANAGER WILL DISPLAY A QUERY DIALOG!
        # This is something that should be avoided, but I don't know how, yet.
        #
        # Also, if connection is disconnected at this point, the Get()
        # method will raise an org.freedesktop.DBus.Error.UnknownMethod
        # exception. This should also be anticipated.
        state = connection_props.Get(
            "org.freedesktop.NetworkManager.Connection.Active", "State")
        if state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
            break
        time.sleep(0.001)
    print "Connection established!"

    #
    # Connection is established. Do whatever is necessary.
    # ...
    #
    print "Sleeping for 5 seconds ..."
    time.sleep(5)
    print "Disconnecting ..."
    exit(0)
    # Clean up: disconnect and delete connection settings. If program crashes
    # before this point is reached then connection settings will be stored
    # forever.
    # Some pre-init cleanup feature should be devised to deal with this problem,
    # but this is an issue for another topic.
    manager.DeactivateConnection(connection_path)
    settings = dbus.Interface(
        bus.get_object("org.freedesktop.NetworkManager", settings_path),
        "org.freedesktop.NetworkManager.Settings.Connection")
    settings.Delete()

    # Disable Wireless (optional step)
    if not was_wifi_enabled:
        manager_props.Set("org.freedesktop.NetworkManager", "WirelessEnabled",
                          False)
    print "DONE!"
    exit(0)

end

28 comments:

  1. Fab thank you so much!! bout to throw the dongle out the window

    ReplyDelete
  2. Why was it so difficult to find this information?

    You are a life saver!! That python script as well, genius

    ReplyDelete
  3. Very good. I too was about to buy a new dongle. This worked flawlessly.

    Two points

    1) I had to run "sudo python setupwifi.py" otherwise I got an error "dbus dbus insufficient privileges"
    2) If you have a hidden SSID you have to unhide it for the python script to work

    ReplyDelete
  4. Somebody is able to provide a running mt7601 driver for the firmware v. 3.12.22+ 690 ? I'm getting stuck in that issue. Thanks in advance.
    Ciao
    Alberto

    ReplyDelete
  5. Ditto on the mt7601 driver none of the current compiled versions work with 3.12.27+

    ReplyDelete
  6. Thank you for your guide. Do you know how it works for static IP? The entry in /etc/network/interfaces does not work and the wlan0 adapter disappears from ifconfig.

    ReplyDelete
    Replies
    1. i need to check it again. If i remember correctly, raspbmc does not use a /etc/wpa.config (and /etc/network/interfaces) file to store the WLAN settings, but /home/pi/.xbmc/userdata/addon_data/script.raspbmc.settings/settings.xml

      A simple solution is to set a fixed ip on the router based on the mac address of the wifi card

      Delete
  7. got error exec format error with modprobe

    ReplyDelete
    Replies
    1. -make sure kernel version is same as in post (else may need recompilation)
      - try using modprobe --force mt7601Usta and test if it works
      good luck!

      Delete
    2. I succeed with compiling the driver following
      http://va3paw.com/2014/03/16/hsmm-mesh-on-raspberry-pi/#more-629
      my kernel is 3.12.31
      I then got the same error with modprobe.
      The reason was the modules.symvers on github was for 3.12.32
      I then went in Raspbmc settings - system configuration and activated 'Install and update kernel headers' - OK
      in /usr/src/linux-headers-3.12.31 , I found the correct version of the modules.symvers
      after putting this file in /usr/src/linux (and rebooting) I got my modprobe working :-)

      Delete
  8. Thx for this very useful article
    Unfortunately, my raspbmc kernel updated, and my wifi dongle isn't working anymore. Do you know how to compile a new driver ?

    ReplyDelete
  9. Hi, I try deseperatly to find a way to do the same thing for an ASUS USB-AC51. I got the linux driver from asus, but i am totallly lost to get the kernel (3.12.31) source and compile it like you did. The usb drive in the TAR file provided by asus is mt7610u. Someone can help?

    ReplyDelete
    Replies
    1. Hi,

      Here is an update driver for 3.12.31 kernel

      https://mega.co.nz/#!3tgjgaJB!SVQ262_PFY_ljdiIQYwLzBt1MQbfDM9mi23EBGCPyNk

      Delete
    2. Thanks. Worked perfectly with my latest Raspbmc!

      Delete
  10. Thanks -- the Python script did the trick for me :)

    ReplyDelete
  11. Hi ,

    I had an input support and wep support:

    http://pastebin.com/EPDAjQC3

    ReplyDelete
  12. Please provide instructions to recompile the driver. I have 2 problems...first I'm on 3.12.32 and second my device is slight variation it's 148f:760b (I have instructions elsewhere that say to just add one line in the source files which I've done to compensate for that).

    ReplyDelete
    Replies
    1. may be you can try this:
      http://askubuntu.com/questions/498680/ralink-148f760b-mt7601-driver-not-working

      Delete
    2. hi, thanks, those are the "instructions elsewhere" I was referring to...but it won't work for me, I can change the line mentioned in the topic but then the instructions refer to other instructions which are not clear and don't work for me ...possibly because of a kernel version conflict or something. Any clearer instructions please?

      Delete
    3. see my previous post
      http://blog.riyas.org/2014/07/setting-up-mediatek-ralink-wifi-adapter-Raspbmc3.12.21-Raspberry-PI-mt7601.html?showComment=1416386683096#c6416885433181993373

      Delete
    4. Thanks for trying to help me. I have also tried those instructions without success. I think I may also have the wrong module.symvers but I cannot 'Install and update kernel headers' as I'm actually using Raspbian rather than Raspbmc and can't find it. I don't know how to check and find the version I need. I'm pretty new to RPi and Linux in case you haven't guessed.

      Delete
    5. EDIT - actually don't worry, I've now finally got it working....using a combination of several techniques and the correct Module.symvers (I think). Hope I don't have to go through this though every time I do an update?

      Delete
  13. thanks, run on Raspberry Pi 3.12.35 see my post in german

    http://blog.wenzlaff.de/?p=4805

    ReplyDelete
  14. Hey..I am using raspbian on my raspberry pi. The WiFi adapter used by me is leoxsys NANO150N 802.11n . my kernel version is 3.12.35+ and I am thus unable to install the said drivers ax mentioned in the steps above. Could someone help me out here.

    ReplyDelete
  15. Could have a packaged version (*.arm.deb), using a script to compile the driver for kernel version. I would like to know do it. Could help everybody. Thanks by your help.

    ReplyDelete