<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://www.raviprak.com/">
  <id>https://www.raviprak.com/</id>
  <title>Blog</title>
  <updated>2025-11-12T05:00:00Z</updated>
  <link rel="alternate" href="https://www.raviprak.com/" type="text/html"/>
  <link rel="self" href="https://www.raviprak.com/blog.xml" type="application/atom+xml"/>
  <author>
    <name>Ravi Prakash</name>
    <uri>https://www.raviprak.com</uri>
  </author>
  <entry>
    <id>tag:www.raviprak.com,2025-11-12:/misc/movingCAtoMD.html</id>
    <title type="html">Moving from Santa Clara, CA to Hyattsville, MD</title>
    <published>2025-11-12T05:00:00Z</published>
    <updated>2025-11-12T05:00:00Z</updated>
    <link rel="alternate" href="https://www.raviprak.com/misc/movingCAtoMD.html" type="text/html"/>
    <content type="html">&lt;h1 id="road-trip-from-santa-clara-ca-to-hyattsville-md"&gt;Road Trip from Santa Clara, CA to Hyattsville, MD&lt;/h1&gt;

&lt;h3 id="last-modified--12-november-2025"&gt;Last modified : 12 November, 2025&lt;/h3&gt;

&lt;p&gt;In this post, I’m sharing data from my cross-country drive from &lt;strong&gt;Santa Clara, California&lt;/strong&gt; to &lt;strong&gt;Hyattsville, Maryland&lt;/strong&gt;. Along the way, I stopped in &lt;strong&gt;West Lafayette, Indiana&lt;/strong&gt; to see family (a detour of 60 miles). I drove a 16 foot Penske truck and kept track of fuel stops, miles traveled, and costs throughout the journey.&lt;/p&gt;

