Friday, April 3, 2015

Script to simulate multiple DHCP clients

#!/bin/sh
#simulate 255 IPhones requesting DHCP
 
 
# Apple OUI = D8:96:95
BASE="d8:96:95:08:96"
FROM=$1
shift
TO=$2
 
if [ -e $FROM ]; then FROM=1; fi
if [ -e $TO ]; then TO=1; fi
 
for i in `seq $FROM $TO`
do
    LSB=`echo "obase=16; $i" | bc`
    MAC="$BASE:$LSB"
    HNAME="`uname -n`-fakehost-$i"
    #CMD="$HOME/bin/dhtest -m $MAC -V -i eth1 -h '$HNAME'"
    CMD="$HOME/bin/dhtest -m $MAC -i eth1 -h '$HNAME'"
    echo $CMD
    $CMD
    sleep 1
done

Another way, the program dhtest (source code) can be download from  https://github.com/saravana815/dhtest.  

For example:
 
git clone https://github.com/saravana815/dhtest
cd dhtest
make

Daily backup of local git changes

While working on a ticket and not ready to commit, it's a good idea to backup all of our changes to an archive file.

The following script does all that and executed daily by cronjob automatically.
  1. create a file, say "backup" in /etc/cron.daily
  2. Type the following (change '<yourhome directory>' to your own login name and <git location> to the git directory where source codes are located):
backing up changed files to tarball
#!/bin/sh
pushd <your source-code location>
LIST=`git status --porcelain | sed -n -e '/^ [D|M]/p' | sed -e 's/^ [D|M] //'`
backupname=`git branch | sed -n -e "/^* /p" | sed  -e 's/** //'`
backupname=$backupname-`date "+%s"`.backup.tar.bz2
dest='<your home directory>'
if [ ! -d "$dest" ]
then
    mkdir -p $dest
fi
tar jcvf $dest/$backupname $LIST > /dev/null

Make the file executable:
chmod +x /etc/cron.daily/backup

Sunday, March 22, 2015

Block Access during certain period using EBTABLES


Say, we want to block any packets coming from a device with mac address 00:01:02:03:04:05 (in other words, our router/switch should just silently drop any packets coming from this MAC address) during period of time 00:00 (00:00 AM) to 6:00 AM, do:

#ebtables -A INPUT -s 00:01:02:03:04:05  --timestart 0:0 --timestop 06:00 -j DROP


If we just want to drop IPv4 packets for the above:

#ebtables -A INPUT -p IPv4 -s 00:01:02:03:04:05  --timestart 0:0 --timestop 06:00 -j DROP


So, parameters for ebtables are actually similar (yet subset) of iptables (netfilter).

Wednesday, March 11, 2015

To fix Mute button keyboard shortcut issue on LXDE

Create a script call "amixertoggle" and save it in /usr/local/bin:

#!/bin/bash

amixer $1 sset Headphone toggle
amixer $1 sset Speaker toggle
amixer $1 sset PCM toggle
amixer $1 sset Master toggle




Edit file $HOME/.config/openbox/lxde-rc.xml and replace block that has "XF86AudioMute" to call our script.  For example:

...
...

    <keybind key="XF86AudioMute">
      <action name="Execute">
              <command>amixertoggle -c 1 toggle</command>
      </action>


...
...

(" -c 1" above is for machine, where the mixer control is actually on card 1.  If doesn't work, we can try different number)

Reload the modified file lxde-rc.xml by doing:

openbox --reconfigure

That's it.  Everytime we press "Mute" button on our PC keyboard, the mute/unmute will toggle.

Thursday, February 26, 2015

Raspberry Pi 2

Got this New Raspberry Pi 2 I ordered a few weeks ago.  It's significantly faster than the first version.  I only wish it had USB 3.0 ports so I can have much bigger and faster storage.

Monday, October 13, 2014

Cheap ATMEL AVR ISP ICE from QinHeng

I bought this small USB stick from eBay.  It supposedly can do JTAG and many other cool stuff for ATMEL microcontrollers.

Anyway, here is the detail how to use it:

The other end of the stick has dual-line 10-pin connector.  The pins are:

Pin  Purpose
------------------------------
1    TCK
2    GND
3    TDO
4    VTref
5    TMS
6    nSRT
7    VSupply
8    (nSRT)
9    TDI
10   GND

These pins are actually JTAG pins.  The connections to the Microcontroller is as follow (the pullup resistors are all 4.7k):



The USB id:

$ lsusb
...
Bus 003 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
...


Upon inserting the stick to my PC's USB (running Ubuntu Linux):

[118845.955500] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[118845.955541] ch341 3-2:1.0: device disconnected
[118851.692044] usb 3-2: new full-speed USB device number 6 using ohci-pci
[118851.901261] usb 3-2: New USB device found, idVendor=1a86, idProduct=7523
[118851.901271] usb 3-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[118851.901276] usb 3-2: Product: USB2.0-Serial
[118851.904683] ch341 3-2:1.0: ch341-uart converter detected
[118851.940428] usb 3-2: ch341-uart converter now attached to ttyUSB0


To use it as programmer, we can use avrdude:

$ sudo avrdude -c avrisp -P /dev/ttyUSB0 -pm328p <other options>

To debug, we can use another opensource, AvaRICE (from ubuntu, just do "apt-get install avarice").

For example (this is just to show how to use it, as my ICE stick is not connected to any target device yet so it reports it "No configuration available for device ID: ffff"):

$ sudo avarice --jtag /dev/ttyUSB0 -1
AVaRICE version 2.11, Jan 17 2014 02:53:19

Defaulting JTAG bitrate to 250 kHz.

JTAG config starting.
Hardware Version: 0xc3
Software Version: 0x80
Reported JTAG device ID: 0xFFFF
No configuration available for device ID: ffff


The avarice can be set as a gdb server mode, so we can debug the target removely. For example, to make it as gdb-server listening on port 4242.

$ sudo avarice --jtag /dev/ttyUSB0 :4242

From another PC (or the same PC, if host and server is on the same machine), we open gdb, and connect:

$ gdb
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) target remote 127.0.0.1:4242