&lt;p&gt;The truck was relatively lightly packed with lots of room. I could’ve should’ve could’ve used a smaller 10 foot truck, except for the fact that I needed to transport my motorcycle, and 10 ft trucks don’t have a ramp. Maybe I should have bought my own ramp. The rental cost for the truck was &lt;strong&gt;$3308.46&lt;/strong&gt;. I chose not to insure the truck separately because Penske was asking for almost $600 and my car insurance already covered rental vehicles. I also drove the truck extremely carefully and almost always 5-10 miles below the speed limit on cruise control.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id="trip-summary"&gt;🚗 Trip Summary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Starting point:&lt;/strong&gt; Santa Clara, CA&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Destination:&lt;/strong&gt; Hyattsville, MD&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Distance traveled:&lt;/strong&gt; 2,924 miles&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fuel consumed:&lt;/strong&gt; 242.83 gallons&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Total cost:&lt;/strong&gt; $738.89&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Average fuel economy:&lt;/strong&gt; ~12.0 mpg&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Average cost per gallon:&lt;/strong&gt; $3.04&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Average cost per mile:&lt;/strong&gt; $0.25&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id="fueling-and-mileage-log"&gt;🗺️ Fueling and Mileage Log&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;#&lt;/th&gt;
      &lt;th&gt;Place&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Miles to this place&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Gallons to this place&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Cost to this place&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Cumulative miles&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Cumulative gallons&lt;/th&gt;
      &lt;th style="text-align: right"&gt;Cumulative cost&lt;/th&gt;
      &lt;th style="text-align: right"&gt;MPG (segment)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;Santa Clara, CA&lt;/td&gt;
      &lt;td style="text-align: right"&gt;–&lt;/td&gt;
      &lt;td style="text-align: right"&gt;–&lt;/td&gt;
      &lt;td style="text-align: right"&gt;–&lt;/td&gt;
      &lt;td style="text-align: right"&gt;0&lt;/td&gt;
      &lt;td style="text-align: right"&gt;0&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$0.00&lt;/td&gt;
      &lt;td style="text-align: right"&gt;–&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;Fernley, NV&lt;/td&gt;
      &lt;td style="text-align: right"&gt;284&lt;/td&gt;
      &lt;td style="text-align: right"&gt;25.533&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$82.70&lt;/td&gt;
      &lt;td style="text-align: right"&gt;284&lt;/td&gt;
      &lt;td style="text-align: right"&gt;25.533&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$82.70&lt;/td&gt;
      &lt;td style="text-align: right"&gt;11.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;Elko, NV&lt;/td&gt;
      &lt;td style="text-align: right"&gt;259&lt;/td&gt;
      &lt;td style="text-align: right"&gt;22.079&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$75.93&lt;/td&gt;
      &lt;td style="text-align: right"&gt;543&lt;/td&gt;
      &lt;td style="text-align: right"&gt;47.612&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$158.63&lt;/td&gt;
      &lt;td style="text-align: right"&gt;11.7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;West Valley, UT&lt;/td&gt;
      &lt;td style="text-align: right"&gt;224&lt;/td&gt;
      &lt;td style="text-align: right"&gt;18.651&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$58.55&lt;/td&gt;
      &lt;td style="text-align: right"&gt;767&lt;/td&gt;
      &lt;td style="text-align: right"&gt;66.263&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$217.18&lt;/td&gt;
      &lt;td style="text-align: right"&gt;12.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;Laramie, WY&lt;/td&gt;
      &lt;td style="text-align: right"&gt;396&lt;/td&gt;
      &lt;td style="text-align: right"&gt;30.504&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$88.13&lt;/td&gt;
      &lt;td style="text-align: right"&gt;1,163&lt;/td&gt;
      &lt;td style="text-align: right"&gt;96.767&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$305.31&lt;/td&gt;
      &lt;td style="text-align: right"&gt;13.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6&lt;/td&gt;
      &lt;td&gt;Big Springs, NE&lt;/td&gt;
      &lt;td style="text-align: right"&gt;198&lt;/td&gt;
      &lt;td style="text-align: right"&gt;14.283&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$40.84&lt;/td&gt;
      &lt;td style="text-align: right"&gt;1,361&lt;/td&gt;
      &lt;td style="text-align: right"&gt;111.050&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$346.15&lt;/td&gt;
      &lt;td style="text-align: right"&gt;13.9&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;7&lt;/td&gt;
      &lt;td&gt;Lincoln, NE&lt;/td&gt;
      &lt;td style="text-align: right"&gt;294&lt;/td&gt;
      &lt;td style="text-align: right"&gt;25.588&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$75.71&lt;/td&gt;
      &lt;td style="text-align: right"&gt;1,655&lt;/td&gt;
      &lt;td style="text-align: right"&gt;136.638&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$421.86&lt;/td&gt;
      &lt;td style="text-align: right"&gt;11.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8&lt;/td&gt;
      &lt;td&gt;Chillicothe, MO&lt;/td&gt;
      &lt;td style="text-align: right"&gt;213&lt;/td&gt;
      &lt;td style="text-align: right"&gt;17.741&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$49.66&lt;/td&gt;
      &lt;td style="text-align: right"&gt;1,868&lt;/td&gt;
      &lt;td style="text-align: right"&gt;154.379&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$471.52&lt;/td&gt;
      &lt;td style="text-align: right"&gt;12.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;9&lt;/td&gt;
      &lt;td&gt;Macon, MO&lt;/td&gt;
      &lt;td style="text-align: right"&gt;60&lt;/td&gt;
      &lt;td style="text-align: right"&gt;0.167&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$0.49&lt;/td&gt;
      &lt;td style="text-align: right"&gt;1,928&lt;/td&gt;
      &lt;td style="text-align: right"&gt;154.546&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$472.01&lt;/td&gt;
      &lt;td style="text-align: right"&gt;359.3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;Hoopeston, IL&lt;/td&gt;
      &lt;td style="text-align: right"&gt;295&lt;/td&gt;
      &lt;td style="text-align: right"&gt;30.970&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$95.36&lt;/td&gt;
      &lt;td style="text-align: right"&gt;2,223&lt;/td&gt;
      &lt;td style="text-align: right"&gt;185.516&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$567.37&lt;/td&gt;
      &lt;td style="text-align: right"&gt;9.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;11&lt;/td&gt;
      &lt;td&gt;Centerville, IN&lt;/td&gt;
      &lt;td style="text-align: right"&gt;177&lt;/td&gt;
      &lt;td style="text-align: right"&gt;13.155&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$39.45&lt;/td&gt;
      &lt;td style="text-align: right"&gt;2,400&lt;/td&gt;
      &lt;td style="text-align: right"&gt;198.671&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$606.82&lt;/td&gt;
      &lt;td style="text-align: right"&gt;13.5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12&lt;/td&gt;
      &lt;td&gt;Morgantown, WV&lt;/td&gt;
      &lt;td style="text-align: right"&gt;318&lt;/td&gt;
      &lt;td style="text-align: right"&gt;26.139&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$78.39&lt;/td&gt;
      &lt;td style="text-align: right"&gt;2,718&lt;/td&gt;
      &lt;td style="text-align: right"&gt;224.810&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$685.21&lt;/td&gt;
      &lt;td style="text-align: right"&gt;12.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;13&lt;/td&gt;
      &lt;td&gt;Hyattsville, MD&lt;/td&gt;
      &lt;td style="text-align: right"&gt;206&lt;/td&gt;
      &lt;td style="text-align: right"&gt;18.019&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$53.68&lt;/td&gt;
      &lt;td style="text-align: right"&gt;2,924&lt;/td&gt;
      &lt;td style="text-align: right"&gt;242.829&lt;/td&gt;
      &lt;td style="text-align: right"&gt;$738.89&lt;/td&gt;
      &lt;td style="text-align: right"&gt;11.4&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;📝 &lt;em&gt;Note:&lt;/em&gt; The Macon, MO stop was a very small top-off, hence the unusually high calculated MPG for that leg.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id="observations"&gt;⛽ Observations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;strong&gt;best fuel efficiency&lt;/strong&gt; was between &lt;strong&gt;Big Springs, NE and Lincoln, NE&lt;/strong&gt; at nearly 13.9 mpg.&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;most expensive fuel stop&lt;/strong&gt; was in &lt;strong&gt;Hoopeston, IL&lt;/strong&gt; at &lt;strong&gt;$95.36&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;The &lt;strong&gt;total cost&lt;/strong&gt; of fuel for the entire trip came to &lt;strong&gt;$738.89&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;The trip averaged around &lt;strong&gt;12 mpg&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;Hope this helps any future movers.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.raviprak.com,2024-09-17:/research/linux/networking/networking.html</id>
    <title type="html">Networking on Linux.</title>
    <published>2024-09-17T04:00:00Z</published>
    <updated>2024-09-17T04:00:00Z</updated>
    <link rel="alternate" href="https://www.raviprak.com/research/linux/networking/networking.html" type="text/html"/>
    <content type="html">
&lt;h2 id="networking-on-linux"&gt;Networking on Linux.&lt;/h2&gt;

&lt;h6 id="last-modified--17-september-2024"&gt;Last modified : 17 September, 2024&lt;/h6&gt;

&lt;p&gt;&lt;br /&gt;
This page talks about how the networking stack is set up on some Linux computers.&lt;/p&gt;

&lt;h3 id="device-enumeration"&gt;Device Enumeration.&lt;/h3&gt;
&lt;p&gt;The Linux kernel boots up and enumerates all devices attached to all the buses (e.g. PCI). The devices are recognized by some mechanism and appropriate device drivers are loaded in, so that the kernel can interface with the devices. The &lt;strong&gt;networking&lt;/strong&gt; devices are enumerated in SysFS at &lt;code&gt;/sys/class/net&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ls -al /sys/class/net
total 0
drwxr-xr-x.  2 root root 0 Sep 17 10:00 .
drwxr-xr-x. 84 root root 0 Sep  4 14:13 ..
lrwxrwxrwx.  1 root root 0 Sep  4 14:13 lo -&amp;gt; ../../devices/virtual/net/lo
lrwxrwxrwx.  1 root root 0 Sep  4 14:13 wlp166s0 -&amp;gt; ../../devices/pci0000:00/0000:00:1d.0/0000:a6:00.0/net/wlp166s0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The devices are named so that across different boots, the name stays the same.&lt;/p&gt;