Using PicKit2 Programmer to program Atmel's microcontrollers

Many hobbists are familiar with Arduino kit.  This beast uses various Microcontrollers from Atmel.  For example, Arduino UNO uses AtMega 328p.

Normally, we use the pcb kit to program the chip, as the Arduino (or the clones) use USB to serial chip to translate  USB to serial needed to program Arduino.

For people who has done hacking on PIC microcontrollers from MicroChip and wants to use bare-metal chip, they can program the Atmel chips using the existing cheap PicKit2 programmer.  What they need just the Pickit2 programmer and a software tool called avrdude.

The pin connections:

AVR   - PICKit2 (pin):
----------------------- 
RST   - VPP/MCLR (1)
VDD   - VDD Target (2) -- optional if AVR self powered
GND   - GND (3)
MISO  - PGD (4)
SCLK  - PDC (5)
MOSI  - AUX (6) 
 
 
Some of command examples are shown below:

To write our firmware to the flash in AtMega 328p:

 
$ avrdude -c pickit2 -p m328p -v -V -U flash:w:"myfirmware.hex":a 
 

To upload bootloader (e.g. to upload ARDUINO bootloader):
 
$ avrdude -c pickit2 -p m328p -v -V -U boot:w:"boot.hex":a 

 

Left shift by negative number used to test unique characters in a string

What is the outcome of this?

val=-32;
mask = 1<<val;

I tried to execute it on Python, it failed with error message.

But if I do it in C or C++, I get something else.  Turn out, this depends o the compiler and CPU we use.  As I use Pentium4 and GCC to compile this, the following snippet of the generated assembly language is interesting:


.L4:
        movsbl  (%edx), %ecx
        movl    %esi, %edi
        addl    $1, %edx
        subl    $97, %ecx
        sall    %cl, %edi
        testl   %eax, %edi
        jg      .L5
        orl     %edi, %eax

.L2:

What is "sall" above? It is Intel CPU's mnemonic for "Shift Arithmetic Left for Long Integer".

In the machine code, -32 is transformed to Second-complement of 32:

32        = 0b00100000
~32      = 0b11011111
~32+1 = 0b11100000 = -32

According Wikipedia,  arithmetic shift left maintains the MSBit, so in this case MSB is always 1. Also, Intel CPUs only shifts the first 5-bits of the shifting bits (in this case, 5-bit LSB of 0b11100000 which is 0), so 1<<-32 is actuall 1<<0 = 1.

What about 1<<-33?

33        = 0b00100001
~33      = 0b11011110
~32+1 = 0b11100001 = -33

The first five bits is 1, so 1<<-33 = 1<<1 = 2

What about 1<<-31?

31        = 0b00011111
~31      = 0b11100000
~31+1 = 0b11100001 = -31

The first five bits is 1, so 1<<-31 = 1<<1 = 0x00000010

What about 1<<-7?

7        = 0b00000111
~7      = 0b11111000
~7+1 = 0b11111001 = -7

The first five bits is 1, so 1<<-7 = 1<<25 = 0x02000000

Now, how do we use this to check a uniqueness of characters in a string? 
Alphabet 'A' to 'Z' has 26 characters. Alphabet 'a' to 'z' has also 26 characters.

The difference between the character i in a string is: str[i] - 'a'.  Now this is the interesting part: if we declare a 32-bit variable (which is enough to cover 'A' to 'Z') where each bit corresponds to the occurence of each character in alphabet, we can determine if the character has been used before and tell the string has unique characters or not (e.g, bit 1 to tell if character 'A' has been used or not, etc.)

'A' - 'a' = -32
...
...
'Z' - 'a' = -7
...
...
'a' - 'a' = 0
...
...
'Z' - 'a' = 25