&lt;p&gt;To find out which device driver was loaded for each interface, you can use &lt;code&gt;ethtool&lt;/code&gt;. e.g.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ethtool -i wlp166s0 
driver: iwlwifi
version: 6.10.6-200.fc40.x86_64
firmware-version: 89.202a2f7b.0 ty-a0-gf-a0-89.uc
expansion-rom-version: 
bus-info: 0000:a6:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also SysFS has a link to the driver for the device:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ readlink /sys/class/net/wlp166s0/device/driver
../../../../bus/pci/drivers/iwlwifi
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="bringing-up-the-interfaces"&gt;Bringing up the interface(s).&lt;/h3&gt;
&lt;p&gt;The kernel sends+receives Ethernet / 802.11 / (some equivalent) Layer 2 frames to+from the device driver. The device driver interfaces with the networking hardware and sends+receives those Layer 2 frames. To check statistics you can use the &lt;code&gt;ip&lt;/code&gt; command. e.g.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ip -s link show wlp166s0 
2: wlp166s0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether d2:5d:d0:e6:c8:5e brd ff:ff:ff:ff:ff:ff permaddr 8c:f8:c5:ed:92:fc
    RX:   bytes  packets errors dropped  missed   mcast           
    21506231662 18394460      0   14606       0       0 
    TX:   bytes  packets errors dropped carrier collsns           
     1289526154  3582885      0       0       0       0 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more detailed statistics for wireless hardware, you can use &lt;code&gt;$ iw dev wlp166s0 station dump&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id="routing-table"&gt;Routing table.&lt;/h3&gt;
&lt;p&gt;The kernel uses routing tables to determine which interface should handle a connection. Routing tables map IP address ranges to specific interfaces. We can view the routing table using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ip route show
default via 192.168.68.1 dev wlp166s0 proto dhcp src 192.168.68.59 metric 600 
192.168.68.0/22 dev wlp166s0 proto kernel scope link src 192.168.68.59 metric 600 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This routing table is populated by the kernel using (typically) DHCP. The DHCP client sends a request which is responded to by the DHCP server. &lt;code&gt;$ nmcli device show&lt;/code&gt; can show the result of DHCP.&lt;/p&gt;

&lt;h3 id="dns"&gt;DNS&lt;/h3&gt;
&lt;p&gt;DHCP may also provide extra information for example DNS configuration.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ resolvectl status
Global
         Protocols: LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (wlp166s0)
    Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
         Protocols: +DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.168.68.1
       DNS Servers: 206.225.75.226 206.225.75.225 192.168.68.1
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id="vpn"&gt;VPN&lt;/h3&gt;
&lt;p&gt;When a VPN connection is established, it typically modifies the routing table on your machine so that your traffic is routed through the VPN’s virtual interface rather than directly through your physical network interfaces (like eth0 or wlan0).&lt;/p&gt;

&lt;p&gt;There are different types of VPNs, but two of the most common protocols used are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;OpenVPN (uses &lt;code&gt;tun&lt;/code&gt; or &lt;code&gt;tap&lt;/code&gt; devices)&lt;/li&gt;
  &lt;li&gt;WireGuard (uses &lt;code&gt;wg&lt;/code&gt; interfaces)&lt;/li&gt;
&lt;/ul&gt;

</content>
  </entry>
  <entry>
    <id>tag:www.raviprak.com,2024-01-11:/research/linux/bluetooth/tozo.html</id>
    <title type="html">Using Linux bluetooth to spoof Tozo headphones to pair them</title>
    <published>2024-01-11T05:00:00Z</published>
    <updated>2024-01-11T05:00:00Z</updated>
    <link rel="alternate" href="https://www.raviprak.com/research/linux/bluetooth/tozo.html" type="text/html"/>
    <content type="html">&lt;h2 id="spoofing-a-tozo-headphone-in-order-to-pair-the-left-with-the-right"&gt;Spoofing a TOZO headphone in order to pair the left with the right.&lt;/h2&gt;

&lt;h6 id="last-modified--11-jan-2024"&gt;Last modified : 11 Jan, 2024&lt;/h6&gt;

&lt;p&gt;This seems to be a fairly common problem. I faced it too. Despite following instructions to “hard-reset”, the left and right headphones would &lt;em&gt;just&lt;/em&gt; not pair with each other. I was able to pair each individual headphone with my laptop, which forced me to hear audio from only 1 side. I tried draining the battery completely in the hope that it would be akin to a “factory-reset”, but that didn’t help either.&lt;/p&gt;

&lt;p&gt;I was able to make the 2 headphones (TOZO-T10-L and TOZO-T10-R) pair with each other using Linux bluetooth commands. My strategy was to&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;turn off TOZO-T10-L&lt;/li&gt;
  &lt;li&gt;Change my laptop bluetooth adapter to pretend to be TOZO-T10-L&lt;/li&gt;
  &lt;li&gt;Turn on TOZO-T10-R&lt;/li&gt;
  &lt;li&gt;Pair TOZO-T10-R with my laptop (which is pretending to be TOZO-T10-L)&lt;/li&gt;
  &lt;li&gt;Turn off TOZO-T10-R&lt;/li&gt;
  &lt;li&gt;Turn off bluetooth on my laptop.&lt;/li&gt;
  &lt;li&gt;Turn on both TOZO-T10-L and TOZO-T10-R&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Turns out the above process did actually work for me and I was able to save my perfectly usable TOZO headphones from the trash.&lt;/p&gt;

&lt;p&gt;I first gathered the information about the headphones using 
&lt;code&gt;$ bt-device -l
Added devices:
TOZO-T10-L (00:00:00:03:07:8F)
TOZO-T10-R (00:00:00:00:3B:7F)
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I also saved my laptop’s real bluetooth configuration in a temporary file. The output of the command:
&lt;code&gt;$ btmgmt info
Index list with 1 item
hci0:	Primary controller
	addr 01:23:45:67:89:00 version 12 manufacturer 2 class 0x7c010c
	supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr le advertising secure-conn debug-keys privacy configuration static-addr phy-configuration wide-band-speech cis-central cis-peripheral 
	current settings: powered connectable discoverable bondable ssp br/edr le secure-conn cis-central cis-peripheral 
	name something
	short name 
hci0:	Configuration options
	supported options: public-address 
	missing options: 
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then turn off TOZO-T10-L and TOZO-T10-R. Make my laptop pretend to be TOZO-T10-L:
&lt;code&gt;$ sudo btmgmt public-addr 00:00:00:03:07:8F
$ sudo btmgmt name TOZO-T10-L
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turn on TOZO-T10-R. Pair my laptop again with TOZO-T10-R using:
&lt;code&gt;$ sudo btmgmt unpair 00:00:00:00:3B:7F
$ sudo btmgmt pair 00:00:00:00:3B:7F
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then turn off my laptop bluetooth (using the GUI). Turn off both headphones. Turn on both headphones. At this point my two headphones paired with each other and TOZO-T10-R was open to be paired with a device. I turned them both off and un-spoofed my laptop using.
&lt;code&gt;$ sudo btmgmt public-addr 01:23:45:67:89:00
$ sudo btmgmt name something
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turning them all again, I was able to pair everything perfectly and the audio came from left and right headphones correctly.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.raviprak.com,2019-11-11:/research/linux/sd_card_benchmarks/sd_card_benchmark.html</id>
    <title type="html">Benchmarks for SanDisk Extreme microSD cards.</title>
    <published>2019-11-11T05:00:00Z</published>
    <updated>2019-11-11T05:00:00Z</updated>
    <link rel="alternate" href="https://www.raviprak.com/research/linux/sd_card_benchmarks/sd_card_benchmark.html" type="text/html"/>
    <content type="html">&lt;h2 id="benchmarks-for-sandisk-extreme-microsd-cards"&gt;Benchmarks for SanDisk Extreme microSD cards.&lt;/h2&gt;