if we shift 1 to -32, it is the same as 1<<0.  If we shift 1 to -33 it is the same as 1<<1, so on.

1<<-32 = 0x01
1<<-31 = 0x02
...
...
1<<-7 = 1<<25 = 0x2000000
1<<0 = 0x01
1<<1 = 0x02
...
...
1<<25 = 0x2000000

so:
 1<<('A'-'a') == 1<<('a'-'a') = 0x01
 1<<('B'-'a') == 1<<('b'-'a') = 0x02
...
...
1<<('Z'-'a') == 1<<('z'-'a') = 0x2000000

So the code is:

for (i=0; i<strlen(s); i++)
{
    val = s[i] - 'a';
    if (flags & (1 << val))
        return 0; /* the string is not unique */
    flags |= 1 << val;
}
return 1;


Notice this algorithm might not work on different machine with different compiler (as shifting by negative number is undefined in standard C).





The Use of c++decl

cdecl and c++decl are two nice tools to check syntax or to generate declaration of C and C++ respectively.

for example, using c++decl (the text in bold is the one we type):

$ cdecl

Type `help' or `?' for help
c++decl>

c++decl> declare foo as pointer to member of class X function (arg1, arg2) returning reference to class Y
class Y &(X::*foo)(arg1, arg2)
c++decl>

c++decl> declare foo as reference to class X
class X &foo
c++decl>

c++decl> cast foo into reference to class X
(class X &)foo
c++decl>


We can also use them to check a declaration syntax, for example:

c++decl> explain int (*a)[5]
declare a as pointer to array 5 of int
c++decl>

c++decl> explain long **foo[10]
declare foo as array 10 of pointer to pointer to long
c++decl>

c++decl> explain int*&(foo);
declare foo as reference to pointer to int
c++decl>

The function can also be used to translate an english declaration to C (or C++) declaration.  For example:

$ c++decl declare "i as array 5 of pointer to function(int,int) returning reference to class X"
class X &(*i[5])(int , int )
$

$ c++decl declare "i as array 5 of pointer to function(reference to class X,constant reference to int) returning reference to class X"
class X &(*i[5])(class X &, int & const )
$

$ c++decl declare "const_ptr as const pointer to const int"
const int * const const_ptr

$ c++decl declare "const_ptr as const pointer to const reference to class X"
class X & const * const const_ptr
$

c++decl> declare myfunc as const pointer to function (const pointer to int, reference to class X) returning void
void (* const myfunc)(int * const , class X &)
c++decl>

c++decl> declare myfunctpr as array of pointer to function (void) returning int
int (*myfunctpr[])(void )
c++decl>

declare myptr as pointer to array 10 of struct MyStruct
struct MyStruct (*myptr)[10]
c++decl>


Saturday, October 4, 2014

Odd Numbers with Parity


#!/usr/bin/python

table=[]
for n in range(0,256):
    p=False
    while n:
        p = not p
        n &= n-1
    table.append(p)

parity_odd = []
print "Odd numbers with Parity:"
for i in range(0,256):
if (i%2) and (table[i]): parity_odd.append(i) print i,

Result:

Odd numbers with Parity:
1 7 11 13 19 21 25 31 35 37 41 47 49 55 59 61 67 69 73 79 81 87 91 93 97 103 107 109 115 117 121 127 131 133 137 143 145 151 155 157 161 167 171 173 179 181 185 191 193 199 203 205 211 213 217 223 227 229 233 239 241 247 251 253


Thursday, October 2, 2014

Fastest Fibonacci Sequencer

This algorithm is based on Fast-doubling  as explained in Fast Fibonacci algorithms.

Given F(k) and F(k+1), we can calculate these equations:

F(2k) = F(k)[2F(k+1)−F(k)]
F(2k+1) = F(k+1)2+F(k)2.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#ifdef DEBUG
#define DBGMSG(x)       printf x 
#else
#define DBGMSG(x)
#endif

typedef unsigned long long num_type;

void _fib(int n, num_type *fn, num_type *fn_1);

num_type fibonacci(uint n, num_type *s)
{
 int i;
    num_type fn=0, fn_1=1;

 if (!s)
  return 0;

 if (n < 2)
    {
  return 1;
    }
    for(i=1; i<n; i++)
    {
        _fib(i, &fn, &fn_1);
        DBGMSG(("i=%u, n=%u, fn=%llu, fn+1=%llu\n", i, n, fn, fn_1));
        s[i] = fn;
    }
    return s[n];
}

/*
 * This is base on matrix exponentiation algorithm:
 * where:
 *  f(2k) = f(k)*{ 2*f(k+1) - f(k)}         ---> c
 *  f(2k+1) = f(k)^2 + f(k+1)^2             ---> s
 *
 *  if we plugin k = n/2, we get f(n) and f(n+1)
 */
void _fib(int n, num_type *fn, num_type *fn_1)
{
    num_type c,d;
    num_type a, b;

    DBGMSG( ("%s: Initially n=%u, fn=%llu, fn_1=%llu\n", __FUNCTION__, n, *fn, *fn_1) );
    if (n==0)
    {
        *fn = 0;        // fn
        *fn_1 = 1;      // fn+1
        return; 
    }
    else {
        a = *fn;
        b = *fn_1;
    }
    _fib(n>>1, &a, &b);
    DBGMSG (("%s: local fn=%llu, fn_1=%llu\n", __FUNCTION__, a, b));
    c = a * (2*b - a);
    d = b*b + a*a;
    DBGMSG( ("%s: c=%llu, d=%llu\n", __FUNCTION__, c, d) );
    if (n % 2 == 0)
    {
        // n is even
        *fn = c;
        *fn_1 = d;
    }
    else {
        *fn = d;
        *fn_1 = c+d;
    }
}

int main(int argc, char *argv[])
{
 uint n;
 uint f;
 int i;
 num_type *result;
    char *sbuf;
    int status = 0;

    if (argc > 1)
        n = atoi(argv[1]);
    else {
     printf("Enter a number: ");
        sbuf = (char *)malloc(50);
     status = (getline(&sbuf, &n, stdin) > 0);
        if (status == 0) {
      n = atoi(sbuf);
            free(sbuf);
        }
       else {
            printf("Error in input\n");
            return (1);
        }
    }
    if (n <= 0)
    {
        printf("What have yo done???\n");
        return(0);
    }
    if (status == 0)
 {
     result = (num_type *)malloc(n*sizeof(unsigned long long));
     f = fibonacci(n, result);
  printf("Fibonacci sequence: ");
  for(i=0; i<n; i++)
   printf("%llu ", result[i]);
  printf("\n");
        if (result)
      free(result);
    }
}

Friday, September 26, 2014

Fastest bit counting

The best bit counting algorithm as far as I know is the one invented by folks at Stanford University, which is always O(1).