&lt;h6 id="last-modified--november-11-2019"&gt;Last modified : November 11, 2019&lt;/h6&gt;

&lt;p&gt;I recently bought 2 SanDisk Extreme microSD cards (256Gb). I also happened to have the same SD card brand for (32Gb). The device I had it in was also reporting errors writing to the SD card. I benchmarked before and after fixing it using the Linux Disk Utility. I ran the Linux filesystem benchmarks and thought it might be useful for people who are also considering purchasing it. Even though the SD cards are advertised as having a max read throughput of 160MB/s, I wasn’t able to get that performance. I tried with different filesystem formats (ext4, NTFS, FAT), still no dice&lt;/p&gt;

&lt;h2 id="gb-card-before-fixing"&gt;32Gb card before fixing:&lt;/h2&gt;
&lt;p&gt;&lt;img src="32gb_sd_card1.png" alt="32Gb Benchmarked before fixing" /&gt;
&lt;img src="32gb_sd_card2.png" alt="32Gb Benchmarked after fixing" /&gt;&lt;/p&gt;

&lt;h2 id="gb-card-after-fixing"&gt;32Gb card after fixing:&lt;/h2&gt;
&lt;p&gt;&lt;img src="32gb_after_fixing.png" alt="32gb_after_fixing.png" /&gt;&lt;/p&gt;

&lt;h2 id="gb-card-after-fixing-with-different-filesystems"&gt;32Gb card after fixing with different filesystems:&lt;/h2&gt;

&lt;h4 id="ext4"&gt;Ext4&lt;/h4&gt;
&lt;p&gt;&lt;img src="32gb_with_ext4.png" alt="32gb_with_ext4.png" /&gt;&lt;/p&gt;

&lt;h4 id="fat"&gt;FAT&lt;/h4&gt;
&lt;p&gt;&lt;img src="32gb_with_fat.png" alt="32gb_with_fat.png" /&gt;&lt;/p&gt;

&lt;h4 id="ntfs"&gt;NTFS&lt;/h4&gt;
&lt;p&gt;&lt;img src="32gb_with_ntfs.png" alt="32gb_with_ntfs.png" /&gt;&lt;/p&gt;

&lt;h2 id="gb-card-sandisk-extreme-microsd-uhs-i-card---256gb-product-sku-sdsqxa1-25"&gt;256Gb card: SanDisk Extreme microSD UHS-I Card - 256GB. Product SKU SDSQXA1-25&lt;/h2&gt;
&lt;p&gt;&lt;img src="256gb_benchmark.png" alt="256gb_benchmark.png" /&gt;&lt;/p&gt;

</content>
  </entry>
  <entry>
    <id>tag:www.raviprak.com,2019-06-12:/research/linux/hdd/hdd-disassembly.html</id>
    <title type="html">Disassembling a Hard Drive</title>
    <published>2019-06-12T04:00:00Z</published>
    <updated>2019-06-12T04:00:00Z</updated>
    <link rel="alternate" href="https://www.raviprak.com/research/linux/hdd/hdd-disassembly.html" type="text/html"/>
    <content type="html">&lt;h2 id="disassembling-a-hard-drive"&gt;Disassembling a hard drive&lt;/h2&gt;