int bitcount(int n)
{
    int cnt = 0;

    n = n - ((n >> 1) & 0x55555555);
    n = (n & 0x33333333) + ((n >> 2) & 0x33333333);

    return (((n + (n >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

For example, after I compile it to x86 Assembly:

    .cfi_startproc
    movl    4(%esp), %eax
    movl    %eax, %edx
    sarl    %edx
    andl    $1431655765, %edx
    subl    %edx, %eax
    movl    %eax, %edx
    sarl    $2, %eax
    andl    $858993459, %edx
    andl    $858993459, %eax
    addl    %edx, %eax
    movl    %eax, %edx
    sarl    $4, %edx
    addl    %edx, %eax
    andl    $252645135, %eax
    imull   $16843009, %eax, %eax
    sarl    $24, %eax
    ret
    .cfi_endproc


But, how does actually the algorithm work?

Ok, let try a simple one.  Assume n is a 4-bit number, and the bits can be represented as a set such that n= {a,b,c,d}., where a,b,c.. can only have either 0 or 1.  The decimal value of the n is: 8*a + 4*b + 2*c + d.  Total number of bit one is: a + b + c +d.  

For example, for n=0b1101, a=1, b=1, c=0, d=1 (which in decimal is 8*1 + 4*1 + 2*0 + 1 = 13), and total number of bit one is a+b+c+d = 1 + 1 + 0 + 1 = 3.  So far so good?

Now, we know that to count the 1-bits is as simple as: a+b+c+d.  But, wait.... n itself is not a+b+c+d, but 8*a + 4*b + 2*c + d.  Ok, let's conquer this step-by-step.  

If we shift n one bit to the right the LSbit is gone and other numbers just divided by two, so n becomes 4*a + 2*b + c, right? Now substract this to the original n.
  
n      = 8*a + 4*b + 2*c + d
n>>1   = 0 +   4*a + 2*b + c
----------------------------- -
       = 0   + 4*a + 2*b + c + d

That's a good direction!  Now if  (n>>1)  is written in the 4-bit nibble it is actually 0 + 4a + 2b + c.  If I just want to subtract 4a and c, we have to mask out 2*b.  so we mask it with binary 0101 (0x5), so we get only 4a + c:

n              = 8*a + 4*b + 2*c + d
(n>>1)&0x5     = 4*a +   0 + c
---------------------------------- -
n -(n>>1)&0x05 = 4*a + 4*b + c + d

Now store this result back to n, so from now on n is 4*a + 4*b + c + d
To get c + d only, we mask n with 0b11 or n & 0x03
if we shift n above once, we get 0 + 2a + 2b + 0, but if shift it again it becomes a + b!
To make sure we only get the lowest two bits (a + b), we mask it to 0x03 or:

n & 0x03       = c + d
(n >> 2)&0x03) = a + b
------------------------ +

Nice! now we have this expression: a + b + c +d .

so, for 4-bit bit counting, we can use the expression:

n = n - (n>>1) & 0x05
bits = (n & 0x3) + (n>>2) & 0x3

Proof: as example above, n=13 (0b1101).  so a=1,b=1, c=0, d=1

n = 0b1101 - (0b0110) & 0b0101 = 0b1101 - 0b100 = 13 - 4 = 9 = 0b1001
then the next step:
bits =(0b1001 & 0b0011)  +  (0b1001>>2) & 0b0011, or bits = 0b0001 + (0b0010) & 0b0011
 or bits = 1 + 2 = 3 !!

For 32-bit, it is based on the same idea, except we have to do more.

Say n  has set of coefficients {a[0], a[1], ...., a[31]} to represent the number, so n = a[0]*2^31 + a[1]*2^30 + .... + a[15]*2^0

The mask should be 32-bit, so instead of 0x5, we use 0x55555555 = 0b0101010101...0101

n                   = 2^31*a[0] + ... + 2^1*a[30] + 2^0*a[31]
(n>>1)&0b0101..0101 = 2^30*a[0] + ... + 2^2*a[28] + 2^0*a[30]
-------------------------------------------------------------- -
n -(n>>1)&0x055555555 = 2^31*a[0] - 2^28*a[0] + (2^30*a[1] - 2^26*a[1]) + ... + 4*a[29] - 2*a[30] + a[31]


Let's review binary arithmetics.

23 - 22 = 8 - 4 = 4
216 - 215 = 65536 - 32768 = 32768
or: 2(a+1) - 2a = 2a

2(a+2) - 2a = 2a * 22 - 2a = 2a (4 - 1) = 3*2a

So the result is:

a[0] * (2^31 - 2^28) + a[1] * (2^30 - 2^26) + ..... + a[30] (4 -2) + a[31]
= 3*2^28*a[0] + .3*2^26*a[1].. + 2*a[30] + a[31]

n - n(>>1) & 0x055555555 = 3*2^28*a[0] + .3*2^26*a[1].. + 2*a[30] + a[31]

stored this as a new n.

n>>2 = 2^24*a[0] + 2^22*a[1] + ...2*a[28] + a[29]

The rest is actually manipulation to count this a[0] + a[1] + ...  + a[31]

A variant, but this one is invented by folks at MIT:

int bitcount(unsigned int n)
{
    int cnt = 0;
    register unsigned int tmp;
                     
    tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) &    011111111111);

    return ((tmp + (tmp >>3)) & 0030707070707) % 63;
}

It uses the similar method. but with different approach (notice the number 01..., 0333... and 00307... are in octal.  We could use Hex version but then it is harder to remember)





Monday, June 2, 2014

Audio on Laptop HP dv7-6c80us not working

Problem:

HP-PAVILION-DV7:~$ aplay -l
aplay: device_list:268: no soundcards found...
HP-PAVILION-DV7:~$ 

HP-PAVILION-DV7:~$ lsmod | grep snd
snd_hda_codec_hdmi     41154  0 
snd_hda_codec_idt      50341  1 
snd_hda_intel          52267  0 
snd_hda_codec         188738  3 snd_hda_codec_hdmi,snd_hda_codec_idt,snd_hda_intel
snd_hwdep              13602  1 snd_hda_codec
snd_pcm               102033  3 snd_hda_codec_hdmi,snd_hda_codec,snd_hda_intel
snd_page_alloc         18710  2 snd_pcm,snd_hda_intel
snd_seq_midi           13324  0 
snd_seq_midi_event     14899  1 snd_seq_midi
snd_rawmidi            30095  1 snd_seq_midi
snd_seq                61560  2 snd_seq_midi_event,snd_seq_midi
snd_seq_device         14497  3 snd_seq,snd_rawmidi,snd_seq_midi
snd_timer              29433  2 snd_pcm,snd_seq
snd                    69141  11 snd_hwdep,snd_timer,snd_hda_codec_hdmi,snd_hda_codec_idt,snd_pcm,snd_seq,snd_rawmidi,snd_hda_codec,snd_hda_intel,snd_seq_device,snd_seq_midi
soundcore              12680  1 snd

HP-PAVILION-DV7:~$ cat /proc/asound/pcm 
00-00: 92HD81B1X5 Analog : 92HD81B1X5 Analog : playback 1 : capture 1

HP-PAVILION-DV7:~$  lspci -v
...
...
00:1b.0 Audio device: Intel Corporation 6 Series/C200 Series Chipset Family High Definition Audio Controller (rev 05)
Subsystem: Hewlett-Packard Company Device 165b
Flags: bus master, fast devsel, latency 0, IRQ 54
Memory at c6500000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [50] Power Management version 2
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00
Capabilities: [100] Virtual Channel
Capabilities: [130] Root Complex Link
Kernel driver in use: snd_hda_intel



Thursday, February 6, 2014

The Magic of 37

If x is a multiplication of 3 (3,6,9,12,15,....)

37 * x = y1y2y3 = z

 y1 + y2 + y3 = x
 y1 = z div 100
 y2 = (z mod 100) div 10
 y3 = (z mod 10) div 1

Examples:
37*3 = 111
1+1+1 = 3

37*6 = 222
2+2+2 = 6

Interesting, isn't??

Not really so.   x is multiplication of 3, so x = 3*b (where b=1,2,3...)
37*x = 37 * (3*b) = 111*b = bbb

so bbb = y1y2y3 = yyy

or y = b

When we do y1 + y2 + y3, it is actually b + b + b.  For example, pick b=2 (so x=6), 111*b = 222, 2+2+2=6=x.



Tuesday, December 31, 2013

Value with a constant growth factor

Many times we hear in the news, either financial news or economy in general, about growths with constant factor.  For example: "The appreciated value of residential property in townville grows at 4% per year', or "The stock price grows constantly at 5% per year", or "the population of villageville decreases by constant factor of 5%".

What does it mean?

Well, it is actually simple.  The value increases by factor of 4%.  If the current value is A0, next year its value is A0 + 4%*A0.  Next 2 years the value is A1 + 4%*A1 = A0*(1+4%)^2 and so on.  From this, we can deduct a general formula for a growth (which is a form of geometric series):

A(t) = A(0) * (1+g/100)^t

Where A(0) is the value at the initial evaluation (t = 0)
t = unit time for the growth
g = percentage of growth (in %), so we need to divide it by 100 there
A(t) = the value at t

From this formula, we also can find "Doubling Time", or the time needed for a value to be double.

Tdouble = ln(2) / ln( 1+g/100)

For example:
Michael bought his house in 2002 for $315,000.  The average appreciation rate of properties in his area is 2%/year.  How long he has to keep his house to make the house value double (assuming the appreciation rate stays the same)?

Answer:

Tdouble = ln(2) / ln( 1 + 2/100) = 0.693/0.0198 = 35 years.


P.S:
For negative growth (decrease), use negative g.

More complex calculation is if the growth factor is not constant.


Monday, December 16, 2013

How to mount disk used by ReadyNAS

The following steps are useful if we want to salvage data stored in the drive in ReadyNAS.
I am not sure if the steps below are going to work on other ReadyNAS models, but it works on my ReadyNAS Duo (Sparc CPU).

Basically, what we need is a SATA-to-USB cable (can be bought on the Internet for couple of bucks).
NETGEAR ReadyNAS partitions the drive into 4 partitions.  In my case, it is detected as /dev/sdc:


[root@r3000 media]# fdisk -l /dev/sdc

Disk /dev/sdc: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders, total 1953525168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1               2     4096001     2048000   83  Linux
/dev/sdc2         4096002     4608001      256000   82  Linux swap / Solaris
/dev/sdc3         4608002  1953092233   974242116    5  Extended
/dev/sdc5         4608003  1953092233   974242115+  8e  Linux LVM
[root@r3000 media]# 


There are couple of issues if we try to mount the partitions directly:

  1. ReadyNAS uses non-standard ext3 block-size, which in my case is 16384 bytes (use command "lvsc" to check)
  2. The home directory is partitioned as LV group, so conventional mount command is not gonna work
Here's the steps:
  • Scan the usb for LVM volumes and identify in the output the volume group name that has your READYNAS volume (mine proved to be c):
# vgscan
[root@r3000 media]# vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "c" using metadata type lvm2
  Found volume group "vg_r3000" using metadata type lvm2
  Found volume group "VolGroup" using metadata type lvm2

  • Activate the group for ReadyNAS (in this case, the group name is "C")
# vgchange -ay c
  • Find the logical volume that  (mine proved to be 'c'):
# lvs
  • root@r3000:/home/root# lvs
      LV   VG   Attr      LSize   Pool Origin Data%  Move Log Copy%  Convert
      c    c    -wi-ao--- 929.09g  
     
  • To display the logical name of the partition, use command "lvdisplay":
# lvdisplay /dev/c
  --- Logical volume ---
  LV Name                /dev/c/c
  VG Name                c
  LV UUID                7HUOrf-B5bL-ur6r-ULsd-yl4m-gCrA-zQc4s9
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                929.09 GiB
  Current LE             29731
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:5


We cannot use regular command "mount" to mount the non-standard blocksize ext3 partition.  Fortunately, there is a tool called "fuse-ext3" running in userspace that can help us.  The tool can be downloaded here.

Here's an example how to mount my ReadyNAS's LV volume:

fuse-ext2 -o sync_read,allow_other,rw+ /dev/c/c /media/readynas2

And here is the command to mount the system (root) partition which has the Linux software (I will post later about how to reset root password without resetting the ReadyNAS to factory default etc.)

fuse-ext2 -o sync_read,allow_other,rw+ /dev/c/c /media/readynas2


Note: don't forget to unmount the partitions once your'de done.



Why we need to migrate to IPv6 sooner



The test result above was done using DOCSIS 3.0 modem, XFinity Blast and thru 5 MHz Wi-Fi (802.11n).
See how IPv6 improves the download speed more than 3 times of IPv4 in download test?

I think of the reason is that with IPv6, we no longer need NAT on the router.  So the router most likely bypassed the traffic and directly forward it from the server to my computer (using global IP address).

The latency also improves with IPv6.  This might be caused due to the fixed size of IPv6 header, unlike IPv4.  All other optional headers in IPv6 are moved beyond the header, so routers can forward packets faster.

Tuesday, December 3, 2013

AT&T U-Verse vs. Comcast Xfinity

Technology used

U-Verse: FTTN (Fiber-to-the Node) and VDSL
Comcast: DOCSIS (DataOver Cable Service Interface Specification) and HFC



Diagram



CMTS = Cable Modem Termination System  (usually at curbside of a neighborhood serving house)
VRAD = Video-Ready Access Device (usually at curbside of a neighborhood serving house)
VDSL = Very-high-bit-rate Digital Subscriber Line
CPE = Customer Premise Equipment (e.g, U-Verse Residential Gateway)
FTTN = Fiber To The Node
HFC = Hybrid Fiber Coax
RG = Residential Gateway

How They Work

The central office above is a simplified of interwork of switches, edge routers (facing customers), and core routers (facing the Internet cloud, where Tier-1 backbone connections are interconnected).

U-Verse


The top network is AT&T network, while the bottom one is Comcast network.  Off course, the diagram above is oversimplified.  There are many other components of the Internet (web servers, mail servers, dhcp servers, dns servers, etc.  They will be discussed some day in separate blog).

AT&T's U-Verse network system consists of CPE sitting inside customer's home.  The upstream connection most of the time use existing coax cable that are usually pre-installed inside most houses for cable tv to minimize cross-talk and noise.  The Layer-1 protocol of this connection to VRAD is VDSL (or VDSL2 for higher speed [24 Mbps], or even VDSL2 bonding for even faster speed up to 45 Mbps.  Using VDSL2 vectoring, theoretically we can achieve even 100 Mbps).  

VRAD is an equipment (a rack equipment) sitting at the curb aggregating traffic from premises (homes).  It acts mostly like a layer-2 switch (with some layer-3 capability, such as DHCP, IGMP, some filtering).  The uplink connection to C.O is FTTN (Fiber To The Node) via optical fiber using GPON technology (or other optical technologies), while downlink connections to premises using existing regular phone's twisted pairs.  VRAD usually is equipped with backup batteries, so even when there is power outage, customers still can make phone call (if the customer uses VOIP, he also needs backup battery for his/her CPE).

The AT&T's CPE usually has multiple downlink ethernet ports and one (or two) POTS for VOIP (optional).  One of the Ethernet port is connected to setop-box (in case the customer subscribes to video as part of dual-play or triple-play).  Internet packets and IPTV packet streams are separated over separate VLAN.  For example, VLAN=100 for the Internet, while VLAN=999 for IPTV.  

When customer wants to watch a TV program by selecting a certain channel via remote, the setop-box sends IGMP join packet to VRAD.  VRAD, with its IGMP snooping capability, then requests C.O's router to send multicast packets containing the program.  This multicast packets are then forwarded to the customer's CPE as unicast packets.When other customers watch the same channel, they just join the multicast group and VRAD then forward the stream to them as unicast packets, so there is single multicast video stream coming from central office to VRAD.

All AT&T's residential gateway /CPE support Wi-Fi.  Wireless connection is treated like other wired connection in a sense it is bridged logically.  Once a CPE is up, as usual it sends DHCP (if it is set for automatic IP assignment).  This DHCP is snooped by VRAD and forwarded to C.O.  Once the client device has been assigned an IP address (public IP address), everything is the same as normal wired connection.  It is up to the CPE/RG to assign a local private IP address to any device connected to it (see previous posting for more detail about how it works).

Cable Network


Front Panel of a cable modem


Back panel of a cable modem


Cost Comparison

Sunday, December 1, 2013

Connecting Cable Modem to Two routers

Sometimes we want to split our home private network to two separate subnets, but want to maintain connectivity to the Internet/outside world. The following article tries to explain the basics and internals of most home WiFi routers in the market.

First, let see what are the basic components of a Wi-Fi router:



The following is an example of topology and connection of typical home network:





Router-1: Linksys WRT-54G running DD-WRT firmware
Router-2: NETGEAR Genie WNDR3400v2

The cable modem (DOCSIS modem) is connected to cable provider thru coax cable and its main function is to modulate/demodulate DOCSIS signal to regular ethernet frames (it might bind multiple channels [channel bonding] to increase bandwidth).  The cable provider assigns a public IP address to us to use.  This single public IP cannot be shared if we don't use router.

Router-1 and Router-2 see packets coming from modem, but they don't know how to route them to our devices at home yet.  Assume router-1 is the router that assigns DHCP IP address (running DHCP server), while DHCP server on router-1 is set to forwarder to router-2.  Router-2 is chosen as the main router because it has more recent hardware, supports 11n Wi-fi and supports IPv6 (PS3 is actually better to be connected to router-2 to lower the latency).

Other clients such as as Ooma, Roku and PS3 don't support IPv6 yet, so it's Ok to connect them to Router-2.

On Router-1:  
  • Set DHCP to DHCP forwarder (forward DHCP requests) to router-2 IP address
  • Set router IP address to 192.168.0.1/24
  • Set DNS to either public DNS (such as Google: 8.8.8.8, opendns's IPs or our own local DNS server)
  • Operation mode: router
  • Set wireless to bridged mode (so router-1's wifi is like another L2 ethernet device in our private LAN)
  • WAN type: Static IP.  If it is set to DHCP and the WAN port of router-1 is connected to the ethernet bridge, DHCP server at the ISP site may deny the request or even worse, shutdown the connection completely (thus require modem reboot to fix the problem).
  • Set WAN static IP to router-2 ip address.  This way, we assume router-2 is the gateway and delegates NAT work to router-2 (that's why we set the operation mode of router-1 to "router")


Router-2:
  • Enable AP mode
  • Set router IP address to 192.168.1.1/24
  • Internet IP: Get dynamically from ISP
  • Set DMZ to Router-1

How it works:

A tablet is trying to connect to the Internet via router-2.  All Wi-fi transactions have been done and now it sends DHCP request to router-2.  If this is an initial request made to router-2, router-2 doesn't learn any IP yet so it first learns for the tablet's MAC. Because router-2 runs local dhcp server, it snoops any DHCP request and serves it.  In this case, router-2 then assigns an address in the subnet 192.168.1.0/24 along with DNS addresses and gateway IP (in this case, an ISP-assigned IP address) back to the tablet as DHCP RESP packet.

Now the tablet has a valid private address, now it can connect to the Internet via router-2.  All requests from the tablet is network-translated to public address and vice-versa.  So, if the public IP is a.b.c.d, tablet' IP address is 192.168.1.5 and it is requesting access to www.google.com (http www.google.com:80) from a local tcp port xxxx, the actual packet in the public wire is "a.b.c.d:yyyy", where xxxx is a the original tcp port and yyyy is the translated tcp port by NAT (router-2 maps local to public IP via port) [ Click this for more info about NAT/PAT mechanism].

OK, everything seems to work.  Wait...what about all other devices connected to router-1? What happens if we want to watch Netflix on Roku?

When Roku device is turned on, it sends DHCP REQ similar to tablet above.  The sequence is the same, but the difference is, because router-1 doesn't run DHCP server, all DHCP packets are forwarded to router-2.  So, it is assigned an IP address in the same subnet (sorry, the diagram above is wrong, the subnet should be the same).  When the Roku starts sending tcp packets, the packets not-intended to the private subnet and coming to router-1 are assumed to be forwarded to its gateway (router-2).  Router-1 sees these packets coming from its DMZ and do the same translation to public IP.

An alternative is to subtend router-1 to router-2 directly, not via ethernet switch.  The rest is the same.



Sunday, November 10, 2013

AT&T U-Verse with external wifi router running DD-WRT software



I don't like the way wi-fi connection is handled by CPE (Customer Premise Equipment, such as the provider's home gateway/router), so I want to use the Wi-Fi capability of Linksys.  DD-WRT gives features in handling L2 connections (MAC filtering etc.),  but I still want the CPE to handle DHCP and NAT services.  Basically, I just want to make the Linksys router acts like a Wi-Fi and Wired switch, as an extender of the existing CPE.

 The objects in yellow box represents component in the Wi-Fi router (in this case, a Linksys WRT54G running DD-WRT firmware).

DHCP server on U-Verse CPE is configured to give IPs in 192.168.0.x subnet.  The CPE address is set manually to 192.168.0.1

Here's what I want:
CPE internal IP address = 192.168.0.1
Linksys Internal IP address = 192.168.0.2
IP range for Clients = 192.168.0.3 - 192.168.0.254

CPE setting:
  • Wireless  disabled
  • Configure DHCP to assign IP range: 192.168.0.3 - 192.168.254

DD-WRT settings:
  • WAN connection type = disable
  • Local IP = 192.168.0.2/24
  • DHCP server = forwarding to 19.168.0.1 (CPE)
  • Check option box to assign WAN port to switch (NAT is thus disabled; it is now acting like a pass-thru to switch)
  • Wiress network configuration = bridged (so all Wi-Fi clients are seen by CPE as they're directly connected)
  • Wiress Tx Power = 250 mW
  • Advanced routing = router (doesn't matter actually)
  • Disable CPI firewall
  • Routing = disable
This way, all Wi-Fi is handled by Linksys router/switch, but only its L1-L2 layers.  Everything else is handled by the CPE.  We can also relocate the Linksys somewhere else, no need to be close to CPE as long as we have long ethernet cable or by using Powerline extender.