&lt;h6 id="last-modified--12-june-2019"&gt;Last modified : 12 June, 2019&lt;/h6&gt;

&lt;p&gt;In the past year one of the hard drives in my desktop started to fail. It first manifested as SMART errors while booting up, and then one day a remarkably loud scratching noise. The irony is that this was the newer of the 2 hard disks in my RAID1 (mirroring) configuration. It was a Seagate Barracuda ST2000DM001. By my count, it lasted me ~3.5 years. My desktop is usually idle (no gaming, no constant write / read loads) so its a little disappointing given the other soldier in my RAID1 is going strong still. Oh well!&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_144535.jpg" alt="Hard drive bottom" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_144540.jpg" alt="Hard drive top" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;I decided to destructively disassemble the hdd, just for kicks. The following are the pictures I took and short blurbs. I’m glad I did it because its fascinating how such small things can store &lt;strong&gt;so&lt;/strong&gt; much data. The process of disassembly itself was very easy too. All I needed was the correct screwdrivers (I think 3 of them) that any small screwdriver kit would have.&lt;/p&gt;

&lt;p&gt;First to come off was the control board. This board plugs into the SATA port on the Motherboard. On the other side it had a 3-pin (I wonder why 3) connection to the motor which rotates the platter and a springy socket for reading the signals coming from the head. I’ve heard there are millions of lines of code running on the microcontroller on the control board. It exports the SATA API and schedules all the accesses on the physical media.&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_144837.jpg" alt="The Control board" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;The next thing to unscrew was the top plate. There were a bunch of screws (and some hidden under stickers) but once all of them were unscrewed, the top plate came off very easily exposing the inner components.&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_145427.jpg" alt="The inside of an hdd" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;The next thing I unscrewed were the platters. Again a bunch of screws. What I didn’t quite expect was that the platters were so shiny and thick. I bent them to destroy the data, and I couldn’t with my bare hands. I had to use pliers and good leverage. The surface was shiny like a mirror rather than the rusty brown color of iron oxide that was the color of the magnetic tape of floppy disks. I was also surprised that there were only 2 platters. Somehow I had expected more of them. I’m sure a lot of engineering effort has gone into optimizing the characteristics of these components. I did remember the white paper from Google on &lt;a href="https://ai.google/research/pubs/pub44830"&gt;Disks for Data Centers (2016)&lt;/a&gt;. Its a good read if you haven’t so far. I was also hoping I’d see some scratches owing to the loud scratching I had heard, but I wasn’t able to spot any with my eyesight.&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_150302.jpg" alt="The platters which store all data" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;The next component I took off was the head. It was mounted on a spring system. I probably damaged it while taking it off. The arms were made of solid metal, at the end of which was a triangular plastic protruding with a small sensor at the end. I tried getting good pictures of this from different angles. The base of the arms had a solenoidal loop of wire. I’m guessing the physics of this component are what determine the seek time of these disks.&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_150416.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_150817.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151118.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151126.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151150.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151203.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151417.jpg" alt="The head" height="25%" width="25%" /&gt;
&lt;img src="./IMG_20190527_151434.jpg" alt="The head" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;The last thing to come off was the motor. I did note that the bearings were extremely smooth and efficient. I tried incorrectly to uncap the motor at first hitting it repeatedly with a heavy duty hammer before realizing I was going the wrong way. The rotor needs to be pushed out from the bottom of the hard drive towards the top. Even after such excessive abuse, the bearings were more or less smooth-ish. These bearings are probably the majority of the steady state power draw.&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_152159.jpg" alt="The motor" height="25%" width="25%" /&gt;&lt;/p&gt;

&lt;p&gt;The case itself was pure solid metal. I don’t think any amount of hammering would have bent it. Here’s a picture of the tools that I used:&lt;/p&gt;

&lt;p&gt;&lt;img src="./IMG_20190527_152320.jpg" alt="The tools I used" height="25%" width="25%" /&gt;&lt;/p&gt;

</content>
  </entry>
</feed>

